Rewrite mterp field access helpers

Simplify the code to make further optimizations easier.

Test: ./art/test.py -b -g
Test: ./art/test.py -b -r --interpreter
Change-Id: I54fc29a27a982bc007b600e044660ef04b6d9f29
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index e6f3d0b..1045d2a 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -317,20 +317,9 @@
                                    ArtMethod* referrer,
                                    Thread* self,
                                    size_t expected_size) {
-  bool is_primitive;
-  bool is_set;
-  bool is_static;
-  switch (type) {
-    case InstanceObjectRead:     is_primitive = false; is_set = false; is_static = false; break;
-    case InstanceObjectWrite:    is_primitive = false; is_set = true;  is_static = false; break;
-    case InstancePrimitiveRead:  is_primitive = true;  is_set = false; is_static = false; break;
-    case InstancePrimitiveWrite: is_primitive = true;  is_set = true;  is_static = false; break;
-    case StaticObjectRead:       is_primitive = false; is_set = false; is_static = true;  break;
-    case StaticObjectWrite:      is_primitive = false; is_set = true;  is_static = true;  break;
-    case StaticPrimitiveRead:    is_primitive = true;  is_set = false; is_static = true;  break;
-    case StaticPrimitiveWrite:   // Keep GCC happy by having a default handler, fall-through.
-    default:                     is_primitive = true;  is_set = true;  is_static = true;  break;
-  }
+  constexpr bool is_primitive = (type & FindFieldFlags::PrimitiveBit) != 0;
+  constexpr bool is_set = (type & FindFieldFlags::WriteBit) != 0;
+  constexpr bool is_static = (type & FindFieldFlags::StaticBit) != 0;
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
 
   ArtField* resolved_field;
@@ -611,22 +600,9 @@
     return nullptr;
   }
   // Check for incompatible class change.
-  bool is_primitive;
-  bool is_set;
-  bool is_static;
-  switch (type) {
-    case InstanceObjectRead:     is_primitive = false; is_set = false; is_static = false; break;
-    case InstanceObjectWrite:    is_primitive = false; is_set = true;  is_static = false; break;
-    case InstancePrimitiveRead:  is_primitive = true;  is_set = false; is_static = false; break;
-    case InstancePrimitiveWrite: is_primitive = true;  is_set = true;  is_static = false; break;
-    case StaticObjectRead:       is_primitive = false; is_set = false; is_static = true;  break;
-    case StaticObjectWrite:      is_primitive = false; is_set = true;  is_static = true;  break;
-    case StaticPrimitiveRead:    is_primitive = true;  is_set = false; is_static = true;  break;
-    case StaticPrimitiveWrite:   is_primitive = true;  is_set = true;  is_static = true;  break;
-    default:
-      LOG(FATAL) << "UNREACHABLE";
-      UNREACHABLE();
-  }
+  const bool is_primitive = (type & FindFieldFlags::PrimitiveBit) != 0;
+  const bool is_set = (type & FindFieldFlags::WriteBit) != 0;
+  const bool is_static = (type & FindFieldFlags::StaticBit) != 0;
   if (UNLIKELY(resolved_field->IsStatic() != is_static)) {
     // Incompatible class change.
     return nullptr;
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index 9d70b03..c8bf6d0 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -103,16 +103,25 @@
     REQUIRES_SHARED(Locks::mutator_lock_)
     REQUIRES(!Roles::uninterruptible_);
 
+enum FindFieldFlags {
+  InstanceBit = 1 << 0,
+  StaticBit = 1 << 1,
+  ObjectBit = 1 << 2,
+  PrimitiveBit = 1 << 3,
+  ReadBit = 1 << 4,
+  WriteBit = 1 << 5,
+};
+
 // Type of find field operation for fast and slow case.
 enum FindFieldType {
-  InstanceObjectRead,
-  InstanceObjectWrite,
-  InstancePrimitiveRead,
-  InstancePrimitiveWrite,
-  StaticObjectRead,
-  StaticObjectWrite,
-  StaticPrimitiveRead,
-  StaticPrimitiveWrite,
+  InstanceObjectRead = InstanceBit | ObjectBit | ReadBit,
+  InstanceObjectWrite = InstanceBit | ObjectBit | WriteBit,
+  InstancePrimitiveRead = InstanceBit | PrimitiveBit | ReadBit,
+  InstancePrimitiveWrite = InstanceBit | PrimitiveBit | WriteBit,
+  StaticObjectRead = StaticBit | ObjectBit | ReadBit,
+  StaticObjectWrite = StaticBit | ObjectBit | WriteBit,
+  StaticPrimitiveRead = StaticBit | PrimitiveBit | ReadBit,
+  StaticPrimitiveWrite = StaticBit | PrimitiveBit | WriteBit,
 };
 
 template<FindFieldType type, bool access_check>
diff --git a/runtime/entrypoints/quick/quick_field_entrypoints.cc b/runtime/entrypoints/quick/quick_field_entrypoints.cc
index 62cc9de..d38e3ed 100644
--- a/runtime/entrypoints/quick/quick_field_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_field_entrypoints.cc
@@ -28,13 +28,6 @@
 
 namespace art {
 
-inline constexpr bool FindFieldTypeIsRead(FindFieldType type) {
-  return type == InstanceObjectRead ||
-         type == InstancePrimitiveRead ||
-         type == StaticObjectRead ||
-         type == StaticPrimitiveRead;
-}
-
 // Helper function to do a null check after trying to resolve the field. Not for statics since obj
 // does not exist there. There is a suspend check, object is a double pointer to update the value
 // in the caller in case it moves.
@@ -50,7 +43,7 @@
   HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(obj));
   ArtField* field = FindFieldFromCode<type, kAccessCheck>(field_idx, referrer, self, size);
   if (LIKELY(field != nullptr) && UNLIKELY(h == nullptr)) {
-    ThrowNullPointerExceptionForFieldAccess(field, /*is_read*/FindFieldTypeIsRead(type));
+    ThrowNullPointerExceptionForFieldAccess(field, (type & FindFieldFlags::ReadBit) != 0);
     return nullptr;
   }
   return field;
diff --git a/runtime/interpreter/mterp/arm/field.S b/runtime/interpreter/mterp/arm/field.S
new file mode 100644
index 0000000..c468788
--- /dev/null
+++ b/runtime/interpreter/mterp/arm/field.S
@@ -0,0 +1,16 @@
+%default { }
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern $helper
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       $helper
+    cmp      r0, #0
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_iget.S b/runtime/interpreter/mterp/arm/op_iget.S
index 1684a76..1fa32fa 100644
--- a/runtime/interpreter/mterp/arm/op_iget.S
+++ b/runtime/interpreter/mterp/arm/op_iget.S
@@ -1,26 +1,2 @@
 %default { "is_object":"0", "helper":"MterpIGetU32"}
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    EXPORT_PC
-    FETCH    r0, 1                         @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12            @ r1<- B
-    GET_VREG r1, r1                        @ r1<- fp[B], the object pointer
-    ldr      r2, [rFP, #OFF_FP_METHOD]     @ r2<- referrer
-    mov      r3, rSELF                     @ r3<- self
-    bl       $helper
-    ldr      r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    ubfx     r2, rINST, #8, #4             @ r2<- A
-    PREFETCH_INST 2
-    cmp      r3, #0
-    bne      MterpPossibleException        @ bail out
-    .if $is_object
-    SET_VREG_OBJECT r0, r2                 @ fp[A]<- r0
-    .else
-    SET_VREG r0, r2                        @ fp[A]<- r0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE ip                     @ extract opcode from rINST
-    GOTO_OPCODE ip                         @ jump to next instruction
+%include "arm/field.S" { }
diff --git a/runtime/interpreter/mterp/arm/op_iget_wide.S b/runtime/interpreter/mterp/arm/op_iget_wide.S
index 46e9ec8..ede21eb 100644
--- a/runtime/interpreter/mterp/arm/op_iget_wide.S
+++ b/runtime/interpreter/mterp/arm/op_iget_wide.S
@@ -1,23 +1 @@
-    /*
-     * 64-bit instance field get.
-     *
-     * for: iget-wide
-     */
-    EXPORT_PC
-    FETCH    r0, 1                         @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12            @ r1<- B
-    GET_VREG r1, r1                        @ r1<- fp[B], the object pointer
-    ldr      r2, [rFP, #OFF_FP_METHOD]     @ r2<- referrer
-    mov      r3, rSELF                     @ r3<- self
-    bl       MterpIGetU64
-    ldr      r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    ubfx     r2, rINST, #8, #4             @ r2<- A
-    PREFETCH_INST 2
-    cmp      r3, #0
-    bne      MterpException                @ bail out
-    CLEAR_SHADOW_PAIR r2, ip, lr           @ Zero out the shadow regs
-    VREG_INDEX_TO_ADDR r3, r2              @ r3<- &fp[A]
-    stmia    r3, {r0-r1}                   @ fp[A]<- r0/r1
-    ADVANCE 2
-    GET_INST_OPCODE ip                     @ extract opcode from rINST
-    GOTO_OPCODE ip                         @ jump to next instruction
+%include "arm/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/arm/op_iput.S b/runtime/interpreter/mterp/arm/op_iput.S
index a16795d..6201d80 100644
--- a/runtime/interpreter/mterp/arm/op_iput.S
+++ b/runtime/interpreter/mterp/arm/op_iput.S
@@ -1,22 +1,2 @@
 %default { "is_object":"0", "helper":"MterpIPutU32" }
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field@CCCC */
-    .extern $helper
-    EXPORT_PC
-    FETCH    r0, 1                      @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12         @ r1<- B
-    GET_VREG r1, r1                     @ r1<- fp[B], the object pointer
-    ubfx     r2, rINST, #8, #4          @ r2<- A
-    GET_VREG r2, r2                     @ r2<- fp[A]
-    ldr      r3, [rFP, #OFF_FP_METHOD]  @ r3<- referrer
-    PREFETCH_INST 2
-    bl       $helper
-    cmp      r0, #0
-    bne      MterpPossibleException
-    ADVANCE  2                          @ advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+%include "arm/field.S" { }
diff --git a/runtime/interpreter/mterp/arm/op_iput_object.S b/runtime/interpreter/mterp/arm/op_iput_object.S
index 4f401eb..1003d10 100644
--- a/runtime/interpreter/mterp/arm/op_iput_object.S
+++ b/runtime/interpreter/mterp/arm/op_iput_object.S
@@ -1,11 +1 @@
-    EXPORT_PC
-    add     r0, rFP, #OFF_FP_SHADOWFRAME
-    mov     r1, rPC
-    mov     r2, rINST
-    mov     r3, rSELF
-    bl      MterpIPutObj
-    cmp     r0, #0
-    beq     MterpException
-    FETCH_ADVANCE_INST 2                @ advance rPC, load rINST
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+%include "arm/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/arm/op_iput_wide.S b/runtime/interpreter/mterp/arm/op_iput_wide.S
index 6a41473..f2845ad 100644
--- a/runtime/interpreter/mterp/arm/op_iput_wide.S
+++ b/runtime/interpreter/mterp/arm/op_iput_wide.S
@@ -1,16 +1 @@
-    /* iput-wide vA, vB, field@CCCC */
-    .extern MterpIPutU64
-    EXPORT_PC
-    FETCH    r0, 1                      @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12         @ r1<- B
-    GET_VREG r1, r1                     @ r1<- fp[B], the object pointer
-    ubfx     r2, rINST, #8, #4          @ r2<- A
-    VREG_INDEX_TO_ADDR r2, r2           @ r2<- &fp[A]
-    ldr      r3, [rFP, #OFF_FP_METHOD]  @ r3<- referrer
-    PREFETCH_INST 2
-    bl       MterpIPutU64
-    cmp      r0, #0
-    bne      MterpPossibleException
-    ADVANCE  2                          @ advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+%include "arm/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/arm/op_sget.S b/runtime/interpreter/mterp/arm/op_sget.S
index 575a8c0..b382de4 100644
--- a/runtime/interpreter/mterp/arm/op_sget.S
+++ b/runtime/interpreter/mterp/arm/op_sget.S
@@ -1,27 +1,2 @@
 %default { "is_object":"0", "helper":"MterpSGetU32" }
-    /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field@BBBB */
-
-    .extern $helper
-    EXPORT_PC
-    FETCH r0, 1                         @ r0<- field ref BBBB
-    ldr   r1, [rFP, #OFF_FP_METHOD]
-    mov   r2, rSELF
-    bl    $helper
-    ldr   r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    mov   r2, rINST, lsr #8             @ r2<- AA
-    PREFETCH_INST 2
-    cmp   r3, #0                        @ Fail to resolve?
-    bne   MterpException                @ bail out
-.if $is_object
-    SET_VREG_OBJECT r0, r2              @ fp[AA]<- r0
-.else
-    SET_VREG r0, r2                     @ fp[AA]<- r0
-.endif
-    ADVANCE 2
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip
+%include "arm/field.S" { }
diff --git a/runtime/interpreter/mterp/arm/op_sget_wide.S b/runtime/interpreter/mterp/arm/op_sget_wide.S
index 5981ec4..d6905df 100644
--- a/runtime/interpreter/mterp/arm/op_sget_wide.S
+++ b/runtime/interpreter/mterp/arm/op_sget_wide.S
@@ -1,22 +1 @@
-    /*
-     * SGET_WIDE handler wrapper.
-     *
-     */
-    /* sget-wide vAA, field@BBBB */
-
-    .extern MterpSGetU64
-    EXPORT_PC
-    FETCH r0, 1                         @ r0<- field ref BBBB
-    ldr   r1, [rFP, #OFF_FP_METHOD]
-    mov   r2, rSELF
-    bl    MterpSGetU64
-    ldr   r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    mov   r9, rINST, lsr #8             @ r9<- AA
-    VREG_INDEX_TO_ADDR lr, r9           @ r9<- &fp[AA]
-    cmp   r3, #0                        @ Fail to resolve?
-    bne   MterpException                @ bail out
-    FETCH_ADVANCE_INST 2                @ advance rPC, load rINST
-    CLEAR_SHADOW_PAIR r9, r2, ip        @ Zero out the shadow regs
-    stmia lr, {r0-r1}                   @ vAA/vAA+1<- r0/r1
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+%include "arm/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/arm/op_sput.S b/runtime/interpreter/mterp/arm/op_sput.S
index c4a8978..171f024 100644
--- a/runtime/interpreter/mterp/arm/op_sput.S
+++ b/runtime/interpreter/mterp/arm/op_sput.S
@@ -1,20 +1,2 @@
-%default { "helper":"MterpSPutU32"}
-    /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field@BBBB */
-    EXPORT_PC
-    FETCH   r0, 1                       @ r0<- field ref BBBB
-    mov     r3, rINST, lsr #8           @ r3<- AA
-    GET_VREG r1, r3                     @ r1<= fp[AA]
-    ldr     r2, [rFP, #OFF_FP_METHOD]
-    mov     r3, rSELF
-    PREFETCH_INST 2                     @ Get next inst, but don't advance rPC
-    bl      $helper
-    cmp     r0, #0                      @ 0 on success, -1 on failure
-    bne     MterpException
-    ADVANCE 2                           @ Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "arm/field.S" { }
diff --git a/runtime/interpreter/mterp/arm/op_sput_object.S b/runtime/interpreter/mterp/arm/op_sput_object.S
index c58918f..8fcd52e 100644
--- a/runtime/interpreter/mterp/arm/op_sput_object.S
+++ b/runtime/interpreter/mterp/arm/op_sput_object.S
@@ -1,11 +1 @@
-    EXPORT_PC
-    add     r0, rFP, #OFF_FP_SHADOWFRAME
-    mov     r1, rPC
-    mov     r2, rINST
-    mov     r3, rSELF
-    bl      MterpSPutObj
-    cmp     r0, #0
-    beq     MterpException
-    FETCH_ADVANCE_INST 2                @ advance rPC, load rINST
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+%include "arm/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/arm/op_sput_wide.S b/runtime/interpreter/mterp/arm/op_sput_wide.S
index 0ed4017..c254f78 100644
--- a/runtime/interpreter/mterp/arm/op_sput_wide.S
+++ b/runtime/interpreter/mterp/arm/op_sput_wide.S
@@ -1,19 +1 @@
-    /*
-     * SPUT_WIDE handler wrapper.
-     *
-     */
-    /* sput-wide vAA, field@BBBB */
-    .extern MterpSPutU64
-    EXPORT_PC
-    FETCH   r0, 1                       @ r0<- field ref BBBB
-    mov     r1, rINST, lsr #8           @ r1<- AA
-    VREG_INDEX_TO_ADDR r1, r1
-    ldr     r2, [rFP, #OFF_FP_METHOD]
-    mov     r3, rSELF
-    PREFETCH_INST 2                     @ Get next inst, but don't advance rPC
-    bl      MterpSPutU64
-    cmp     r0, #0                      @ 0 on success, -1 on failure
-    bne     MterpException
-    ADVANCE 2                           @ Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+%include "arm/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/arm64/field.S b/runtime/interpreter/mterp/arm64/field.S
new file mode 100644
index 0000000..631c8d1
--- /dev/null
+++ b/runtime/interpreter/mterp/arm64/field.S
@@ -0,0 +1,15 @@
+%default { }
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern $helper
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       $helper
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_iget.S b/runtime/interpreter/mterp/arm64/op_iget.S
index cb453ac..48b9cad 100644
--- a/runtime/interpreter/mterp/arm64/op_iget.S
+++ b/runtime/interpreter/mterp/arm64/op_iget.S
@@ -1,26 +1,2 @@
-%default { "extend":"", "is_object":"0", "helper":"MterpIGetU32"}
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    EXPORT_PC
-    FETCH    w0, 1                         // w0<- field ref CCCC
-    lsr      w1, wINST, #12                // w1<- B
-    GET_VREG w1, w1                        // w1<- fp[B], the object pointer
-    ldr      x2, [xFP, #OFF_FP_METHOD]     // w2<- referrer
-    mov      x3, xSELF                     // w3<- self
-    bl       $helper
-    ldr      x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    $extend
-    ubfx     w2, wINST, #8, #4             // w2<- A
-    PREFETCH_INST 2
-    cbnz     x3, MterpPossibleException    // bail out
-    .if $is_object
-    SET_VREG_OBJECT w0, w2                 // fp[A]<- w0
-    .else
-    SET_VREG w0, w2                        // fp[A]<- w0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE ip                     // extract opcode from rINST
-    GOTO_OPCODE ip                         // jump to next instruction
+%default { "is_object":"0", "helper":"MterpIGetU32"}
+%include "arm64/field.S" { }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_boolean.S b/runtime/interpreter/mterp/arm64/op_iget_boolean.S
index 3b17144..9a83b2a 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_boolean.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_boolean.S
@@ -1 +1 @@
-%include "arm64/op_iget.S" { "helper":"MterpIGetU8", "extend":"uxtb w0, w0" }
+%include "arm64/op_iget.S" { "helper":"MterpIGetU8" }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_byte.S b/runtime/interpreter/mterp/arm64/op_iget_byte.S
index d5ef1d3..f73e634 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_byte.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_byte.S
@@ -1 +1 @@
-%include "arm64/op_iget.S" { "helper":"MterpIGetI8", "extend":"sxtb w0, w0" }
+%include "arm64/op_iget.S" { "helper":"MterpIGetI8" }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_char.S b/runtime/interpreter/mterp/arm64/op_iget_char.S
index 68e1435..a5efd9e 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_char.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_char.S
@@ -1 +1 @@
-%include "arm64/op_iget.S" { "helper":"MterpIGetU16", "extend":"uxth w0, w0" }
+%include "arm64/op_iget.S" { "helper":"MterpIGetU16" }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_short.S b/runtime/interpreter/mterp/arm64/op_iget_short.S
index 714f4b9..bb81c17 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_short.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_short.S
@@ -1 +1 @@
-%include "arm64/op_iget.S" { "helper":"MterpIGetI16", "extend":"sxth w0, w0" }
+%include "arm64/op_iget.S" { "helper":"MterpIGetI16" }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_wide.S b/runtime/interpreter/mterp/arm64/op_iget_wide.S
index 4fc735c..70061d6 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_wide.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_wide.S
@@ -1,21 +1 @@
-    /*
-     * 64-bit instance field get.
-     *
-     * for: iget-wide
-     */
-    EXPORT_PC
-    FETCH    w0, 1                         // w0<- field ref CCCC
-    lsr      w1, wINST, #12                // w1<- B
-    GET_VREG w1, w1                        // w1<- fp[B], the object pointer
-    ldr      x2, [xFP, #OFF_FP_METHOD]     // w2<- referrer
-    mov      x3, xSELF                     // w3<- self
-    bl       MterpIGetU64
-    ldr      x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    ubfx     w2, wINST, #8, #4             // w2<- A
-    PREFETCH_INST 2
-    cmp      w3, #0
-    cbnz     w3, MterpException            // bail out
-    SET_VREG_WIDE x0, w2
-    ADVANCE 2
-    GET_INST_OPCODE ip                     // extract opcode from wINST
-    GOTO_OPCODE ip                         // jump to next instruction
+%include "arm64/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/arm64/op_iput.S b/runtime/interpreter/mterp/arm64/op_iput.S
index 5e21d5c..2bc3db9 100644
--- a/runtime/interpreter/mterp/arm64/op_iput.S
+++ b/runtime/interpreter/mterp/arm64/op_iput.S
@@ -1,21 +1,2 @@
 %default { "is_object":"0", "helper":"MterpIPutU32" }
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field//CCCC */
-    .extern $helper
-    EXPORT_PC
-    FETCH    w0, 1                      // w0<- field ref CCCC
-    lsr      w1, wINST, #12             // w1<- B
-    GET_VREG w1, w1                     // w1<- fp[B], the object pointer
-    ubfx     w2, wINST, #8, #4          // w2<- A
-    GET_VREG w2, w2                     // w2<- fp[A]
-    ldr      x3, [xFP, #OFF_FP_METHOD]  // w3<- referrer
-    PREFETCH_INST 2
-    bl       $helper
-    cbnz     w0, MterpPossibleException
-    ADVANCE  2                          // advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+%include "arm64/field.S" { }
diff --git a/runtime/interpreter/mterp/arm64/op_iput_object.S b/runtime/interpreter/mterp/arm64/op_iput_object.S
index 0c0441a..e9bb93f 100644
--- a/runtime/interpreter/mterp/arm64/op_iput_object.S
+++ b/runtime/interpreter/mterp/arm64/op_iput_object.S
@@ -1,10 +1 @@
-    EXPORT_PC
-    add     x0, xFP, #OFF_FP_SHADOWFRAME
-    mov     x1, xPC
-    mov     w2, wINST
-    mov     x3, xSELF
-    bl      MterpIPutObj
-    cbz     w0, MterpException
-    FETCH_ADVANCE_INST 2                // advance rPC, load rINST
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+%include "arm64/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/arm64/op_iput_wide.S b/runtime/interpreter/mterp/arm64/op_iput_wide.S
index be6aeb0..e1fafad 100644
--- a/runtime/interpreter/mterp/arm64/op_iput_wide.S
+++ b/runtime/interpreter/mterp/arm64/op_iput_wide.S
@@ -1,15 +1 @@
-    /* iput-wide vA, vB, field//CCCC */
-    .extern MterpIPutU64
-    EXPORT_PC
-    FETCH    w0, 1                      // w0<- field ref CCCC
-    lsr      w1, wINST, #12             // w1<- B
-    GET_VREG w1, w1                     // w1<- fp[B], the object pointer
-    ubfx     w2, wINST, #8, #4          // w2<- A
-    VREG_INDEX_TO_ADDR x2, x2           // w2<- &fp[A]
-    ldr      x3, [xFP, #OFF_FP_METHOD]  // w3<- referrer
-    PREFETCH_INST 2
-    bl       MterpIPutU64
-    cbnz     w0, MterpPossibleException
-    ADVANCE  2                          // advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from wINST
-    GOTO_OPCODE ip                      // jump to next instruction
+%include "arm64/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/arm64/op_sget.S b/runtime/interpreter/mterp/arm64/op_sget.S
index 00b07fa..78e95b2 100644
--- a/runtime/interpreter/mterp/arm64/op_sget.S
+++ b/runtime/interpreter/mterp/arm64/op_sget.S
@@ -1,27 +1,2 @@
-%default { "is_object":"0", "helper":"MterpSGetU32", "extend":"" }
-    /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field//BBBB */
-
-    .extern $helper
-    EXPORT_PC
-    FETCH w0, 1                         // w0<- field ref BBBB
-    ldr   x1, [xFP, #OFF_FP_METHOD]
-    mov   x2, xSELF
-    bl    $helper
-    ldr   x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    lsr   w2, wINST, #8                 // w2<- AA
-    $extend
-    PREFETCH_INST 2
-    cbnz  x3, MterpException            // bail out
-.if $is_object
-    SET_VREG_OBJECT w0, w2              // fp[AA]<- w0
-.else
-    SET_VREG w0, w2                     // fp[AA]<- w0
-.endif
-    ADVANCE 2
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip
+%default { "is_object":"0", "helper":"MterpSGetU32" }
+%include "arm64/field.S" { }
diff --git a/runtime/interpreter/mterp/arm64/op_sget_boolean.S b/runtime/interpreter/mterp/arm64/op_sget_boolean.S
index 73f3a10..0cf9f09 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_boolean.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_boolean.S
@@ -1 +1 @@
-%include "arm64/op_sget.S" {"helper":"MterpSGetU8", "extend":"uxtb w0, w0"}
+%include "arm64/op_sget.S" {"helper":"MterpSGetU8"}
diff --git a/runtime/interpreter/mterp/arm64/op_sget_byte.S b/runtime/interpreter/mterp/arm64/op_sget_byte.S
index 38c0da6..7c88a81 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_byte.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_byte.S
@@ -1 +1 @@
-%include "arm64/op_sget.S" {"helper":"MterpSGetI8", "extend":"sxtb w0, w0"}
+%include "arm64/op_sget.S" {"helper":"MterpSGetI8"}
diff --git a/runtime/interpreter/mterp/arm64/op_sget_char.S b/runtime/interpreter/mterp/arm64/op_sget_char.S
index c0801bf..883e944 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_char.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_char.S
@@ -1 +1 @@
-%include "arm64/op_sget.S" {"helper":"MterpSGetU16", "extend":"uxth w0, w0"}
+%include "arm64/op_sget.S" {"helper":"MterpSGetU16"}
diff --git a/runtime/interpreter/mterp/arm64/op_sget_short.S b/runtime/interpreter/mterp/arm64/op_sget_short.S
index 81e0434..6cb9184 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_short.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_short.S
@@ -1 +1 @@
-%include "arm64/op_sget.S" {"helper":"MterpSGetI16", "extend":"sxth w0, w0"}
+%include "arm64/op_sget.S" {"helper":"MterpSGetI16"}
diff --git a/runtime/interpreter/mterp/arm64/op_sget_wide.S b/runtime/interpreter/mterp/arm64/op_sget_wide.S
index 546ab94..f5d182e 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_wide.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_wide.S
@@ -1,19 +1 @@
-    /*
-     * SGET_WIDE handler wrapper.
-     *
-     */
-    /* sget-wide vAA, field//BBBB */
-
-    .extern MterpSGetU64
-    EXPORT_PC
-    FETCH w0, 1                         // w0<- field ref BBBB
-    ldr   x1, [xFP, #OFF_FP_METHOD]
-    mov   x2, xSELF
-    bl    MterpSGetU64
-    ldr   x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    lsr   w4, wINST, #8                 // w4<- AA
-    cbnz  x3, MterpException            // bail out
-    FETCH_ADVANCE_INST 2                // advance rPC, load wINST
-    SET_VREG_WIDE x0, w4
-    GET_INST_OPCODE ip                  // extract opcode from wINST
-    GOTO_OPCODE ip                      // jump to next instruction
+%include "arm64/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/arm64/op_sput.S b/runtime/interpreter/mterp/arm64/op_sput.S
index 7a0dc30..d229d0d 100644
--- a/runtime/interpreter/mterp/arm64/op_sput.S
+++ b/runtime/interpreter/mterp/arm64/op_sput.S
@@ -1,19 +1,2 @@
-%default { "helper":"MterpSPutU32"}
-    /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field//BBBB */
-    EXPORT_PC
-    FETCH   w0, 1                       // r0<- field ref BBBB
-    lsr     w3, wINST, #8               // r3<- AA
-    GET_VREG w1, w3                     // r1<= fp[AA]
-    ldr     x2, [xFP, #OFF_FP_METHOD]
-    mov     x3, xSELF
-    PREFETCH_INST 2                     // Get next inst, but don't advance rPC
-    bl      $helper
-    cbnz    w0, MterpException          // 0 on success
-    ADVANCE 2                           // Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "arm64/field.S" { }
diff --git a/runtime/interpreter/mterp/arm64/op_sput_object.S b/runtime/interpreter/mterp/arm64/op_sput_object.S
index a649656..536f1b1 100644
--- a/runtime/interpreter/mterp/arm64/op_sput_object.S
+++ b/runtime/interpreter/mterp/arm64/op_sput_object.S
@@ -1,10 +1 @@
-    EXPORT_PC
-    add     x0, xFP, #OFF_FP_SHADOWFRAME
-    mov     x1, xPC
-    mov     x2, xINST
-    mov     x3, xSELF
-    bl      MterpSPutObj
-    cbz     w0, MterpException
-    FETCH_ADVANCE_INST 2                // advance rPC, load rINST
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+%include "arm64/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/arm64/op_sput_wide.S b/runtime/interpreter/mterp/arm64/op_sput_wide.S
index 58b3c42..b4be6b2 100644
--- a/runtime/interpreter/mterp/arm64/op_sput_wide.S
+++ b/runtime/interpreter/mterp/arm64/op_sput_wide.S
@@ -1,18 +1 @@
-    /*
-     * SPUT_WIDE handler wrapper.
-     *
-     */
-    /* sput-wide vAA, field//BBBB */
-    .extern MterpSPutU64
-    EXPORT_PC
-    FETCH   w0, 1                       // w0<- field ref BBBB
-    lsr     w1, wINST, #8               // w1<- AA
-    VREG_INDEX_TO_ADDR x1, w1
-    ldr     x2, [xFP, #OFF_FP_METHOD]
-    mov     x3, xSELF
-    PREFETCH_INST 2                     // Get next inst, but don't advance rPC
-    bl      MterpSPutU64
-    cbnz    w0, MterpException          // 0 on success, -1 on failure
-    ADVANCE 2                           // Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from wINST
-    GOTO_OPCODE ip                      // jump to next instruction
+%include "arm64/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/mips/field.S b/runtime/interpreter/mterp/mips/field.S
new file mode 100644
index 0000000..1333ed7
--- /dev/null
+++ b/runtime/interpreter/mterp/mips/field.S
@@ -0,0 +1 @@
+TODO
diff --git a/runtime/interpreter/mterp/mips/op_iget.S b/runtime/interpreter/mterp/mips/op_iget.S
index 33717de..e218272 100644
--- a/runtime/interpreter/mterp/mips/op_iget.S
+++ b/runtime/interpreter/mterp/mips/op_iget.S
@@ -1,25 +1,2 @@
 %default { "is_object":"0", "helper":"MterpIGetU32"}
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    /* op vA, vB, field@CCCC */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- referrer
-    move  a3, rSELF                        # a3 <- self
-    JAL($helper)
-    lw   a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA4(a2)                           # a2<- A+
-    PREFETCH_INST(2)                       # load rINST
-    bnez  a3, MterpPossibleException        # bail out
-    ADVANCE(2)                             #  advance rPC
-    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
-    .if $is_object
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[A] <- v0
-    .else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[A] <- v0
-    .endif
+%include "mips/field.S" { }
diff --git a/runtime/interpreter/mterp/mips/op_iget_wide.S b/runtime/interpreter/mterp/mips/op_iget_wide.S
index 858a889..885372a 100644
--- a/runtime/interpreter/mterp/mips/op_iget_wide.S
+++ b/runtime/interpreter/mterp/mips/op_iget_wide.S
@@ -1,20 +1 @@
-    /*
-     * 64-bit instance field get.
-     *
-     * for: iget-wide
-     */
-    /* op vA, vB, field@CCCC */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field byte offset
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- referrer
-    move  a3, rSELF                        # a3 <- self
-    JAL(MterpIGetU64)
-    lw   a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA4(a2)                           # a2<- A+
-    PREFETCH_INST(2)                       # load rINST
-    bnez a3, MterpException                # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    SET_VREG64_GOTO(v0, v1, a2, t0)        # fp[A] <- v0/v1
+%include "mips/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/mips/op_iput.S b/runtime/interpreter/mterp/mips/op_iput.S
index 4dd4075..efbdfba 100644
--- a/runtime/interpreter/mterp/mips/op_iput.S
+++ b/runtime/interpreter/mterp/mips/op_iput.S
@@ -1,21 +1,2 @@
-%default { "helper":"MterpIPutU32" }
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field@CCCC */
-    .extern $helper
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    GET_OPA4(a2)                           # a2 <- A+
-    GET_VREG(a2, a2)                       # a2 <- fp[A]
-    lw    a3, OFF_FP_METHOD(rFP)           # a3 <- referrer
-    PREFETCH_INST(2)                       # load rINST
-    JAL($helper)
-    bnez  v0, MterpPossibleException       # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+%default { "is_object":"0", "helper":"MterpIPutU32" }
+%include "mips/field.S" { }
diff --git a/runtime/interpreter/mterp/mips/op_iput_object.S b/runtime/interpreter/mterp/mips/op_iput_object.S
index c96a4d4..6f7e7b7 100644
--- a/runtime/interpreter/mterp/mips/op_iput_object.S
+++ b/runtime/interpreter/mterp/mips/op_iput_object.S
@@ -1,16 +1 @@
-    /*
-     * 32-bit instance field put.
-     *
-     * for: iput-object, iput-object-volatile
-     */
-    /* op vA, vB, field@CCCC */
-    EXPORT_PC()
-    addu   a0, rFP, OFF_FP_SHADOWFRAME
-    move   a1, rPC
-    move   a2, rINST
-    move   a3, rSELF
-    JAL(MterpIPutObj)
-    beqz   v0, MterpException
-    FETCH_ADVANCE_INST(2)               # advance rPC, load rINST
-    GET_INST_OPCODE(t0)                 # extract opcode from rINST
-    GOTO_OPCODE(t0)                     # jump to next instruction
+%include "mips/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/mips/op_iput_wide.S b/runtime/interpreter/mterp/mips/op_iput_wide.S
index dccb6b7..fc862e4 100644
--- a/runtime/interpreter/mterp/mips/op_iput_wide.S
+++ b/runtime/interpreter/mterp/mips/op_iput_wide.S
@@ -1,15 +1 @@
-    /* iput-wide vA, vB, field@CCCC */
-    .extern MterpIPutU64
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    GET_OPA4(a2)                           # a2 <- A+
-    EAS2(a2, rFP, a2)                      # a2 <- &fp[A]
-    lw    a3, OFF_FP_METHOD(rFP)           # a3 <- referrer
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpIPutU64)
-    bnez  v0, MterpPossibleException       # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+%include "mips/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/mips/op_sget.S b/runtime/interpreter/mterp/mips/op_sget.S
index 8750a17..92d6673 100644
--- a/runtime/interpreter/mterp/mips/op_sget.S
+++ b/runtime/interpreter/mterp/mips/op_sget.S
@@ -1,24 +1,2 @@
 %default { "is_object":"0", "helper":"MterpSGetU32" }
-    /*
-     * General SGET handler.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field@BBBB */
-    .extern $helper
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    lw    a1, OFF_FP_METHOD(rFP)           # a1 <- method
-    move  a2, rSELF                        # a2 <- self
-    JAL($helper)
-    lw    a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA(a2)                            # a2 <- AA
-    PREFETCH_INST(2)
-    bnez  a3, MterpException               # bail out
-    ADVANCE(2)
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-.if $is_object
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[AA] <- v0
-.else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[AA] <- v0
-.endif
+%include "mips/field.S" { }
diff --git a/runtime/interpreter/mterp/mips/op_sget_wide.S b/runtime/interpreter/mterp/mips/op_sget_wide.S
index 76f78cb..be4ae02 100644
--- a/runtime/interpreter/mterp/mips/op_sget_wide.S
+++ b/runtime/interpreter/mterp/mips/op_sget_wide.S
@@ -1,16 +1 @@
-    /*
-     * 64-bit SGET handler.
-     */
-    /* sget-wide vAA, field@BBBB */
-    .extern MterpSGetU64
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    lw    a1, OFF_FP_METHOD(rFP)           # a1 <- method
-    move  a2, rSELF                        # a2 <- self
-    JAL(MterpSGetU64)
-    lw    a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    bnez  a3, MterpException
-    GET_OPA(a1)                            # a1 <- AA
-    FETCH_ADVANCE_INST(2)                  # advance rPC, load rINST
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    SET_VREG64_GOTO(v0, v1, a1, t0)        # vAA/vAA+1 <- v0/v1
+%include "mips/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/mips/op_sput.S b/runtime/interpreter/mterp/mips/op_sput.S
index 547de39..c858679 100644
--- a/runtime/interpreter/mterp/mips/op_sput.S
+++ b/runtime/interpreter/mterp/mips/op_sput.S
@@ -1,19 +1,2 @@
-%default { "helper":"MterpSPutU32"}
-    /*
-     * General SPUT handler.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field@BBBB */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    GET_OPA(a3)                            # a3 <- AA
-    GET_VREG(a1, a3)                       # a1 <- fp[AA], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- method
-    move  a3, rSELF                        # a3 <- self
-    PREFETCH_INST(2)                       # load rINST
-    JAL($helper)
-    bnez  v0, MterpException               # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "mips/field.S" { }
diff --git a/runtime/interpreter/mterp/mips/op_sput_object.S b/runtime/interpreter/mterp/mips/op_sput_object.S
index 55c88a6..683b767 100644
--- a/runtime/interpreter/mterp/mips/op_sput_object.S
+++ b/runtime/interpreter/mterp/mips/op_sput_object.S
@@ -1,16 +1 @@
-    /*
-     * General 32-bit SPUT handler.
-     *
-     * for: sput-object,
-     */
-    /* op vAA, field@BBBB */
-    EXPORT_PC()
-    addu   a0, rFP, OFF_FP_SHADOWFRAME
-    move   a1, rPC
-    move   a2, rINST
-    move   a3, rSELF
-    JAL(MterpSPutObj)
-    beqz   v0, MterpException
-    FETCH_ADVANCE_INST(2)               # advance rPC, load rINST
-    GET_INST_OPCODE(t0)                 # extract opcode from rINST
-    GOTO_OPCODE(t0)                     # jump to next instruction
+%include "mips/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/mips/op_sput_wide.S b/runtime/interpreter/mterp/mips/op_sput_wide.S
index cfaaaee..1d2ed19 100644
--- a/runtime/interpreter/mterp/mips/op_sput_wide.S
+++ b/runtime/interpreter/mterp/mips/op_sput_wide.S
@@ -1,17 +1 @@
-    /*
-     * 64-bit SPUT handler.
-     */
-    /* sput-wide vAA, field@BBBB */
-    .extern MterpSPutU64
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPA(a1)                            # a1 <- AA
-    EAS2(a1, rFP, a1)                      # a1 <- &fp[AA]
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- method
-    move  a3, rSELF                        # a3 <- self
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpSPutU64)
-    bnez  v0, MterpException               # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+%include "mips/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/mips64/field.S b/runtime/interpreter/mterp/mips64/field.S
new file mode 100644
index 0000000..1333ed7
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/field.S
@@ -0,0 +1 @@
+TODO
diff --git a/runtime/interpreter/mterp/mips64/op_iget.S b/runtime/interpreter/mterp/mips64/op_iget.S
index a8ce94c..e91f099 100644
--- a/runtime/interpreter/mterp/mips64/op_iget.S
+++ b/runtime/interpreter/mterp/mips64/op_iget.S
@@ -1,26 +1,2 @@
 %default { "is_object":"0", "helper":"MterpIGetU32"}
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    .extern $helper
-    EXPORT_PC
-    lhu      a0, 2(rPC)                 # a0 <- field ref CCCC
-    srl      a1, rINST, 12              # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ld       a2, OFF_FP_METHOD(rFP)     # a2 <- referrer
-    move     a3, rSELF                  # a3 <- self
-    jal      $helper
-    ld       a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    ext      a2, rINST, 8, 4            # a2 <- A
-    PREFETCH_INST 2
-    bnez     a3, MterpPossibleException # bail out
-    .if $is_object
-    SET_VREG_OBJECT v0, a2              # fp[A] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[A] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+%include "mips64/field.S" { }
diff --git a/runtime/interpreter/mterp/mips64/op_iget_wide.S b/runtime/interpreter/mterp/mips64/op_iget_wide.S
index 08bf544..40f3645 100644
--- a/runtime/interpreter/mterp/mips64/op_iget_wide.S
+++ b/runtime/interpreter/mterp/mips64/op_iget_wide.S
@@ -1,21 +1 @@
-    /*
-     * 64-bit instance field get.
-     *
-     * for: iget-wide
-     */
-    .extern MterpIGetU64
-    EXPORT_PC
-    lhu      a0, 2(rPC)                 # a0 <- field ref CCCC
-    srl      a1, rINST, 12              # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ld       a2, OFF_FP_METHOD(rFP)     # a2 <- referrer
-    move     a3, rSELF                  # a3 <- self
-    jal      MterpIGetU64
-    ld       a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    ext      a2, rINST, 8, 4            # a2 <- A
-    PREFETCH_INST 2
-    bnez     a3, MterpPossibleException # bail out
-    SET_VREG_WIDE v0, a2                # fp[A] <- v0
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+%include "mips64/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/mips64/op_iput.S b/runtime/interpreter/mterp/mips64/op_iput.S
index 9a789e6..81ab911 100644
--- a/runtime/interpreter/mterp/mips64/op_iput.S
+++ b/runtime/interpreter/mterp/mips64/op_iput.S
@@ -1,21 +1,2 @@
-%default { "helper":"MterpIPutU32" }
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field//CCCC */
-    .extern $helper
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref CCCC
-    srl     a1, rINST, 12               # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ext     a2, rINST, 8, 4             # a2 <- A
-    GET_VREG a2, a2                     # a2 <- fp[A]
-    ld      a3, OFF_FP_METHOD(rFP)      # a3 <- referrer
-    PREFETCH_INST 2
-    jal     $helper
-    bnez    v0, MterpPossibleException  # bail out
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+%default { "is_object":"0", "helper":"MterpIPutU32" }
+%include "mips64/field.S" { }
diff --git a/runtime/interpreter/mterp/mips64/op_iput_object.S b/runtime/interpreter/mterp/mips64/op_iput_object.S
index dd1938e..d3316dd 100644
--- a/runtime/interpreter/mterp/mips64/op_iput_object.S
+++ b/runtime/interpreter/mterp/mips64/op_iput_object.S
@@ -1,11 +1 @@
-    .extern MterpIPutObj
-    EXPORT_PC
-    daddu   a0, rFP, OFF_FP_SHADOWFRAME
-    move    a1, rPC
-    move    a2, rINST
-    move    a3, rSELF
-    jal     MterpIPutObj
-    beqzc   v0, MterpException
-    FETCH_ADVANCE_INST 2                # advance rPC, load rINST
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+%include "mips64/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/mips64/op_iput_wide.S b/runtime/interpreter/mterp/mips64/op_iput_wide.S
index 6272690..05194b3 100644
--- a/runtime/interpreter/mterp/mips64/op_iput_wide.S
+++ b/runtime/interpreter/mterp/mips64/op_iput_wide.S
@@ -1,15 +1 @@
-    /* iput-wide vA, vB, field//CCCC */
-    .extern MterpIPutU64
-    EXPORT_PC
-    lhu      a0, 2(rPC)                 # a0 <- field ref CCCC
-    srl      a1, rINST, 12              # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ext      a2, rINST, 8, 4            # a2 <- A
-    dlsa     a2, a2, rFP, 2             # a2 <- &fp[A]
-    ld       a3, OFF_FP_METHOD(rFP)     # a3 <- referrer
-    PREFETCH_INST 2
-    jal      MterpIPutU64
-    bnez     v0, MterpPossibleException # bail out
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+%include "mips64/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/mips64/op_sget.S b/runtime/interpreter/mterp/mips64/op_sget.S
index b7b0382..200da35 100644
--- a/runtime/interpreter/mterp/mips64/op_sget.S
+++ b/runtime/interpreter/mterp/mips64/op_sget.S
@@ -1,26 +1,2 @@
-%default { "is_object":"0", "helper":"MterpSGetU32", "extend":"" }
-    /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field//BBBB */
-    .extern $helper
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    ld      a1, OFF_FP_METHOD(rFP)
-    move    a2, rSELF
-    jal     $helper
-    ld      a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    srl     a2, rINST, 8                # a2 <- AA
-    $extend
-    PREFETCH_INST 2
-    bnez    a3, MterpException          # bail out
-    .if $is_object
-    SET_VREG_OBJECT v0, a2              # fp[AA] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[AA] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0
+%default { "is_object":"0", "helper":"MterpSGetU32" }
+%include "mips64/field.S" { }
diff --git a/runtime/interpreter/mterp/mips64/op_sget_boolean.S b/runtime/interpreter/mterp/mips64/op_sget_boolean.S
index fe2deb1..8abb396 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_boolean.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_boolean.S
@@ -1 +1 @@
-%include "mips64/op_sget.S" {"helper":"MterpSGetU8", "extend":"and v0, v0, 0xff"}
+%include "mips64/op_sget.S" {"helper":"MterpSGetU8"}
diff --git a/runtime/interpreter/mterp/mips64/op_sget_byte.S b/runtime/interpreter/mterp/mips64/op_sget_byte.S
index a7e2bef..68623f6 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_byte.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_byte.S
@@ -1 +1 @@
-%include "mips64/op_sget.S" {"helper":"MterpSGetI8", "extend":"seb v0, v0"}
+%include "mips64/op_sget.S" {"helper":"MterpSGetI8"}
diff --git a/runtime/interpreter/mterp/mips64/op_sget_char.S b/runtime/interpreter/mterp/mips64/op_sget_char.S
index ed86f32..3c7b962 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_char.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_char.S
@@ -1 +1 @@
-%include "mips64/op_sget.S" {"helper":"MterpSGetU16", "extend":"and v0, v0, 0xffff"}
+%include "mips64/op_sget.S" {"helper":"MterpSGetU16"}
diff --git a/runtime/interpreter/mterp/mips64/op_sget_short.S b/runtime/interpreter/mterp/mips64/op_sget_short.S
index f708a20..9a8579b 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_short.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_short.S
@@ -1 +1 @@
-%include "mips64/op_sget.S" {"helper":"MterpSGetI16", "extend":"seh v0, v0"}
+%include "mips64/op_sget.S" {"helper":"MterpSGetI16"}
diff --git a/runtime/interpreter/mterp/mips64/op_sget_wide.S b/runtime/interpreter/mterp/mips64/op_sget_wide.S
index 7c31252..14f232c 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_wide.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_wide.S
@@ -1,18 +1 @@
-    /*
-     * SGET_WIDE handler wrapper.
-     *
-     */
-    /* sget-wide vAA, field//BBBB */
-    .extern MterpSGetU64
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    ld      a1, OFF_FP_METHOD(rFP)
-    move    a2, rSELF
-    jal     MterpSGetU64
-    ld      a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    srl     a4, rINST, 8                # a4 <- AA
-    bnez    a3, MterpException          # bail out
-    FETCH_ADVANCE_INST 2                # advance rPC, load rINST
-    SET_VREG_WIDE v0, a4
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+%include "mips64/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/mips64/op_sput.S b/runtime/interpreter/mterp/mips64/op_sput.S
index 28b8c3e..0bd6837 100644
--- a/runtime/interpreter/mterp/mips64/op_sput.S
+++ b/runtime/interpreter/mterp/mips64/op_sput.S
@@ -1,20 +1,2 @@
-%default { "helper":"MterpSPutU32" }
-    /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field//BBBB */
-    .extern $helper
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    srl     a3, rINST, 8                # a3 <- AA
-    GET_VREG a1, a3                     # a1 <- fp[AA]
-    ld      a2, OFF_FP_METHOD(rFP)
-    move    a3, rSELF
-    PREFETCH_INST 2                     # Get next inst, but don't advance rPC
-    jal     $helper
-    bnezc   v0, MterpException          # 0 on success
-    ADVANCE 2                           # Past exception point - now advance rPC
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "mips64/field.S" { }
diff --git a/runtime/interpreter/mterp/mips64/op_sput_object.S b/runtime/interpreter/mterp/mips64/op_sput_object.S
index ff43967..09bd0fb 100644
--- a/runtime/interpreter/mterp/mips64/op_sput_object.S
+++ b/runtime/interpreter/mterp/mips64/op_sput_object.S
@@ -1,11 +1 @@
-    .extern MterpSPutObj
-    EXPORT_PC
-    daddu   a0, rFP, OFF_FP_SHADOWFRAME
-    move    a1, rPC
-    move    a2, rINST
-    move    a3, rSELF
-    jal     MterpSPutObj
-    beqzc   v0, MterpException
-    FETCH_ADVANCE_INST 2                # advance rPC, load rINST
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+%include "mips64/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/mips64/op_sput_wide.S b/runtime/interpreter/mterp/mips64/op_sput_wide.S
index bfb6983..070d17f 100644
--- a/runtime/interpreter/mterp/mips64/op_sput_wide.S
+++ b/runtime/interpreter/mterp/mips64/op_sput_wide.S
@@ -1,18 +1 @@
-    /*
-     * SPUT_WIDE handler wrapper.
-     *
-     */
-    /* sput-wide vAA, field//BBBB */
-    .extern MterpSPutU64
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    srl     a1, rINST, 8                # a2 <- AA
-    dlsa    a1, a1, rFP, 2
-    ld      a2, OFF_FP_METHOD(rFP)
-    move    a3, rSELF
-    PREFETCH_INST 2                     # Get next inst, but don't advance rPC
-    jal     MterpSPutU64
-    bnezc   v0, MterpException          # 0 on success, -1 on failure
-    ADVANCE 2                           # Past exception point - now advance rPC
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+%include "mips64/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc
index 7b37c9a..65c1aa8 100644
--- a/runtime/interpreter/mterp/mterp.cc
+++ b/runtime/interpreter/mterp/mterp.cc
@@ -490,24 +490,6 @@
   return true;
 }
 
-extern "C" size_t MterpSPutObj(ShadowFrame* shadow_frame, uint16_t* dex_pc_ptr,
-                                uint32_t inst_data, Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  const Instruction* inst = Instruction::At(dex_pc_ptr);
-  return DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, false, false>
-      (self, *shadow_frame, inst, inst_data);
-}
-
-extern "C" size_t MterpIPutObj(ShadowFrame* shadow_frame,
-                                  uint16_t* dex_pc_ptr,
-                                  uint32_t inst_data,
-                                  Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  const Instruction* inst = Instruction::At(dex_pc_ptr);
-  return DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, false, false>
-      (self, *shadow_frame, inst, inst_data);
-}
-
 extern "C" size_t MterpIputObjectQuick(ShadowFrame* shadow_frame,
                                        uint16_t* dex_pc_ptr,
                                        uint32_t inst_data)
@@ -681,352 +663,159 @@
   return MterpShouldSwitchInterpreters();
 }
 
-template<typename PrimType, typename RetType, typename Getter, FindFieldType kType>
-NO_INLINE RetType artGetInstanceFromMterp(uint32_t field_idx,
-                                          mirror::Object* obj,
-                                          ArtMethod* referrer,
-                                          Thread* self)
-      REQUIRES_SHARED(Locks::mutator_lock_) {
-  StackHandleScope<1> hs(self);
-  HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(&obj));  // GC might move the object.
-  ArtField* field = FindFieldFromCode<kType, /* access_checks */ false>(
-      field_idx, referrer, self, sizeof(PrimType));
-  if (UNLIKELY(field == nullptr)) {
-    return 0;  // Will throw exception by checking with Thread::Current.
+// Execute single field access instruction (get/put, static/instance).
+// The template arguments reduce this to fairly small amount of code.
+// It requires the target object and field to be already resolved.
+template<typename PrimType, FindFieldType kAccessType>
+ALWAYS_INLINE void MterpFieldAccess(Instruction* inst,
+                                    uint16_t inst_data,
+                                    ShadowFrame* shadow_frame,
+                                    ObjPtr<mirror::Object> obj,
+                                    MemberOffset offset,
+                                    bool is_volatile)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  static_assert(std::is_integral<PrimType>::value, "Unexpected primitive type");
+  constexpr bool kIsStatic = (kAccessType & FindFieldFlags::StaticBit) != 0;
+  constexpr bool kIsPrimitive = (kAccessType & FindFieldFlags::PrimitiveBit) != 0;
+  constexpr bool kIsRead = (kAccessType & FindFieldFlags::ReadBit) != 0;
+
+  uint16_t vRegA = kIsStatic ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data);
+  if (kIsPrimitive) {
+    if (kIsRead) {
+      PrimType value = UNLIKELY(is_volatile)
+          ? obj->GetFieldPrimitive<PrimType, /*kIsVolatile*/ true>(offset)
+          : obj->GetFieldPrimitive<PrimType, /*kIsVolatile*/ false>(offset);
+      if (sizeof(PrimType) == sizeof(uint64_t)) {
+        shadow_frame->SetVRegLong(vRegA, value);  // Set two consecutive registers.
+      } else {
+        shadow_frame->SetVReg(vRegA, static_cast<int32_t>(value));  // Sign/zero extend.
+      }
+    } else {  // Write.
+      uint64_t value = (sizeof(PrimType) == sizeof(uint64_t))
+          ? shadow_frame->GetVRegLong(vRegA)
+          : shadow_frame->GetVReg(vRegA);
+      if (UNLIKELY(is_volatile)) {
+        obj->SetFieldPrimitive<PrimType, /*kIsVolatile*/ true>(offset, value);
+      } else {
+        obj->SetFieldPrimitive<PrimType, /*kIsVolatile*/ false>(offset, value);
+      }
+    }
+  } else {  // Object.
+    if (kIsRead) {
+      ObjPtr<mirror::Object> value = UNLIKELY(is_volatile)
+          ? obj->GetFieldObjectVolatile<mirror::Object>(offset)
+          : obj->GetFieldObject<mirror::Object>(offset);
+      shadow_frame->SetVRegReference(vRegA, value);
+    } else {  // Write.
+      ObjPtr<mirror::Object> value = shadow_frame->GetVRegReference(vRegA);
+      if (UNLIKELY(is_volatile)) {
+        obj->SetFieldObjectVolatile</*kTransactionActive*/ false>(offset, value);
+      } else {
+        obj->SetFieldObject</*kTransactionActive*/ false>(offset, value);
+      }
+    }
   }
-  if (UNLIKELY(h == nullptr)) {
-    ThrowNullPointerExceptionForFieldAccess(field, /*is_read*/ true);
-    return 0;  // Will throw exception by checking with Thread::Current.
-  }
-  return Getter::Get(obj, field);
 }
 
-template<typename PrimType, typename RetType, typename Getter>
-ALWAYS_INLINE RetType artGetInstanceFromMterpFast(uint32_t field_idx,
-                                                  mirror::Object* obj,
-                                                  ArtMethod* referrer,
-                                                  Thread* self)
-      REQUIRES_SHARED(Locks::mutator_lock_) {
-  constexpr bool kIsObject = std::is_same<RetType, mirror::Object*>::value;
-  constexpr FindFieldType kType = kIsObject ? InstanceObjectRead : InstancePrimitiveRead;
+template<typename PrimType, FindFieldType kAccessType>
+NO_INLINE bool MterpFieldAccessSlow(Instruction* inst,
+                                    uint16_t inst_data,
+                                    ShadowFrame* shadow_frame,
+                                    Thread* self)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  constexpr bool kIsStatic = (kAccessType & FindFieldFlags::StaticBit) != 0;
+  constexpr bool kIsRead = (kAccessType & FindFieldFlags::ReadBit) != 0;
+
+  // Update the dex pc in shadow frame, just in case anything throws.
+  shadow_frame->SetDexPCPtr(reinterpret_cast<uint16_t*>(inst));
+  ArtMethod* referrer = shadow_frame->GetMethod();
+  uint32_t field_idx = kIsStatic ? inst->VRegB_21c() : inst->VRegC_22c();
+  ArtField* field = FindFieldFromCode<kAccessType, /* access_checks */ false>(
+      field_idx, referrer, self, sizeof(PrimType));
+  if (UNLIKELY(field == nullptr)) {
+    DCHECK(self->IsExceptionPending());
+    return false;
+  }
+  ObjPtr<mirror::Object> obj = kIsStatic
+      ? field->GetDeclaringClass().Ptr()
+      : shadow_frame->GetVRegReference(inst->VRegB_22c(inst_data));
+  if (UNLIKELY(obj == nullptr)) {
+    ThrowNullPointerExceptionForFieldAccess(field, kIsRead);
+    return false;
+  }
+  MterpFieldAccess<PrimType, kAccessType>(
+      inst, inst_data, shadow_frame, obj, field->GetOffset(), field->IsVolatile());
+  return true;
+}
+
+template<typename PrimType, FindFieldType kAccessType>
+ALWAYS_INLINE bool MterpFieldAccessFast(Instruction* inst,
+                                        uint16_t inst_data,
+                                        ShadowFrame* shadow_frame,
+                                        Thread* self)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  constexpr bool kIsStatic = (kAccessType & FindFieldFlags::StaticBit) != 0;
 
   // This effectively inlines the fast path from ArtMethod::GetDexCache.
   // It avoids non-inlined call which in turn allows elimination of the prologue and epilogue.
+  ArtMethod* referrer = shadow_frame->GetMethod();
   if (LIKELY(!referrer->IsObsolete())) {
     // Avoid read barriers, since we need only the pointer to the native (non-movable)
     // DexCache field array which we can get even through from-space objects.
     ObjPtr<mirror::Class> klass = referrer->GetDeclaringClass<kWithoutReadBarrier>();
     mirror::DexCache* dex_cache = klass->GetDexCache<kDefaultVerifyFlags, kWithoutReadBarrier>();
+
     // Try to find the desired field in DexCache.
+    uint32_t field_idx = kIsStatic ? inst->VRegB_21c() : inst->VRegC_22c();
     ArtField* field = dex_cache->GetResolvedField(field_idx, kRuntimePointerSize);
-    if (LIKELY(field != nullptr & obj != nullptr)) {
-      if (kIsDebugBuild) {
-        // Compare the fast path and slow path.
-        StackHandleScope<1> hs(self);
-        HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(&obj));  // GC might move the object.
-        DCHECK_EQ(field, (FindFieldFromCode<kType, /* access_checks */ false>(
+    if (LIKELY(field != nullptr)) {
+      bool initialized = !kIsStatic || field->GetDeclaringClass()->IsInitialized();
+      if (LIKELY(initialized)) {
+        DCHECK_EQ(field, (FindFieldFromCode<kAccessType, /* access_checks */ false>(
             field_idx, referrer, self, sizeof(PrimType))));
+        ObjPtr<mirror::Object> obj = kIsStatic
+            ? field->GetDeclaringClass().Ptr()
+            : shadow_frame->GetVRegReference(inst->VRegB_22c(inst_data));
+        if (LIKELY(kIsStatic || obj != nullptr)) {
+          MterpFieldAccess<PrimType, kAccessType>(
+              inst, inst_data, shadow_frame, obj, field->GetOffset(), field->IsVolatile());
+          return true;
+        }
       }
-      return Getter::Get(obj, field);
     }
   }
+
   // Slow path. Last and with identical arguments so that it becomes single instruction tail call.
-  return artGetInstanceFromMterp<PrimType, RetType, Getter, kType>(field_idx, obj, referrer, self);
+  return MterpFieldAccessSlow<PrimType, kAccessType>(inst, inst_data, shadow_frame, self);
 }
 
-#define ART_GET_FIELD_FROM_MTERP(Suffix, Kind, PrimType, RetType, Ptr)                            \
-extern "C" RetType MterpIGet ## Suffix(uint32_t field_idx,                                        \
-                                       mirror::Object* obj,                                       \
-                                       ArtMethod* referrer,                                       \
-                                       Thread* self)                                              \
-      REQUIRES_SHARED(Locks::mutator_lock_) {                                                     \
-  struct Getter { /* Specialize the field load depending on the field type */                     \
-    static RetType Get(mirror::Object* o, ArtField* f) REQUIRES_SHARED(Locks::mutator_lock_) {    \
-      return f->Get##Kind(o)Ptr;                                                                  \
-    }                                                                                             \
-  };                                                                                              \
-  return artGetInstanceFromMterpFast<PrimType, RetType, Getter>(field_idx, obj, referrer, self);  \
-}                                                                                                 \
-
-ART_GET_FIELD_FROM_MTERP(I8, Byte, int8_t, ssize_t, )
-ART_GET_FIELD_FROM_MTERP(U8, Boolean, uint8_t, size_t, )
-ART_GET_FIELD_FROM_MTERP(I16, Short, int16_t, ssize_t, )
-ART_GET_FIELD_FROM_MTERP(U16, Char, uint16_t, size_t, )
-ART_GET_FIELD_FROM_MTERP(U32, 32, uint32_t, size_t, )
-ART_GET_FIELD_FROM_MTERP(U64, 64, uint64_t, uint64_t, )
-ART_GET_FIELD_FROM_MTERP(Obj, Obj, mirror::HeapReference<mirror::Object>, mirror::Object*, .Ptr())
-
-#undef ART_GET_FIELD_FROM_MTERP
-
-extern "C" ssize_t MterpIPutU8(uint32_t field_idx,
-                               mirror::Object* obj,
-                               uint8_t new_value,
-                               ArtMethod* referrer)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
-  if (LIKELY(field != nullptr && obj != nullptr)) {
-    field->SetBoolean<false>(obj, new_value);
-    return 0;  // success
-  }
-  return -1;  // failure
+#define MTERP_FIELD_ACCESSOR(Name, PrimType, AccessType)                                          \
+extern "C" bool Name(Instruction* inst, uint16_t inst_data, ShadowFrame* sf, Thread* self)        \
+    REQUIRES_SHARED(Locks::mutator_lock_) {                                                       \
+  return MterpFieldAccessFast<PrimType, AccessType>(inst, inst_data, sf, self);                   \
 }
 
-extern "C" ssize_t MterpIPutI8(uint32_t field_idx,
-                               mirror::Object* obj,
-                               uint8_t new_value,
-                               ArtMethod* referrer)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
-  if (LIKELY(field != nullptr && obj != nullptr)) {
-    field->SetByte<false>(obj, new_value);
-    return 0;  // success
-  }
-  return -1;  // failure
-}
+#define MTERP_FIELD_ACCESSORS_FOR_TYPE(Sufix, PrimType, Kind)                                     \
+  MTERP_FIELD_ACCESSOR(MterpIGet##Sufix, PrimType, Instance##Kind##Read)                          \
+  MTERP_FIELD_ACCESSOR(MterpIPut##Sufix, PrimType, Instance##Kind##Write)                         \
+  MTERP_FIELD_ACCESSOR(MterpSGet##Sufix, PrimType, Static##Kind##Read)                            \
+  MTERP_FIELD_ACCESSOR(MterpSPut##Sufix, PrimType, Static##Kind##Write)
 
-extern "C" ssize_t MterpIPutU16(uint32_t field_idx,
-                                mirror::Object* obj,
-                                uint16_t new_value,
-                                ArtMethod* referrer)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
-  if (LIKELY(field != nullptr && obj != nullptr)) {
-    field->SetChar<false>(obj, new_value);
-    return 0;  // success
-  }
-  return -1;  // failure
-}
+MTERP_FIELD_ACCESSORS_FOR_TYPE(I8, int8_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(U8, uint8_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(I16, int16_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(U16, uint16_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(U32, uint32_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(U64, uint64_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(Obj, uint32_t, Object)
 
-extern "C" ssize_t MterpIPutI16(uint32_t field_idx,
-                                mirror::Object* obj,
-                                uint16_t new_value,
-                                ArtMethod* referrer)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
-  if (LIKELY(field != nullptr && obj != nullptr)) {
-    field->SetShort<false>(obj, new_value);
-    return 0;  // success
-  }
-  return -1;  // failure
-}
+// Check that the primitive type for Obj variant above is correct.
+// It really must be primitive type for the templates to compile.
+// In the case of objects, it is only used to get the field size.
+static_assert(kHeapReferenceSize == sizeof(uint32_t), "Unexpected kHeapReferenceSize");
 
-extern "C" ssize_t MterpIPutU32(uint32_t field_idx,
-                                mirror::Object* obj,
-                                uint32_t new_value,
-                                ArtMethod* referrer)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
-  if (LIKELY(field != nullptr && obj != nullptr)) {
-    field->Set32<false>(obj, new_value);
-    return 0;  // success
-  }
-  return -1;  // failure
-}
-
-extern "C" ssize_t MterpIPutU64(uint32_t field_idx,
-                                mirror::Object* obj,
-                                uint64_t* new_value,
-                                ArtMethod* referrer)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
-  if (LIKELY(field != nullptr  && obj != nullptr)) {
-    field->Set64<false>(obj, *new_value);
-    return 0;  // success
-  }
-  return -1;  // failure
-}
-
-extern "C" ssize_t artSetObjInstanceFromMterp(uint32_t field_idx,
-                                              mirror::Object* obj,
-                                              mirror::Object* new_value,
-                                              ArtMethod* referrer)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
-  if (LIKELY(field != nullptr && obj != nullptr)) {
-    field->SetObj<false>(obj, new_value);
-    return 0;  // success
-  }
-  return -1;  // failure
-}
-
-template <typename return_type, Primitive::Type primitive_type>
-ALWAYS_INLINE return_type MterpGetStatic(uint32_t field_idx,
-                                         ArtMethod* referrer,
-                                         Thread* self,
-                                         return_type (ArtField::*func)(ObjPtr<mirror::Object>))
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return_type res = 0;  // On exception, the result will be ignored.
-  ArtField* f =
-      FindFieldFromCode<StaticPrimitiveRead, false>(field_idx,
-                                                    referrer,
-                                                    self,
-                                                    primitive_type);
-  if (LIKELY(f != nullptr)) {
-    ObjPtr<mirror::Object> obj = f->GetDeclaringClass();
-    res = (f->*func)(obj);
-  }
-  return res;
-}
-
-extern "C" int32_t MterpSGetU8(uint32_t field_idx,
-                               ArtMethod* referrer,
-                               Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return MterpGetStatic<uint8_t, Primitive::kPrimBoolean>(field_idx,
-                                                          referrer,
-                                                          self,
-                                                          &ArtField::GetBoolean);
-}
-
-extern "C" int32_t MterpSGetI8(uint32_t field_idx,
-                               ArtMethod* referrer,
-                               Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return MterpGetStatic<int8_t, Primitive::kPrimByte>(field_idx,
-                                                      referrer,
-                                                      self,
-                                                      &ArtField::GetByte);
-}
-
-extern "C" uint32_t MterpSGetU16(uint32_t field_idx,
-                                 ArtMethod* referrer,
-                                 Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return MterpGetStatic<uint16_t, Primitive::kPrimChar>(field_idx,
-                                                        referrer,
-                                                        self,
-                                                        &ArtField::GetChar);
-}
-
-extern "C" int32_t MterpSGetI16(uint32_t field_idx,
-                                ArtMethod* referrer,
-                                Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return MterpGetStatic<int16_t, Primitive::kPrimShort>(field_idx,
-                                                        referrer,
-                                                        self,
-                                                        &ArtField::GetShort);
-}
-
-extern "C" mirror::Object* MterpSGetObj(uint32_t field_idx,
-                                        ArtMethod* referrer,
-                                        Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return MterpGetStatic<ObjPtr<mirror::Object>, Primitive::kPrimNot>(field_idx,
-                                                                     referrer,
-                                                                     self,
-                                                                     &ArtField::GetObject).Ptr();
-}
-
-extern "C" int32_t MterpSGetU32(uint32_t field_idx,
-                                ArtMethod* referrer,
-                                Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return MterpGetStatic<int32_t, Primitive::kPrimInt>(field_idx,
-                                                      referrer,
-                                                      self,
-                                                      &ArtField::GetInt);
-}
-
-extern "C" int64_t MterpSGetU64(uint32_t field_idx, ArtMethod* referrer, Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return MterpGetStatic<int64_t, Primitive::kPrimLong>(field_idx,
-                                                       referrer,
-                                                       self,
-                                                       &ArtField::GetLong);
-}
-
-
-template <typename field_type, Primitive::Type primitive_type>
-int MterpSetStatic(uint32_t field_idx,
-                   field_type new_value,
-                   ArtMethod* referrer,
-                   Thread* self,
-                   void (ArtField::*func)(ObjPtr<mirror::Object>, field_type val))
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  int res = 0;  // Assume success (following quick_field_entrypoints conventions)
-  ArtField* f =
-      FindFieldFromCode<StaticPrimitiveWrite, false>(field_idx, referrer, self, primitive_type);
-  if (LIKELY(f != nullptr)) {
-    ObjPtr<mirror::Object> obj = f->GetDeclaringClass();
-    (f->*func)(obj, new_value);
-  } else {
-    res = -1;  // Failure
-  }
-  return res;
-}
-
-extern "C" int MterpSPutU8(uint32_t field_idx,
-                           uint8_t new_value,
-                           ArtMethod* referrer,
-                           Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return MterpSetStatic<uint8_t, Primitive::kPrimBoolean>(field_idx,
-                                                          new_value,
-                                                          referrer,
-                                                          self,
-                                                          &ArtField::SetBoolean<false>);
-}
-
-extern "C" int MterpSPutI8(uint32_t field_idx,
-                           int8_t new_value,
-                           ArtMethod* referrer,
-                           Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return MterpSetStatic<int8_t, Primitive::kPrimByte>(field_idx,
-                                                      new_value,
-                                                      referrer,
-                                                      self,
-                                                      &ArtField::SetByte<false>);
-}
-
-extern "C" int MterpSPutU16(uint32_t field_idx,
-                            uint16_t new_value,
-                            ArtMethod* referrer,
-                            Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return MterpSetStatic<uint16_t, Primitive::kPrimChar>(field_idx,
-                                                        new_value,
-                                                        referrer,
-                                                        self,
-                                                        &ArtField::SetChar<false>);
-}
-
-extern "C" int MterpSPutI16(uint32_t field_idx,
-                            int16_t new_value,
-                            ArtMethod* referrer,
-                            Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return MterpSetStatic<int16_t, Primitive::kPrimShort>(field_idx,
-                                                        new_value,
-                                                        referrer,
-                                                        self,
-                                                        &ArtField::SetShort<false>);
-}
-
-extern "C" int MterpSPutU32(uint32_t field_idx,
-                            int32_t new_value,
-                            ArtMethod* referrer,
-                            Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return MterpSetStatic<int32_t, Primitive::kPrimInt>(field_idx,
-                                                      new_value,
-                                                      referrer,
-                                                      self,
-                                                      &ArtField::SetInt<false>);
-}
-
-extern "C" int MterpSPutU64(uint32_t field_idx,
-                            int64_t* new_value,
-                            ArtMethod* referrer,
-                            Thread* self)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return MterpSetStatic<int64_t, Primitive::kPrimLong>(field_idx,
-                                                       *new_value,
-                                                       referrer,
-                                                       self,
-                                                       &ArtField::SetLong<false>);
-}
+#undef MTERP_FIELD_ACCESSORS_FOR_TYPE
+#undef MTERP_FIELD_ACCESSOR
 
 extern "C" mirror::Object* artAGetObjectFromMterp(mirror::Object* arr,
                                                   int32_t index)
diff --git a/runtime/interpreter/mterp/out/mterp_arm.S b/runtime/interpreter/mterp/out/mterp_arm.S
index 394a849..25512ae 100644
--- a/runtime/interpreter/mterp/out/mterp_arm.S
+++ b/runtime/interpreter/mterp/out/mterp_arm.S
@@ -2246,215 +2246,185 @@
     .balign 128
 .L_op_iget: /* 0x52 */
 /* File: arm/op_iget.S */
+/* File: arm/field.S */
     /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    r0, 1                         @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12            @ r1<- B
-    GET_VREG r1, r1                        @ r1<- fp[B], the object pointer
-    ldr      r2, [rFP, #OFF_FP_METHOD]     @ r2<- referrer
-    mov      r3, rSELF                     @ r3<- self
+    .extern MterpIGetU32
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
     bl       MterpIGetU32
-    ldr      r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    ubfx     r2, rINST, #8, #4             @ r2<- A
-    PREFETCH_INST 2
-    cmp      r3, #0
-    bne      MterpPossibleException        @ bail out
-    .if 0
-    SET_VREG_OBJECT r0, r2                 @ fp[A]<- r0
-    .else
-    SET_VREG r0, r2                        @ fp[A]<- r0
-    .endif
+    cmp      r0, #0
+    beq      MterpPossibleException
     ADVANCE 2
     GET_INST_OPCODE ip                     @ extract opcode from rINST
     GOTO_OPCODE ip                         @ jump to next instruction
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_wide: /* 0x53 */
 /* File: arm/op_iget_wide.S */
+/* File: arm/op_iget.S */
+/* File: arm/field.S */
     /*
-     * 64-bit instance field get.
-     *
-     * for: iget-wide
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    r0, 1                         @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12            @ r1<- B
-    GET_VREG r1, r1                        @ r1<- fp[B], the object pointer
-    ldr      r2, [rFP, #OFF_FP_METHOD]     @ r2<- referrer
-    mov      r3, rSELF                     @ r3<- self
+    .extern MterpIGetU64
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
     bl       MterpIGetU64
-    ldr      r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    ubfx     r2, rINST, #8, #4             @ r2<- A
-    PREFETCH_INST 2
-    cmp      r3, #0
-    bne      MterpException                @ bail out
-    CLEAR_SHADOW_PAIR r2, ip, lr           @ Zero out the shadow regs
-    VREG_INDEX_TO_ADDR r3, r2              @ r3<- &fp[A]
-    stmia    r3, {r0-r1}                   @ fp[A]<- r0/r1
+    cmp      r0, #0
+    beq      MterpPossibleException
     ADVANCE 2
     GET_INST_OPCODE ip                     @ extract opcode from rINST
     GOTO_OPCODE ip                         @ jump to next instruction
 
+
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_object: /* 0x54 */
 /* File: arm/op_iget_object.S */
 /* File: arm/op_iget.S */
+/* File: arm/field.S */
     /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    r0, 1                         @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12            @ r1<- B
-    GET_VREG r1, r1                        @ r1<- fp[B], the object pointer
-    ldr      r2, [rFP, #OFF_FP_METHOD]     @ r2<- referrer
-    mov      r3, rSELF                     @ r3<- self
+    .extern MterpIGetObj
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
     bl       MterpIGetObj
-    ldr      r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    ubfx     r2, rINST, #8, #4             @ r2<- A
-    PREFETCH_INST 2
-    cmp      r3, #0
-    bne      MterpPossibleException        @ bail out
-    .if 1
-    SET_VREG_OBJECT r0, r2                 @ fp[A]<- r0
-    .else
-    SET_VREG r0, r2                        @ fp[A]<- r0
-    .endif
+    cmp      r0, #0
+    beq      MterpPossibleException
     ADVANCE 2
     GET_INST_OPCODE ip                     @ extract opcode from rINST
     GOTO_OPCODE ip                         @ jump to next instruction
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_boolean: /* 0x55 */
 /* File: arm/op_iget_boolean.S */
 /* File: arm/op_iget.S */
+/* File: arm/field.S */
     /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    r0, 1                         @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12            @ r1<- B
-    GET_VREG r1, r1                        @ r1<- fp[B], the object pointer
-    ldr      r2, [rFP, #OFF_FP_METHOD]     @ r2<- referrer
-    mov      r3, rSELF                     @ r3<- self
+    .extern MterpIGetU8
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
     bl       MterpIGetU8
-    ldr      r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    ubfx     r2, rINST, #8, #4             @ r2<- A
-    PREFETCH_INST 2
-    cmp      r3, #0
-    bne      MterpPossibleException        @ bail out
-    .if 0
-    SET_VREG_OBJECT r0, r2                 @ fp[A]<- r0
-    .else
-    SET_VREG r0, r2                        @ fp[A]<- r0
-    .endif
+    cmp      r0, #0
+    beq      MterpPossibleException
     ADVANCE 2
     GET_INST_OPCODE ip                     @ extract opcode from rINST
     GOTO_OPCODE ip                         @ jump to next instruction
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_byte: /* 0x56 */
 /* File: arm/op_iget_byte.S */
 /* File: arm/op_iget.S */
+/* File: arm/field.S */
     /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    r0, 1                         @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12            @ r1<- B
-    GET_VREG r1, r1                        @ r1<- fp[B], the object pointer
-    ldr      r2, [rFP, #OFF_FP_METHOD]     @ r2<- referrer
-    mov      r3, rSELF                     @ r3<- self
+    .extern MterpIGetI8
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
     bl       MterpIGetI8
-    ldr      r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    ubfx     r2, rINST, #8, #4             @ r2<- A
-    PREFETCH_INST 2
-    cmp      r3, #0
-    bne      MterpPossibleException        @ bail out
-    .if 0
-    SET_VREG_OBJECT r0, r2                 @ fp[A]<- r0
-    .else
-    SET_VREG r0, r2                        @ fp[A]<- r0
-    .endif
+    cmp      r0, #0
+    beq      MterpPossibleException
     ADVANCE 2
     GET_INST_OPCODE ip                     @ extract opcode from rINST
     GOTO_OPCODE ip                         @ jump to next instruction
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_char: /* 0x57 */
 /* File: arm/op_iget_char.S */
 /* File: arm/op_iget.S */
+/* File: arm/field.S */
     /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    r0, 1                         @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12            @ r1<- B
-    GET_VREG r1, r1                        @ r1<- fp[B], the object pointer
-    ldr      r2, [rFP, #OFF_FP_METHOD]     @ r2<- referrer
-    mov      r3, rSELF                     @ r3<- self
+    .extern MterpIGetU16
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
     bl       MterpIGetU16
-    ldr      r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    ubfx     r2, rINST, #8, #4             @ r2<- A
-    PREFETCH_INST 2
-    cmp      r3, #0
-    bne      MterpPossibleException        @ bail out
-    .if 0
-    SET_VREG_OBJECT r0, r2                 @ fp[A]<- r0
-    .else
-    SET_VREG r0, r2                        @ fp[A]<- r0
-    .endif
+    cmp      r0, #0
+    beq      MterpPossibleException
     ADVANCE 2
     GET_INST_OPCODE ip                     @ extract opcode from rINST
     GOTO_OPCODE ip                         @ jump to next instruction
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_short: /* 0x58 */
 /* File: arm/op_iget_short.S */
 /* File: arm/op_iget.S */
+/* File: arm/field.S */
     /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    r0, 1                         @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12            @ r1<- B
-    GET_VREG r1, r1                        @ r1<- fp[B], the object pointer
-    ldr      r2, [rFP, #OFF_FP_METHOD]     @ r2<- referrer
-    mov      r3, rSELF                     @ r3<- self
+    .extern MterpIGetI16
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
     bl       MterpIGetI16
-    ldr      r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    ubfx     r2, rINST, #8, #4             @ r2<- A
-    PREFETCH_INST 2
-    cmp      r3, #0
-    bne      MterpPossibleException        @ bail out
-    .if 0
-    SET_VREG_OBJECT r0, r2                 @ fp[A]<- r0
-    .else
-    SET_VREG r0, r2                        @ fp[A]<- r0
-    .endif
+    cmp      r0, #0
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
+
+
+/* ------------------------------ */
+    .balign 128
+.L_op_iput: /* 0x59 */
+/* File: arm/op_iput.S */
+/* File: arm/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIPutU32
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpIPutU32
+    cmp      r0, #0
+    beq      MterpPossibleException
     ADVANCE 2
     GET_INST_OPCODE ip                     @ extract opcode from rINST
     GOTO_OPCODE ip                         @ jump to next instruction
@@ -2462,93 +2432,74 @@
 
 /* ------------------------------ */
     .balign 128
-.L_op_iput: /* 0x59 */
-/* File: arm/op_iput.S */
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field@CCCC */
-    .extern MterpIPutU32
-    EXPORT_PC
-    FETCH    r0, 1                      @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12         @ r1<- B
-    GET_VREG r1, r1                     @ r1<- fp[B], the object pointer
-    ubfx     r2, rINST, #8, #4          @ r2<- A
-    GET_VREG r2, r2                     @ r2<- fp[A]
-    ldr      r3, [rFP, #OFF_FP_METHOD]  @ r3<- referrer
-    PREFETCH_INST 2
-    bl       MterpIPutU32
-    cmp      r0, #0
-    bne      MterpPossibleException
-    ADVANCE  2                          @ advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
-
-/* ------------------------------ */
-    .balign 128
 .L_op_iput_wide: /* 0x5a */
 /* File: arm/op_iput_wide.S */
-    /* iput-wide vA, vB, field@CCCC */
+/* File: arm/op_iput.S */
+/* File: arm/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutU64
-    EXPORT_PC
-    FETCH    r0, 1                      @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12         @ r1<- B
-    GET_VREG r1, r1                     @ r1<- fp[B], the object pointer
-    ubfx     r2, rINST, #8, #4          @ r2<- A
-    VREG_INDEX_TO_ADDR r2, r2           @ r2<- &fp[A]
-    ldr      r3, [rFP, #OFF_FP_METHOD]  @ r3<- referrer
-    PREFETCH_INST 2
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
     bl       MterpIPutU64
     cmp      r0, #0
-    bne      MterpPossibleException
-    ADVANCE  2                          @ advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iput_object: /* 0x5b */
 /* File: arm/op_iput_object.S */
-    EXPORT_PC
-    add     r0, rFP, #OFF_FP_SHADOWFRAME
-    mov     r1, rPC
-    mov     r2, rINST
-    mov     r3, rSELF
-    bl      MterpIPutObj
-    cmp     r0, #0
-    beq     MterpException
-    FETCH_ADVANCE_INST 2                @ advance rPC, load rINST
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+/* File: arm/op_iput.S */
+/* File: arm/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIPutObj
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpIPutObj
+    cmp      r0, #0
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iput_boolean: /* 0x5c */
 /* File: arm/op_iput_boolean.S */
 /* File: arm/op_iput.S */
+/* File: arm/field.S */
     /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vA, vB, field@CCCC */
     .extern MterpIPutU8
-    EXPORT_PC
-    FETCH    r0, 1                      @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12         @ r1<- B
-    GET_VREG r1, r1                     @ r1<- fp[B], the object pointer
-    ubfx     r2, rINST, #8, #4          @ r2<- A
-    GET_VREG r2, r2                     @ r2<- fp[A]
-    ldr      r3, [rFP, #OFF_FP_METHOD]  @ r3<- referrer
-    PREFETCH_INST 2
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
     bl       MterpIPutU8
     cmp      r0, #0
-    bne      MterpPossibleException
-    ADVANCE  2                          @ advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2556,27 +2507,23 @@
 .L_op_iput_byte: /* 0x5d */
 /* File: arm/op_iput_byte.S */
 /* File: arm/op_iput.S */
+/* File: arm/field.S */
     /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vA, vB, field@CCCC */
     .extern MterpIPutI8
-    EXPORT_PC
-    FETCH    r0, 1                      @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12         @ r1<- B
-    GET_VREG r1, r1                     @ r1<- fp[B], the object pointer
-    ubfx     r2, rINST, #8, #4          @ r2<- A
-    GET_VREG r2, r2                     @ r2<- fp[A]
-    ldr      r3, [rFP, #OFF_FP_METHOD]  @ r3<- referrer
-    PREFETCH_INST 2
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
     bl       MterpIPutI8
     cmp      r0, #0
-    bne      MterpPossibleException
-    ADVANCE  2                          @ advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2584,27 +2531,23 @@
 .L_op_iput_char: /* 0x5e */
 /* File: arm/op_iput_char.S */
 /* File: arm/op_iput.S */
+/* File: arm/field.S */
     /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vA, vB, field@CCCC */
     .extern MterpIPutU16
-    EXPORT_PC
-    FETCH    r0, 1                      @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12         @ r1<- B
-    GET_VREG r1, r1                     @ r1<- fp[B], the object pointer
-    ubfx     r2, rINST, #8, #4          @ r2<- A
-    GET_VREG r2, r2                     @ r2<- fp[A]
-    ldr      r3, [rFP, #OFF_FP_METHOD]  @ r3<- referrer
-    PREFETCH_INST 2
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
     bl       MterpIPutU16
     cmp      r0, #0
-    bne      MterpPossibleException
-    ADVANCE  2                          @ advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2612,118 +2555,93 @@
 .L_op_iput_short: /* 0x5f */
 /* File: arm/op_iput_short.S */
 /* File: arm/op_iput.S */
+/* File: arm/field.S */
     /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vA, vB, field@CCCC */
     .extern MterpIPutI16
-    EXPORT_PC
-    FETCH    r0, 1                      @ r0<- field ref CCCC
-    mov      r1, rINST, lsr #12         @ r1<- B
-    GET_VREG r1, r1                     @ r1<- fp[B], the object pointer
-    ubfx     r2, rINST, #8, #4          @ r2<- A
-    GET_VREG r2, r2                     @ r2<- fp[A]
-    ldr      r3, [rFP, #OFF_FP_METHOD]  @ r3<- referrer
-    PREFETCH_INST 2
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
     bl       MterpIPutI16
     cmp      r0, #0
-    bne      MterpPossibleException
-    ADVANCE  2                          @ advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 
 /* ------------------------------ */
     .balign 128
 .L_op_sget: /* 0x60 */
 /* File: arm/op_sget.S */
+/* File: arm/field.S */
     /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field@BBBB */
-
     .extern MterpSGetU32
-    EXPORT_PC
-    FETCH r0, 1                         @ r0<- field ref BBBB
-    ldr   r1, [rFP, #OFF_FP_METHOD]
-    mov   r2, rSELF
-    bl    MterpSGetU32
-    ldr   r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    mov   r2, rINST, lsr #8             @ r2<- AA
-    PREFETCH_INST 2
-    cmp   r3, #0                        @ Fail to resolve?
-    bne   MterpException                @ bail out
-.if 0
-    SET_VREG_OBJECT r0, r2              @ fp[AA]<- r0
-.else
-    SET_VREG r0, r2                     @ fp[AA]<- r0
-.endif
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSGetU32
+    cmp      r0, #0
+    beq      MterpPossibleException
     ADVANCE 2
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sget_wide: /* 0x61 */
 /* File: arm/op_sget_wide.S */
+/* File: arm/op_sget.S */
+/* File: arm/field.S */
     /*
-     * SGET_WIDE handler wrapper.
-     *
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* sget-wide vAA, field@BBBB */
-
     .extern MterpSGetU64
-    EXPORT_PC
-    FETCH r0, 1                         @ r0<- field ref BBBB
-    ldr   r1, [rFP, #OFF_FP_METHOD]
-    mov   r2, rSELF
-    bl    MterpSGetU64
-    ldr   r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    mov   r9, rINST, lsr #8             @ r9<- AA
-    VREG_INDEX_TO_ADDR lr, r9           @ r9<- &fp[AA]
-    cmp   r3, #0                        @ Fail to resolve?
-    bne   MterpException                @ bail out
-    FETCH_ADVANCE_INST 2                @ advance rPC, load rINST
-    CLEAR_SHADOW_PAIR r9, r2, ip        @ Zero out the shadow regs
-    stmia lr, {r0-r1}                   @ vAA/vAA+1<- r0/r1
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSGetU64
+    cmp      r0, #0
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sget_object: /* 0x62 */
 /* File: arm/op_sget_object.S */
 /* File: arm/op_sget.S */
+/* File: arm/field.S */
     /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field@BBBB */
-
     .extern MterpSGetObj
-    EXPORT_PC
-    FETCH r0, 1                         @ r0<- field ref BBBB
-    ldr   r1, [rFP, #OFF_FP_METHOD]
-    mov   r2, rSELF
-    bl    MterpSGetObj
-    ldr   r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    mov   r2, rINST, lsr #8             @ r2<- AA
-    PREFETCH_INST 2
-    cmp   r3, #0                        @ Fail to resolve?
-    bne   MterpException                @ bail out
-.if 1
-    SET_VREG_OBJECT r0, r2              @ fp[AA]<- r0
-.else
-    SET_VREG r0, r2                     @ fp[AA]<- r0
-.endif
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSGetObj
+    cmp      r0, #0
+    beq      MterpPossibleException
     ADVANCE 2
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2731,32 +2649,23 @@
 .L_op_sget_boolean: /* 0x63 */
 /* File: arm/op_sget_boolean.S */
 /* File: arm/op_sget.S */
+/* File: arm/field.S */
     /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field@BBBB */
-
     .extern MterpSGetU8
-    EXPORT_PC
-    FETCH r0, 1                         @ r0<- field ref BBBB
-    ldr   r1, [rFP, #OFF_FP_METHOD]
-    mov   r2, rSELF
-    bl    MterpSGetU8
-    ldr   r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    mov   r2, rINST, lsr #8             @ r2<- AA
-    PREFETCH_INST 2
-    cmp   r3, #0                        @ Fail to resolve?
-    bne   MterpException                @ bail out
-.if 0
-    SET_VREG_OBJECT r0, r2              @ fp[AA]<- r0
-.else
-    SET_VREG r0, r2                     @ fp[AA]<- r0
-.endif
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSGetU8
+    cmp      r0, #0
+    beq      MterpPossibleException
     ADVANCE 2
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2764,32 +2673,23 @@
 .L_op_sget_byte: /* 0x64 */
 /* File: arm/op_sget_byte.S */
 /* File: arm/op_sget.S */
+/* File: arm/field.S */
     /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field@BBBB */
-
     .extern MterpSGetI8
-    EXPORT_PC
-    FETCH r0, 1                         @ r0<- field ref BBBB
-    ldr   r1, [rFP, #OFF_FP_METHOD]
-    mov   r2, rSELF
-    bl    MterpSGetI8
-    ldr   r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    mov   r2, rINST, lsr #8             @ r2<- AA
-    PREFETCH_INST 2
-    cmp   r3, #0                        @ Fail to resolve?
-    bne   MterpException                @ bail out
-.if 0
-    SET_VREG_OBJECT r0, r2              @ fp[AA]<- r0
-.else
-    SET_VREG r0, r2                     @ fp[AA]<- r0
-.endif
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSGetI8
+    cmp      r0, #0
+    beq      MterpPossibleException
     ADVANCE 2
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2797,32 +2697,23 @@
 .L_op_sget_char: /* 0x65 */
 /* File: arm/op_sget_char.S */
 /* File: arm/op_sget.S */
+/* File: arm/field.S */
     /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field@BBBB */
-
     .extern MterpSGetU16
-    EXPORT_PC
-    FETCH r0, 1                         @ r0<- field ref BBBB
-    ldr   r1, [rFP, #OFF_FP_METHOD]
-    mov   r2, rSELF
-    bl    MterpSGetU16
-    ldr   r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    mov   r2, rINST, lsr #8             @ r2<- AA
-    PREFETCH_INST 2
-    cmp   r3, #0                        @ Fail to resolve?
-    bne   MterpException                @ bail out
-.if 0
-    SET_VREG_OBJECT r0, r2              @ fp[AA]<- r0
-.else
-    SET_VREG r0, r2                     @ fp[AA]<- r0
-.endif
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSGetU16
+    cmp      r0, #0
+    beq      MterpPossibleException
     ADVANCE 2
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2830,122 +2721,117 @@
 .L_op_sget_short: /* 0x66 */
 /* File: arm/op_sget_short.S */
 /* File: arm/op_sget.S */
+/* File: arm/field.S */
     /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field@BBBB */
-
     .extern MterpSGetI16
-    EXPORT_PC
-    FETCH r0, 1                         @ r0<- field ref BBBB
-    ldr   r1, [rFP, #OFF_FP_METHOD]
-    mov   r2, rSELF
-    bl    MterpSGetI16
-    ldr   r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
-    mov   r2, rINST, lsr #8             @ r2<- AA
-    PREFETCH_INST 2
-    cmp   r3, #0                        @ Fail to resolve?
-    bne   MterpException                @ bail out
-.if 0
-    SET_VREG_OBJECT r0, r2              @ fp[AA]<- r0
-.else
-    SET_VREG r0, r2                     @ fp[AA]<- r0
-.endif
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSGetI16
+    cmp      r0, #0
+    beq      MterpPossibleException
     ADVANCE 2
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput: /* 0x67 */
 /* File: arm/op_sput.S */
+/* File: arm/field.S */
     /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field@BBBB */
-    EXPORT_PC
-    FETCH   r0, 1                       @ r0<- field ref BBBB
-    mov     r3, rINST, lsr #8           @ r3<- AA
-    GET_VREG r1, r3                     @ r1<= fp[AA]
-    ldr     r2, [rFP, #OFF_FP_METHOD]
-    mov     r3, rSELF
-    PREFETCH_INST 2                     @ Get next inst, but don't advance rPC
-    bl      MterpSPutU32
-    cmp     r0, #0                      @ 0 on success, -1 on failure
-    bne     MterpException
-    ADVANCE 2                           @ Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+    .extern MterpSPutU32
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSPutU32
+    cmp      r0, #0
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput_wide: /* 0x68 */
 /* File: arm/op_sput_wide.S */
+/* File: arm/op_sput.S */
+/* File: arm/field.S */
     /*
-     * SPUT_WIDE handler wrapper.
-     *
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* sput-wide vAA, field@BBBB */
     .extern MterpSPutU64
-    EXPORT_PC
-    FETCH   r0, 1                       @ r0<- field ref BBBB
-    mov     r1, rINST, lsr #8           @ r1<- AA
-    VREG_INDEX_TO_ADDR r1, r1
-    ldr     r2, [rFP, #OFF_FP_METHOD]
-    mov     r3, rSELF
-    PREFETCH_INST 2                     @ Get next inst, but don't advance rPC
-    bl      MterpSPutU64
-    cmp     r0, #0                      @ 0 on success, -1 on failure
-    bne     MterpException
-    ADVANCE 2                           @ Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSPutU64
+    cmp      r0, #0
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput_object: /* 0x69 */
 /* File: arm/op_sput_object.S */
-    EXPORT_PC
-    add     r0, rFP, #OFF_FP_SHADOWFRAME
-    mov     r1, rPC
-    mov     r2, rINST
-    mov     r3, rSELF
-    bl      MterpSPutObj
-    cmp     r0, #0
-    beq     MterpException
-    FETCH_ADVANCE_INST 2                @ advance rPC, load rINST
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+/* File: arm/op_sput.S */
+/* File: arm/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpSPutObj
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSPutObj
+    cmp      r0, #0
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput_boolean: /* 0x6a */
 /* File: arm/op_sput_boolean.S */
 /* File: arm/op_sput.S */
+/* File: arm/field.S */
     /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field@BBBB */
-    EXPORT_PC
-    FETCH   r0, 1                       @ r0<- field ref BBBB
-    mov     r3, rINST, lsr #8           @ r3<- AA
-    GET_VREG r1, r3                     @ r1<= fp[AA]
-    ldr     r2, [rFP, #OFF_FP_METHOD]
-    mov     r3, rSELF
-    PREFETCH_INST 2                     @ Get next inst, but don't advance rPC
-    bl      MterpSPutU8
-    cmp     r0, #0                      @ 0 on success, -1 on failure
-    bne     MterpException
-    ADVANCE 2                           @ Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+    .extern MterpSPutU8
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSPutU8
+    cmp      r0, #0
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2953,25 +2839,23 @@
 .L_op_sput_byte: /* 0x6b */
 /* File: arm/op_sput_byte.S */
 /* File: arm/op_sput.S */
+/* File: arm/field.S */
     /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field@BBBB */
-    EXPORT_PC
-    FETCH   r0, 1                       @ r0<- field ref BBBB
-    mov     r3, rINST, lsr #8           @ r3<- AA
-    GET_VREG r1, r3                     @ r1<= fp[AA]
-    ldr     r2, [rFP, #OFF_FP_METHOD]
-    mov     r3, rSELF
-    PREFETCH_INST 2                     @ Get next inst, but don't advance rPC
-    bl      MterpSPutI8
-    cmp     r0, #0                      @ 0 on success, -1 on failure
-    bne     MterpException
-    ADVANCE 2                           @ Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+    .extern MterpSPutI8
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSPutI8
+    cmp      r0, #0
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2979,25 +2863,23 @@
 .L_op_sput_char: /* 0x6c */
 /* File: arm/op_sput_char.S */
 /* File: arm/op_sput.S */
+/* File: arm/field.S */
     /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field@BBBB */
-    EXPORT_PC
-    FETCH   r0, 1                       @ r0<- field ref BBBB
-    mov     r3, rINST, lsr #8           @ r3<- AA
-    GET_VREG r1, r3                     @ r1<= fp[AA]
-    ldr     r2, [rFP, #OFF_FP_METHOD]
-    mov     r3, rSELF
-    PREFETCH_INST 2                     @ Get next inst, but don't advance rPC
-    bl      MterpSPutU16
-    cmp     r0, #0                      @ 0 on success, -1 on failure
-    bne     MterpException
-    ADVANCE 2                           @ Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+    .extern MterpSPutU16
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSPutU16
+    cmp      r0, #0
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -3005,25 +2887,23 @@
 .L_op_sput_short: /* 0x6d */
 /* File: arm/op_sput_short.S */
 /* File: arm/op_sput.S */
+/* File: arm/field.S */
     /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field@BBBB */
-    EXPORT_PC
-    FETCH   r0, 1                       @ r0<- field ref BBBB
-    mov     r3, rINST, lsr #8           @ r3<- AA
-    GET_VREG r1, r3                     @ r1<= fp[AA]
-    ldr     r2, [rFP, #OFF_FP_METHOD]
-    mov     r3, rSELF
-    PREFETCH_INST 2                     @ Get next inst, but don't advance rPC
-    bl      MterpSPutI16
-    cmp     r0, #0                      @ 0 on success, -1 on failure
-    bne     MterpException
-    ADVANCE 2                           @ Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  @ extract opcode from rINST
-    GOTO_OPCODE ip                      @ jump to next instruction
+    .extern MterpSPutI16
+    mov      r0, rPC                       @ arg0: Instruction* inst
+    mov      r1, rINST                     @ arg1: uint16_t inst_data
+    add      r2, rFP, #OFF_FP_SHADOWFRAME  @ arg2: ShadowFrame* sf
+    mov      r3, rSELF                     @ arg3: Thread* self
+    PREFETCH_INST 2                        @ prefetch next opcode
+    bl       MterpSPutI16
+    cmp      r0, #0
+    beq      MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     @ extract opcode from rINST
+    GOTO_OPCODE ip                         @ jump to next instruction
+
 
 
 /* ------------------------------ */
diff --git a/runtime/interpreter/mterp/out/mterp_arm64.S b/runtime/interpreter/mterp/out/mterp_arm64.S
index 5f4aa4f..fd60c95 100644
--- a/runtime/interpreter/mterp/out/mterp_arm64.S
+++ b/runtime/interpreter/mterp/out/mterp_arm64.S
@@ -2183,213 +2183,177 @@
     .balign 128
 .L_op_iget: /* 0x52 */
 /* File: arm64/op_iget.S */
+/* File: arm64/field.S */
     /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    w0, 1                         // w0<- field ref CCCC
-    lsr      w1, wINST, #12                // w1<- B
-    GET_VREG w1, w1                        // w1<- fp[B], the object pointer
-    ldr      x2, [xFP, #OFF_FP_METHOD]     // w2<- referrer
-    mov      x3, xSELF                     // w3<- self
+    .extern MterpIGetU32
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
     bl       MterpIGetU32
-    ldr      x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    
-    ubfx     w2, wINST, #8, #4             // w2<- A
-    PREFETCH_INST 2
-    cbnz     x3, MterpPossibleException    // bail out
-    .if 0
-    SET_VREG_OBJECT w0, w2                 // fp[A]<- w0
-    .else
-    SET_VREG w0, w2                        // fp[A]<- w0
-    .endif
+    cbz      x0, MterpPossibleException
     ADVANCE 2
     GET_INST_OPCODE ip                     // extract opcode from rINST
     GOTO_OPCODE ip                         // jump to next instruction
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_wide: /* 0x53 */
 /* File: arm64/op_iget_wide.S */
+/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
     /*
-     * 64-bit instance field get.
-     *
-     * for: iget-wide
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    w0, 1                         // w0<- field ref CCCC
-    lsr      w1, wINST, #12                // w1<- B
-    GET_VREG w1, w1                        // w1<- fp[B], the object pointer
-    ldr      x2, [xFP, #OFF_FP_METHOD]     // w2<- referrer
-    mov      x3, xSELF                     // w3<- self
+    .extern MterpIGetU64
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
     bl       MterpIGetU64
-    ldr      x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    ubfx     w2, wINST, #8, #4             // w2<- A
-    PREFETCH_INST 2
-    cmp      w3, #0
-    cbnz     w3, MterpException            // bail out
-    SET_VREG_WIDE x0, w2
+    cbz      x0, MterpPossibleException
     ADVANCE 2
-    GET_INST_OPCODE ip                     // extract opcode from wINST
+    GET_INST_OPCODE ip                     // extract opcode from rINST
     GOTO_OPCODE ip                         // jump to next instruction
 
+
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_object: /* 0x54 */
 /* File: arm64/op_iget_object.S */
 /* File: arm64/op_iget.S */
+/* File: arm64/field.S */
     /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    w0, 1                         // w0<- field ref CCCC
-    lsr      w1, wINST, #12                // w1<- B
-    GET_VREG w1, w1                        // w1<- fp[B], the object pointer
-    ldr      x2, [xFP, #OFF_FP_METHOD]     // w2<- referrer
-    mov      x3, xSELF                     // w3<- self
+    .extern MterpIGetObj
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
     bl       MterpIGetObj
-    ldr      x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    
-    ubfx     w2, wINST, #8, #4             // w2<- A
-    PREFETCH_INST 2
-    cbnz     x3, MterpPossibleException    // bail out
-    .if 1
-    SET_VREG_OBJECT w0, w2                 // fp[A]<- w0
-    .else
-    SET_VREG w0, w2                        // fp[A]<- w0
-    .endif
+    cbz      x0, MterpPossibleException
     ADVANCE 2
     GET_INST_OPCODE ip                     // extract opcode from rINST
     GOTO_OPCODE ip                         // jump to next instruction
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_boolean: /* 0x55 */
 /* File: arm64/op_iget_boolean.S */
 /* File: arm64/op_iget.S */
+/* File: arm64/field.S */
     /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    w0, 1                         // w0<- field ref CCCC
-    lsr      w1, wINST, #12                // w1<- B
-    GET_VREG w1, w1                        // w1<- fp[B], the object pointer
-    ldr      x2, [xFP, #OFF_FP_METHOD]     // w2<- referrer
-    mov      x3, xSELF                     // w3<- self
+    .extern MterpIGetU8
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
     bl       MterpIGetU8
-    ldr      x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    uxtb w0, w0
-    ubfx     w2, wINST, #8, #4             // w2<- A
-    PREFETCH_INST 2
-    cbnz     x3, MterpPossibleException    // bail out
-    .if 0
-    SET_VREG_OBJECT w0, w2                 // fp[A]<- w0
-    .else
-    SET_VREG w0, w2                        // fp[A]<- w0
-    .endif
+    cbz      x0, MterpPossibleException
     ADVANCE 2
     GET_INST_OPCODE ip                     // extract opcode from rINST
     GOTO_OPCODE ip                         // jump to next instruction
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_byte: /* 0x56 */
 /* File: arm64/op_iget_byte.S */
 /* File: arm64/op_iget.S */
+/* File: arm64/field.S */
     /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    w0, 1                         // w0<- field ref CCCC
-    lsr      w1, wINST, #12                // w1<- B
-    GET_VREG w1, w1                        // w1<- fp[B], the object pointer
-    ldr      x2, [xFP, #OFF_FP_METHOD]     // w2<- referrer
-    mov      x3, xSELF                     // w3<- self
+    .extern MterpIGetI8
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
     bl       MterpIGetI8
-    ldr      x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    sxtb w0, w0
-    ubfx     w2, wINST, #8, #4             // w2<- A
-    PREFETCH_INST 2
-    cbnz     x3, MterpPossibleException    // bail out
-    .if 0
-    SET_VREG_OBJECT w0, w2                 // fp[A]<- w0
-    .else
-    SET_VREG w0, w2                        // fp[A]<- w0
-    .endif
+    cbz      x0, MterpPossibleException
     ADVANCE 2
     GET_INST_OPCODE ip                     // extract opcode from rINST
     GOTO_OPCODE ip                         // jump to next instruction
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_char: /* 0x57 */
 /* File: arm64/op_iget_char.S */
 /* File: arm64/op_iget.S */
+/* File: arm64/field.S */
     /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    w0, 1                         // w0<- field ref CCCC
-    lsr      w1, wINST, #12                // w1<- B
-    GET_VREG w1, w1                        // w1<- fp[B], the object pointer
-    ldr      x2, [xFP, #OFF_FP_METHOD]     // w2<- referrer
-    mov      x3, xSELF                     // w3<- self
+    .extern MterpIGetU16
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
     bl       MterpIGetU16
-    ldr      x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    uxth w0, w0
-    ubfx     w2, wINST, #8, #4             // w2<- A
-    PREFETCH_INST 2
-    cbnz     x3, MterpPossibleException    // bail out
-    .if 0
-    SET_VREG_OBJECT w0, w2                 // fp[A]<- w0
-    .else
-    SET_VREG w0, w2                        // fp[A]<- w0
-    .endif
+    cbz      x0, MterpPossibleException
     ADVANCE 2
     GET_INST_OPCODE ip                     // extract opcode from rINST
     GOTO_OPCODE ip                         // jump to next instruction
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_short: /* 0x58 */
 /* File: arm64/op_iget_short.S */
 /* File: arm64/op_iget.S */
+/* File: arm64/field.S */
     /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    EXPORT_PC
-    FETCH    w0, 1                         // w0<- field ref CCCC
-    lsr      w1, wINST, #12                // w1<- B
-    GET_VREG w1, w1                        // w1<- fp[B], the object pointer
-    ldr      x2, [xFP, #OFF_FP_METHOD]     // w2<- referrer
-    mov      x3, xSELF                     // w3<- self
+    .extern MterpIGetI16
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
     bl       MterpIGetI16
-    ldr      x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    sxth w0, w0
-    ubfx     w2, wINST, #8, #4             // w2<- A
-    PREFETCH_INST 2
-    cbnz     x3, MterpPossibleException    // bail out
-    .if 0
-    SET_VREG_OBJECT w0, w2                 // fp[A]<- w0
-    .else
-    SET_VREG w0, w2                        // fp[A]<- w0
-    .endif
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
+
+
+/* ------------------------------ */
+    .balign 128
+.L_op_iput: /* 0x59 */
+/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIPutU32
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpIPutU32
+    cbz      x0, MterpPossibleException
     ADVANCE 2
     GET_INST_OPCODE ip                     // extract opcode from rINST
     GOTO_OPCODE ip                         // jump to next instruction
@@ -2397,89 +2361,71 @@
 
 /* ------------------------------ */
     .balign 128
-.L_op_iput: /* 0x59 */
-/* File: arm64/op_iput.S */
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field//CCCC */
-    .extern MterpIPutU32
-    EXPORT_PC
-    FETCH    w0, 1                      // w0<- field ref CCCC
-    lsr      w1, wINST, #12             // w1<- B
-    GET_VREG w1, w1                     // w1<- fp[B], the object pointer
-    ubfx     w2, wINST, #8, #4          // w2<- A
-    GET_VREG w2, w2                     // w2<- fp[A]
-    ldr      x3, [xFP, #OFF_FP_METHOD]  // w3<- referrer
-    PREFETCH_INST 2
-    bl       MterpIPutU32
-    cbnz     w0, MterpPossibleException
-    ADVANCE  2                          // advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
-
-/* ------------------------------ */
-    .balign 128
 .L_op_iput_wide: /* 0x5a */
 /* File: arm64/op_iput_wide.S */
-    /* iput-wide vA, vB, field//CCCC */
+/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutU64
-    EXPORT_PC
-    FETCH    w0, 1                      // w0<- field ref CCCC
-    lsr      w1, wINST, #12             // w1<- B
-    GET_VREG w1, w1                     // w1<- fp[B], the object pointer
-    ubfx     w2, wINST, #8, #4          // w2<- A
-    VREG_INDEX_TO_ADDR x2, x2           // w2<- &fp[A]
-    ldr      x3, [xFP, #OFF_FP_METHOD]  // w3<- referrer
-    PREFETCH_INST 2
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
     bl       MterpIPutU64
-    cbnz     w0, MterpPossibleException
-    ADVANCE  2                          // advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from wINST
-    GOTO_OPCODE ip                      // jump to next instruction
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iput_object: /* 0x5b */
 /* File: arm64/op_iput_object.S */
-    EXPORT_PC
-    add     x0, xFP, #OFF_FP_SHADOWFRAME
-    mov     x1, xPC
-    mov     w2, wINST
-    mov     x3, xSELF
-    bl      MterpIPutObj
-    cbz     w0, MterpException
-    FETCH_ADVANCE_INST 2                // advance rPC, load rINST
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIPutObj
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpIPutObj
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iput_boolean: /* 0x5c */
 /* File: arm64/op_iput_boolean.S */
 /* File: arm64/op_iput.S */
+/* File: arm64/field.S */
     /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vA, vB, field//CCCC */
     .extern MterpIPutU8
-    EXPORT_PC
-    FETCH    w0, 1                      // w0<- field ref CCCC
-    lsr      w1, wINST, #12             // w1<- B
-    GET_VREG w1, w1                     // w1<- fp[B], the object pointer
-    ubfx     w2, wINST, #8, #4          // w2<- A
-    GET_VREG w2, w2                     // w2<- fp[A]
-    ldr      x3, [xFP, #OFF_FP_METHOD]  // w3<- referrer
-    PREFETCH_INST 2
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
     bl       MterpIPutU8
-    cbnz     w0, MterpPossibleException
-    ADVANCE  2                          // advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2487,26 +2433,22 @@
 .L_op_iput_byte: /* 0x5d */
 /* File: arm64/op_iput_byte.S */
 /* File: arm64/op_iput.S */
+/* File: arm64/field.S */
     /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vA, vB, field//CCCC */
     .extern MterpIPutI8
-    EXPORT_PC
-    FETCH    w0, 1                      // w0<- field ref CCCC
-    lsr      w1, wINST, #12             // w1<- B
-    GET_VREG w1, w1                     // w1<- fp[B], the object pointer
-    ubfx     w2, wINST, #8, #4          // w2<- A
-    GET_VREG w2, w2                     // w2<- fp[A]
-    ldr      x3, [xFP, #OFF_FP_METHOD]  // w3<- referrer
-    PREFETCH_INST 2
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
     bl       MterpIPutI8
-    cbnz     w0, MterpPossibleException
-    ADVANCE  2                          // advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2514,26 +2456,22 @@
 .L_op_iput_char: /* 0x5e */
 /* File: arm64/op_iput_char.S */
 /* File: arm64/op_iput.S */
+/* File: arm64/field.S */
     /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vA, vB, field//CCCC */
     .extern MterpIPutU16
-    EXPORT_PC
-    FETCH    w0, 1                      // w0<- field ref CCCC
-    lsr      w1, wINST, #12             // w1<- B
-    GET_VREG w1, w1                     // w1<- fp[B], the object pointer
-    ubfx     w2, wINST, #8, #4          // w2<- A
-    GET_VREG w2, w2                     // w2<- fp[A]
-    ldr      x3, [xFP, #OFF_FP_METHOD]  // w3<- referrer
-    PREFETCH_INST 2
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
     bl       MterpIPutU16
-    cbnz     w0, MterpPossibleException
-    ADVANCE  2                          // advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2541,114 +2479,89 @@
 .L_op_iput_short: /* 0x5f */
 /* File: arm64/op_iput_short.S */
 /* File: arm64/op_iput.S */
+/* File: arm64/field.S */
     /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vA, vB, field//CCCC */
     .extern MterpIPutI16
-    EXPORT_PC
-    FETCH    w0, 1                      // w0<- field ref CCCC
-    lsr      w1, wINST, #12             // w1<- B
-    GET_VREG w1, w1                     // w1<- fp[B], the object pointer
-    ubfx     w2, wINST, #8, #4          // w2<- A
-    GET_VREG w2, w2                     // w2<- fp[A]
-    ldr      x3, [xFP, #OFF_FP_METHOD]  // w3<- referrer
-    PREFETCH_INST 2
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
     bl       MterpIPutI16
-    cbnz     w0, MterpPossibleException
-    ADVANCE  2                          // advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 
 /* ------------------------------ */
     .balign 128
 .L_op_sget: /* 0x60 */
 /* File: arm64/op_sget.S */
+/* File: arm64/field.S */
     /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field//BBBB */
-
     .extern MterpSGetU32
-    EXPORT_PC
-    FETCH w0, 1                         // w0<- field ref BBBB
-    ldr   x1, [xFP, #OFF_FP_METHOD]
-    mov   x2, xSELF
-    bl    MterpSGetU32
-    ldr   x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    lsr   w2, wINST, #8                 // w2<- AA
-    
-    PREFETCH_INST 2
-    cbnz  x3, MterpException            // bail out
-.if 0
-    SET_VREG_OBJECT w0, w2              // fp[AA]<- w0
-.else
-    SET_VREG w0, w2                     // fp[AA]<- w0
-.endif
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSGetU32
+    cbz      x0, MterpPossibleException
     ADVANCE 2
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sget_wide: /* 0x61 */
 /* File: arm64/op_sget_wide.S */
+/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
     /*
-     * SGET_WIDE handler wrapper.
-     *
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* sget-wide vAA, field//BBBB */
+    .extern MterpSGetU64
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSGetU64
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
 
-    .extern MterpGet64StaticFromCode
-    EXPORT_PC
-    FETCH w0, 1                         // w0<- field ref BBBB
-    ldr   x1, [xFP, #OFF_FP_METHOD]
-    mov   x2, xSELF
-    bl    MterpSGetU64
-    ldr   x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    lsr   w4, wINST, #8                 // w4<- AA
-    cbnz  x3, MterpException            // bail out
-    FETCH_ADVANCE_INST 2                // advance rPC, load wINST
-    SET_VREG_WIDE x0, w4
-    GET_INST_OPCODE ip                  // extract opcode from wINST
-    GOTO_OPCODE ip                      // jump to next instruction
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sget_object: /* 0x62 */
 /* File: arm64/op_sget_object.S */
 /* File: arm64/op_sget.S */
+/* File: arm64/field.S */
     /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field//BBBB */
-
     .extern MterpSGetObj
-    EXPORT_PC
-    FETCH w0, 1                         // w0<- field ref BBBB
-    ldr   x1, [xFP, #OFF_FP_METHOD]
-    mov   x2, xSELF
-    bl    MterpSGetObj
-    ldr   x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    lsr   w2, wINST, #8                 // w2<- AA
-    
-    PREFETCH_INST 2
-    cbnz  x3, MterpException            // bail out
-.if 1
-    SET_VREG_OBJECT w0, w2              // fp[AA]<- w0
-.else
-    SET_VREG w0, w2                     // fp[AA]<- w0
-.endif
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSGetObj
+    cbz      x0, MterpPossibleException
     ADVANCE 2
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2656,32 +2569,22 @@
 .L_op_sget_boolean: /* 0x63 */
 /* File: arm64/op_sget_boolean.S */
 /* File: arm64/op_sget.S */
+/* File: arm64/field.S */
     /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field//BBBB */
-
     .extern MterpSGetU8
-    EXPORT_PC
-    FETCH w0, 1                         // w0<- field ref BBBB
-    ldr   x1, [xFP, #OFF_FP_METHOD]
-    mov   x2, xSELF
-    bl    MterpSGetU8
-    ldr   x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    lsr   w2, wINST, #8                 // w2<- AA
-    uxtb w0, w0
-    PREFETCH_INST 2
-    cbnz  x3, MterpException            // bail out
-.if 0
-    SET_VREG_OBJECT w0, w2              // fp[AA]<- w0
-.else
-    SET_VREG w0, w2                     // fp[AA]<- w0
-.endif
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSGetU8
+    cbz      x0, MterpPossibleException
     ADVANCE 2
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2689,32 +2592,22 @@
 .L_op_sget_byte: /* 0x64 */
 /* File: arm64/op_sget_byte.S */
 /* File: arm64/op_sget.S */
+/* File: arm64/field.S */
     /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field//BBBB */
-
     .extern MterpSGetI8
-    EXPORT_PC
-    FETCH w0, 1                         // w0<- field ref BBBB
-    ldr   x1, [xFP, #OFF_FP_METHOD]
-    mov   x2, xSELF
-    bl    MterpSGetI8
-    ldr   x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    lsr   w2, wINST, #8                 // w2<- AA
-    sxtb w0, w0
-    PREFETCH_INST 2
-    cbnz  x3, MterpException            // bail out
-.if 0
-    SET_VREG_OBJECT w0, w2              // fp[AA]<- w0
-.else
-    SET_VREG w0, w2                     // fp[AA]<- w0
-.endif
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSGetI8
+    cbz      x0, MterpPossibleException
     ADVANCE 2
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2722,32 +2615,22 @@
 .L_op_sget_char: /* 0x65 */
 /* File: arm64/op_sget_char.S */
 /* File: arm64/op_sget.S */
+/* File: arm64/field.S */
     /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field//BBBB */
-
     .extern MterpSGetU16
-    EXPORT_PC
-    FETCH w0, 1                         // w0<- field ref BBBB
-    ldr   x1, [xFP, #OFF_FP_METHOD]
-    mov   x2, xSELF
-    bl    MterpSGetU16
-    ldr   x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    lsr   w2, wINST, #8                 // w2<- AA
-    uxth w0, w0
-    PREFETCH_INST 2
-    cbnz  x3, MterpException            // bail out
-.if 0
-    SET_VREG_OBJECT w0, w2              // fp[AA]<- w0
-.else
-    SET_VREG w0, w2                     // fp[AA]<- w0
-.endif
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSGetU16
+    cbz      x0, MterpPossibleException
     ADVANCE 2
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2755,118 +2638,112 @@
 .L_op_sget_short: /* 0x66 */
 /* File: arm64/op_sget_short.S */
 /* File: arm64/op_sget.S */
+/* File: arm64/field.S */
     /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field//BBBB */
-
     .extern MterpSGetI16
-    EXPORT_PC
-    FETCH w0, 1                         // w0<- field ref BBBB
-    ldr   x1, [xFP, #OFF_FP_METHOD]
-    mov   x2, xSELF
-    bl    MterpSGetI16
-    ldr   x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-    lsr   w2, wINST, #8                 // w2<- AA
-    sxth w0, w0
-    PREFETCH_INST 2
-    cbnz  x3, MterpException            // bail out
-.if 0
-    SET_VREG_OBJECT w0, w2              // fp[AA]<- w0
-.else
-    SET_VREG w0, w2                     // fp[AA]<- w0
-.endif
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSGetI16
+    cbz      x0, MterpPossibleException
     ADVANCE 2
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput: /* 0x67 */
 /* File: arm64/op_sput.S */
+/* File: arm64/field.S */
     /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field//BBBB */
-    EXPORT_PC
-    FETCH   w0, 1                       // r0<- field ref BBBB
-    lsr     w3, wINST, #8               // r3<- AA
-    GET_VREG w1, w3                     // r1<= fp[AA]
-    ldr     x2, [xFP, #OFF_FP_METHOD]
-    mov     x3, xSELF
-    PREFETCH_INST 2                     // Get next inst, but don't advance rPC
-    bl      MterpSPutU32
-    cbnz    w0, MterpException          // 0 on success
-    ADVANCE 2                           // Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+    .extern MterpSPutU32
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSPutU32
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput_wide: /* 0x68 */
 /* File: arm64/op_sput_wide.S */
+/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
     /*
-     * SPUT_WIDE handler wrapper.
-     *
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* sput-wide vAA, field//BBBB */
     .extern MterpSPutU64
-    EXPORT_PC
-    FETCH   w0, 1                       // w0<- field ref BBBB
-    lsr     w1, wINST, #8               // w1<- AA
-    VREG_INDEX_TO_ADDR x1, w1
-    ldr     x2, [xFP, #OFF_FP_METHOD]
-    mov     x3, xSELF
-    PREFETCH_INST 2                     // Get next inst, but don't advance rPC
-    bl      MterpSPutU64
-    cbnz    w0, MterpException          // 0 on success, -1 on failure
-    ADVANCE 2                           // Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from wINST
-    GOTO_OPCODE ip                      // jump to next instruction
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSPutU64
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput_object: /* 0x69 */
 /* File: arm64/op_sput_object.S */
-    EXPORT_PC
-    add     x0, xFP, #OFF_FP_SHADOWFRAME
-    mov     x1, xPC
-    mov     x2, xINST
-    mov     x3, xSELF
-    bl      MterpSPutObj
-    cbz     w0, MterpException
-    FETCH_ADVANCE_INST 2                // advance rPC, load rINST
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpSPutObj
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSPutObj
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput_boolean: /* 0x6a */
 /* File: arm64/op_sput_boolean.S */
 /* File: arm64/op_sput.S */
+/* File: arm64/field.S */
     /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field//BBBB */
-    EXPORT_PC
-    FETCH   w0, 1                       // r0<- field ref BBBB
-    lsr     w3, wINST, #8               // r3<- AA
-    GET_VREG w1, w3                     // r1<= fp[AA]
-    ldr     x2, [xFP, #OFF_FP_METHOD]
-    mov     x3, xSELF
-    PREFETCH_INST 2                     // Get next inst, but don't advance rPC
-    bl      MterpSPutU8
-    cbnz    w0, MterpException          // 0 on success
-    ADVANCE 2                           // Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+    .extern MterpSPutU8
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSPutU8
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2874,24 +2751,22 @@
 .L_op_sput_byte: /* 0x6b */
 /* File: arm64/op_sput_byte.S */
 /* File: arm64/op_sput.S */
+/* File: arm64/field.S */
     /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field//BBBB */
-    EXPORT_PC
-    FETCH   w0, 1                       // r0<- field ref BBBB
-    lsr     w3, wINST, #8               // r3<- AA
-    GET_VREG w1, w3                     // r1<= fp[AA]
-    ldr     x2, [xFP, #OFF_FP_METHOD]
-    mov     x3, xSELF
-    PREFETCH_INST 2                     // Get next inst, but don't advance rPC
-    bl      MterpSPutI8
-    cbnz    w0, MterpException          // 0 on success
-    ADVANCE 2                           // Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+    .extern MterpSPutI8
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSPutI8
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2899,24 +2774,22 @@
 .L_op_sput_char: /* 0x6c */
 /* File: arm64/op_sput_char.S */
 /* File: arm64/op_sput.S */
+/* File: arm64/field.S */
     /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field//BBBB */
-    EXPORT_PC
-    FETCH   w0, 1                       // r0<- field ref BBBB
-    lsr     w3, wINST, #8               // r3<- AA
-    GET_VREG w1, w3                     // r1<= fp[AA]
-    ldr     x2, [xFP, #OFF_FP_METHOD]
-    mov     x3, xSELF
-    PREFETCH_INST 2                     // Get next inst, but don't advance rPC
-    bl      MterpSPutU16
-    cbnz    w0, MterpException          // 0 on success
-    ADVANCE 2                           // Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+    .extern MterpSPutU16
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSPutU16
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 
 /* ------------------------------ */
@@ -2924,24 +2797,22 @@
 .L_op_sput_short: /* 0x6d */
 /* File: arm64/op_sput_short.S */
 /* File: arm64/op_sput.S */
+/* File: arm64/field.S */
     /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+     * General field read / write (iget-* iput-* sget-* sput-*).
      */
-    /* op vAA, field//BBBB */
-    EXPORT_PC
-    FETCH   w0, 1                       // r0<- field ref BBBB
-    lsr     w3, wINST, #8               // r3<- AA
-    GET_VREG w1, w3                     // r1<= fp[AA]
-    ldr     x2, [xFP, #OFF_FP_METHOD]
-    mov     x3, xSELF
-    PREFETCH_INST 2                     // Get next inst, but don't advance rPC
-    bl      MterpSPutI16
-    cbnz    w0, MterpException          // 0 on success
-    ADVANCE 2                           // Past exception point - now advance rPC
-    GET_INST_OPCODE ip                  // extract opcode from rINST
-    GOTO_OPCODE ip                      // jump to next instruction
+    .extern MterpSPutI16
+    mov      x0, xPC                       // arg0: Instruction* inst
+    mov      x1, xINST                     // arg1: uint16_t inst_data
+    add      x2, xFP, #OFF_FP_SHADOWFRAME  // arg2: ShadowFrame* sf
+    mov      x3, xSELF                     // arg3: Thread* self
+    PREFETCH_INST 2                        // prefetch next opcode
+    bl       MterpSPutI16
+    cbz      x0, MterpPossibleException
+    ADVANCE 2
+    GET_INST_OPCODE ip                     // extract opcode from rINST
+    GOTO_OPCODE ip                         // jump to next instruction
+
 
 
 /* ------------------------------ */
diff --git a/runtime/interpreter/mterp/out/mterp_mips.S b/runtime/interpreter/mterp/out/mterp_mips.S
index fb7d52e..1f5bea0 100644
--- a/runtime/interpreter/mterp/out/mterp_mips.S
+++ b/runtime/interpreter/mterp/out/mterp_mips.S
@@ -2665,85 +2665,28 @@
     .balign 128
 .L_op_iget: /* 0x52 */
 /* File: mips/op_iget.S */
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    /* op vA, vB, field@CCCC */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- referrer
-    move  a3, rSELF                        # a3 <- self
-    JAL(MterpIGetU32)
-    lw   a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA4(a2)                           # a2<- A+
-    PREFETCH_INST(2)                       # load rINST
-    bnez  a3, MterpPossibleException        # bail out
-    ADVANCE(2)                             #  advance rPC
-    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
-    .if 0
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[A] <- v0
-    .else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[A] <- v0
-    .endif
+/* File: mips/field.S */
+TODO
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iget_wide: /* 0x53 */
 /* File: mips/op_iget_wide.S */
-    /*
-     * 64-bit instance field get.
-     *
-     * for: iget-wide
-     */
-    /* op vA, vB, field@CCCC */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field byte offset
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- referrer
-    move  a3, rSELF                        # a3 <- self
-    JAL(MterpIGetU64)
-    lw   a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA4(a2)                           # a2<- A+
-    PREFETCH_INST(2)                       # load rINST
-    bnez a3, MterpException                # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    SET_VREG64_GOTO(v0, v1, a2, t0)        # fp[A] <- v0/v1
+/* File: mips/op_iget.S */
+/* File: mips/field.S */
+TODO
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iget_object: /* 0x54 */
 /* File: mips/op_iget_object.S */
 /* File: mips/op_iget.S */
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    /* op vA, vB, field@CCCC */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- referrer
-    move  a3, rSELF                        # a3 <- self
-    JAL(MterpIGetObj)
-    lw   a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA4(a2)                           # a2<- A+
-    PREFETCH_INST(2)                       # load rINST
-    bnez  a3, MterpPossibleException        # bail out
-    ADVANCE(2)                             #  advance rPC
-    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
-    .if 1
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[A] <- v0
-    .else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[A] <- v0
-    .endif
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2751,30 +2694,9 @@
 .L_op_iget_boolean: /* 0x55 */
 /* File: mips/op_iget_boolean.S */
 /* File: mips/op_iget.S */
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    /* op vA, vB, field@CCCC */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- referrer
-    move  a3, rSELF                        # a3 <- self
-    JAL(MterpIGetU8)
-    lw   a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA4(a2)                           # a2<- A+
-    PREFETCH_INST(2)                       # load rINST
-    bnez  a3, MterpPossibleException        # bail out
-    ADVANCE(2)                             #  advance rPC
-    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
-    .if 0
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[A] <- v0
-    .else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[A] <- v0
-    .endif
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2782,30 +2704,9 @@
 .L_op_iget_byte: /* 0x56 */
 /* File: mips/op_iget_byte.S */
 /* File: mips/op_iget.S */
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    /* op vA, vB, field@CCCC */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- referrer
-    move  a3, rSELF                        # a3 <- self
-    JAL(MterpIGetI8)
-    lw   a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA4(a2)                           # a2<- A+
-    PREFETCH_INST(2)                       # load rINST
-    bnez  a3, MterpPossibleException        # bail out
-    ADVANCE(2)                             #  advance rPC
-    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
-    .if 0
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[A] <- v0
-    .else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[A] <- v0
-    .endif
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2813,30 +2714,9 @@
 .L_op_iget_char: /* 0x57 */
 /* File: mips/op_iget_char.S */
 /* File: mips/op_iget.S */
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    /* op vA, vB, field@CCCC */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- referrer
-    move  a3, rSELF                        # a3 <- self
-    JAL(MterpIGetU16)
-    lw   a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA4(a2)                           # a2<- A+
-    PREFETCH_INST(2)                       # load rINST
-    bnez  a3, MterpPossibleException        # bail out
-    ADVANCE(2)                             #  advance rPC
-    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
-    .if 0
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[A] <- v0
-    .else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[A] <- v0
-    .endif
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2844,123 +2724,47 @@
 .L_op_iget_short: /* 0x58 */
 /* File: mips/op_iget_short.S */
 /* File: mips/op_iget.S */
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    /* op vA, vB, field@CCCC */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- referrer
-    move  a3, rSELF                        # a3 <- self
-    JAL(MterpIGetI16)
-    lw   a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA4(a2)                           # a2<- A+
-    PREFETCH_INST(2)                       # load rINST
-    bnez  a3, MterpPossibleException        # bail out
-    ADVANCE(2)                             #  advance rPC
-    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
-    .if 0
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[A] <- v0
-    .else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[A] <- v0
-    .endif
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
     .balign 128
 .L_op_iput: /* 0x59 */
 /* File: mips/op_iput.S */
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field@CCCC */
-    .extern MterpIPutU32
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    GET_OPA4(a2)                           # a2 <- A+
-    GET_VREG(a2, a2)                       # a2 <- fp[A]
-    lw    a3, OFF_FP_METHOD(rFP)           # a3 <- referrer
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpIPutU32)
-    bnez  v0, MterpPossibleException       # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+/* File: mips/field.S */
+TODO
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iput_wide: /* 0x5a */
 /* File: mips/op_iput_wide.S */
-    /* iput-wide vA, vB, field@CCCC */
-    .extern MterpIPutU64
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    GET_OPA4(a2)                           # a2 <- A+
-    EAS2(a2, rFP, a2)                      # a2 <- &fp[A]
-    lw    a3, OFF_FP_METHOD(rFP)           # a3 <- referrer
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpIPutU64)
-    bnez  v0, MterpPossibleException       # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+/* File: mips/op_iput.S */
+/* File: mips/field.S */
+TODO
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iput_object: /* 0x5b */
 /* File: mips/op_iput_object.S */
-    /*
-     * 32-bit instance field put.
-     *
-     * for: iput-object, iput-object-volatile
-     */
-    /* op vA, vB, field@CCCC */
-    EXPORT_PC()
-    addu   a0, rFP, OFF_FP_SHADOWFRAME
-    move   a1, rPC
-    move   a2, rINST
-    move   a3, rSELF
-    JAL(MterpIPutObj)
-    beqz   v0, MterpException
-    FETCH_ADVANCE_INST(2)               # advance rPC, load rINST
-    GET_INST_OPCODE(t0)                 # extract opcode from rINST
-    GOTO_OPCODE(t0)                     # jump to next instruction
+/* File: mips/op_iput.S */
+/* File: mips/field.S */
+TODO
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iput_boolean: /* 0x5c */
 /* File: mips/op_iput_boolean.S */
 /* File: mips/op_iput.S */
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field@CCCC */
-    .extern MterpIPutU8
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    GET_OPA4(a2)                           # a2 <- A+
-    GET_VREG(a2, a2)                       # a2 <- fp[A]
-    lw    a3, OFF_FP_METHOD(rFP)           # a3 <- referrer
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpIPutU8)
-    bnez  v0, MterpPossibleException       # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2968,26 +2772,9 @@
 .L_op_iput_byte: /* 0x5d */
 /* File: mips/op_iput_byte.S */
 /* File: mips/op_iput.S */
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field@CCCC */
-    .extern MterpIPutI8
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    GET_OPA4(a2)                           # a2 <- A+
-    GET_VREG(a2, a2)                       # a2 <- fp[A]
-    lw    a3, OFF_FP_METHOD(rFP)           # a3 <- referrer
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpIPutI8)
-    bnez  v0, MterpPossibleException       # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2995,26 +2782,9 @@
 .L_op_iput_char: /* 0x5e */
 /* File: mips/op_iput_char.S */
 /* File: mips/op_iput.S */
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field@CCCC */
-    .extern MterpIPutU16
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    GET_OPA4(a2)                           # a2 <- A+
-    GET_VREG(a2, a2)                       # a2 <- fp[A]
-    lw    a3, OFF_FP_METHOD(rFP)           # a3 <- referrer
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpIPutU16)
-    bnez  v0, MterpPossibleException       # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -3022,105 +2792,37 @@
 .L_op_iput_short: /* 0x5f */
 /* File: mips/op_iput_short.S */
 /* File: mips/op_iput.S */
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field@CCCC */
-    .extern MterpIPutI16
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPB(a1)                            # a1 <- B
-    GET_VREG(a1, a1)                       # a1 <- fp[B], the object pointer
-    GET_OPA4(a2)                           # a2 <- A+
-    GET_VREG(a2, a2)                       # a2 <- fp[A]
-    lw    a3, OFF_FP_METHOD(rFP)           # a3 <- referrer
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpIPutI16)
-    bnez  v0, MterpPossibleException       # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
     .balign 128
 .L_op_sget: /* 0x60 */
 /* File: mips/op_sget.S */
-    /*
-     * General SGET handler.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field@BBBB */
-    .extern MterpSGetU32
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    lw    a1, OFF_FP_METHOD(rFP)           # a1 <- method
-    move  a2, rSELF                        # a2 <- self
-    JAL(MterpSGetU32)
-    lw    a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA(a2)                            # a2 <- AA
-    PREFETCH_INST(2)
-    bnez  a3, MterpException               # bail out
-    ADVANCE(2)
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-.if 0
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[AA] <- v0
-.else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sget_wide: /* 0x61 */
 /* File: mips/op_sget_wide.S */
-    /*
-     * 64-bit SGET handler.
-     */
-    /* sget-wide vAA, field@BBBB */
-    .extern MterpSGetU64
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    lw    a1, OFF_FP_METHOD(rFP)           # a1 <- method
-    move  a2, rSELF                        # a2 <- self
-    JAL(MterpSGetU64)
-    lw    a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    bnez  a3, MterpException
-    GET_OPA(a1)                            # a1 <- AA
-    FETCH_ADVANCE_INST(2)                  # advance rPC, load rINST
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    SET_VREG64_GOTO(v0, v1, a1, t0)        # vAA/vAA+1 <- v0/v1
+/* File: mips/op_sget.S */
+/* File: mips/field.S */
+TODO
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sget_object: /* 0x62 */
 /* File: mips/op_sget_object.S */
 /* File: mips/op_sget.S */
-    /*
-     * General SGET handler.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field@BBBB */
-    .extern MterpSGetObj
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    lw    a1, OFF_FP_METHOD(rFP)           # a1 <- method
-    move  a2, rSELF                        # a2 <- self
-    JAL(MterpSGetObj)
-    lw    a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA(a2)                            # a2 <- AA
-    PREFETCH_INST(2)
-    bnez  a3, MterpException               # bail out
-    ADVANCE(2)
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-.if 1
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[AA] <- v0
-.else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -3128,29 +2830,9 @@
 .L_op_sget_boolean: /* 0x63 */
 /* File: mips/op_sget_boolean.S */
 /* File: mips/op_sget.S */
-    /*
-     * General SGET handler.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field@BBBB */
-    .extern MterpSGetU8
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    lw    a1, OFF_FP_METHOD(rFP)           # a1 <- method
-    move  a2, rSELF                        # a2 <- self
-    JAL(MterpSGetU8)
-    lw    a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA(a2)                            # a2 <- AA
-    PREFETCH_INST(2)
-    bnez  a3, MterpException               # bail out
-    ADVANCE(2)
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-.if 0
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[AA] <- v0
-.else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -3158,29 +2840,9 @@
 .L_op_sget_byte: /* 0x64 */
 /* File: mips/op_sget_byte.S */
 /* File: mips/op_sget.S */
-    /*
-     * General SGET handler.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field@BBBB */
-    .extern MterpSGetI8
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    lw    a1, OFF_FP_METHOD(rFP)           # a1 <- method
-    move  a2, rSELF                        # a2 <- self
-    JAL(MterpSGetI8)
-    lw    a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA(a2)                            # a2 <- AA
-    PREFETCH_INST(2)
-    bnez  a3, MterpException               # bail out
-    ADVANCE(2)
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-.if 0
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[AA] <- v0
-.else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -3188,29 +2850,9 @@
 .L_op_sget_char: /* 0x65 */
 /* File: mips/op_sget_char.S */
 /* File: mips/op_sget.S */
-    /*
-     * General SGET handler.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field@BBBB */
-    .extern MterpSGetU16
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    lw    a1, OFF_FP_METHOD(rFP)           # a1 <- method
-    move  a2, rSELF                        # a2 <- self
-    JAL(MterpSGetU16)
-    lw    a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA(a2)                            # a2 <- AA
-    PREFETCH_INST(2)
-    bnez  a3, MterpException               # bail out
-    ADVANCE(2)
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-.if 0
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[AA] <- v0
-.else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -3218,120 +2860,47 @@
 .L_op_sget_short: /* 0x66 */
 /* File: mips/op_sget_short.S */
 /* File: mips/op_sget.S */
-    /*
-     * General SGET handler.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field@BBBB */
-    .extern MterpSGetI16
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    lw    a1, OFF_FP_METHOD(rFP)           # a1 <- method
-    move  a2, rSELF                        # a2 <- self
-    JAL(MterpSGetI16)
-    lw    a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    GET_OPA(a2)                            # a2 <- AA
-    PREFETCH_INST(2)
-    bnez  a3, MterpException               # bail out
-    ADVANCE(2)
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-.if 0
-    SET_VREG_OBJECT_GOTO(v0, a2, t0)       # fp[AA] <- v0
-.else
-    SET_VREG_GOTO(v0, a2, t0)              # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput: /* 0x67 */
 /* File: mips/op_sput.S */
-    /*
-     * General SPUT handler.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field@BBBB */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    GET_OPA(a3)                            # a3 <- AA
-    GET_VREG(a1, a3)                       # a1 <- fp[AA], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- method
-    move  a3, rSELF                        # a3 <- self
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpSPutU32)
-    bnez  v0, MterpException               # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+/* File: mips/field.S */
+TODO
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput_wide: /* 0x68 */
 /* File: mips/op_sput_wide.S */
-    /*
-     * 64-bit SPUT handler.
-     */
-    /* sput-wide vAA, field@BBBB */
-    .extern MterpSPutU64
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref CCCC
-    GET_OPA(a1)                            # a1 <- AA
-    EAS2(a1, rFP, a1)                      # a1 <- &fp[AA]
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- method
-    move  a3, rSELF                        # a3 <- self
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpSPutU64)
-    bnez  v0, MterpException               # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+/* File: mips/op_sput.S */
+/* File: mips/field.S */
+TODO
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput_object: /* 0x69 */
 /* File: mips/op_sput_object.S */
-    /*
-     * General 32-bit SPUT handler.
-     *
-     * for: sput-object,
-     */
-    /* op vAA, field@BBBB */
-    EXPORT_PC()
-    addu   a0, rFP, OFF_FP_SHADOWFRAME
-    move   a1, rPC
-    move   a2, rINST
-    move   a3, rSELF
-    JAL(MterpSPutObj)
-    beqz   v0, MterpException
-    FETCH_ADVANCE_INST(2)               # advance rPC, load rINST
-    GET_INST_OPCODE(t0)                 # extract opcode from rINST
-    GOTO_OPCODE(t0)                     # jump to next instruction
+/* File: mips/op_sput.S */
+/* File: mips/field.S */
+TODO
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput_boolean: /* 0x6a */
 /* File: mips/op_sput_boolean.S */
 /* File: mips/op_sput.S */
-    /*
-     * General SPUT handler.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field@BBBB */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    GET_OPA(a3)                            # a3 <- AA
-    GET_VREG(a1, a3)                       # a1 <- fp[AA], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- method
-    move  a3, rSELF                        # a3 <- self
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpSPutU8)
-    bnez  v0, MterpException               # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -3339,24 +2908,9 @@
 .L_op_sput_byte: /* 0x6b */
 /* File: mips/op_sput_byte.S */
 /* File: mips/op_sput.S */
-    /*
-     * General SPUT handler.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field@BBBB */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    GET_OPA(a3)                            # a3 <- AA
-    GET_VREG(a1, a3)                       # a1 <- fp[AA], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- method
-    move  a3, rSELF                        # a3 <- self
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpSPutI8)
-    bnez  v0, MterpException               # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -3364,24 +2918,9 @@
 .L_op_sput_char: /* 0x6c */
 /* File: mips/op_sput_char.S */
 /* File: mips/op_sput.S */
-    /*
-     * General SPUT handler.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field@BBBB */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    GET_OPA(a3)                            # a3 <- AA
-    GET_VREG(a1, a3)                       # a1 <- fp[AA], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- method
-    move  a3, rSELF                        # a3 <- self
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpSPutU16)
-    bnez  v0, MterpException               # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -3389,24 +2928,9 @@
 .L_op_sput_short: /* 0x6d */
 /* File: mips/op_sput_short.S */
 /* File: mips/op_sput.S */
-    /*
-     * General SPUT handler.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field@BBBB */
-    EXPORT_PC()
-    FETCH(a0, 1)                           # a0 <- field ref BBBB
-    GET_OPA(a3)                            # a3 <- AA
-    GET_VREG(a1, a3)                       # a1 <- fp[AA], the object pointer
-    lw    a2, OFF_FP_METHOD(rFP)           # a2 <- method
-    move  a3, rSELF                        # a3 <- self
-    PREFETCH_INST(2)                       # load rINST
-    JAL(MterpSPutI16)
-    bnez  v0, MterpException               # bail out
-    ADVANCE(2)                             # advance rPC
-    GET_INST_OPCODE(t0)                    # extract opcode from rINST
-    GOTO_OPCODE(t0)                        # jump to next instruction
+/* File: mips/field.S */
+TODO
+
 
 
 /* ------------------------------ */
diff --git a/runtime/interpreter/mterp/out/mterp_mips64.S b/runtime/interpreter/mterp/out/mterp_mips64.S
index 6561691..40a8396 100644
--- a/runtime/interpreter/mterp/out/mterp_mips64.S
+++ b/runtime/interpreter/mterp/out/mterp_mips64.S
@@ -2241,88 +2241,28 @@
     .balign 128
 .L_op_iget: /* 0x52 */
 /* File: mips64/op_iget.S */
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    .extern MterpIGetU32
-    EXPORT_PC
-    lhu      a0, 2(rPC)                 # a0 <- field ref CCCC
-    srl      a1, rINST, 12              # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ld       a2, OFF_FP_METHOD(rFP)     # a2 <- referrer
-    move     a3, rSELF                  # a3 <- self
-    jal      MterpIGetU32
-    ld       a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    ext      a2, rINST, 8, 4            # a2 <- A
-    PREFETCH_INST 2
-    bnez     a3, MterpPossibleException # bail out
-    .if 0
-    SET_VREG_OBJECT v0, a2              # fp[A] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[A] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iget_wide: /* 0x53 */
 /* File: mips64/op_iget_wide.S */
-    /*
-     * 64-bit instance field get.
-     *
-     * for: iget-wide
-     */
-    .extern MterpIGetU64
-    EXPORT_PC
-    lhu      a0, 2(rPC)                 # a0 <- field ref CCCC
-    srl      a1, rINST, 12              # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ld       a2, OFF_FP_METHOD(rFP)     # a2 <- referrer
-    move     a3, rSELF                  # a3 <- self
-    jal      MterpIGetU64
-    ld       a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    ext      a2, rINST, 8, 4            # a2 <- A
-    PREFETCH_INST 2
-    bnez     a3, MterpPossibleException # bail out
-    SET_VREG_WIDE v0, a2                # fp[A] <- v0
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/op_iget.S */
+/* File: mips64/field.S */
+TODO
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iget_object: /* 0x54 */
 /* File: mips64/op_iget_object.S */
 /* File: mips64/op_iget.S */
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    .extern MterpIGetObj
-    EXPORT_PC
-    lhu      a0, 2(rPC)                 # a0 <- field ref CCCC
-    srl      a1, rINST, 12              # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ld       a2, OFF_FP_METHOD(rFP)     # a2 <- referrer
-    move     a3, rSELF                  # a3 <- self
-    jal      MterpIGetObj
-    ld       a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    ext      a2, rINST, 8, 4            # a2 <- A
-    PREFETCH_INST 2
-    bnez     a3, MterpPossibleException # bail out
-    .if 1
-    SET_VREG_OBJECT v0, a2              # fp[A] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[A] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2330,31 +2270,9 @@
 .L_op_iget_boolean: /* 0x55 */
 /* File: mips64/op_iget_boolean.S */
 /* File: mips64/op_iget.S */
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    .extern MterpIGetU8
-    EXPORT_PC
-    lhu      a0, 2(rPC)                 # a0 <- field ref CCCC
-    srl      a1, rINST, 12              # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ld       a2, OFF_FP_METHOD(rFP)     # a2 <- referrer
-    move     a3, rSELF                  # a3 <- self
-    jal      MterpIGetU8
-    ld       a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    ext      a2, rINST, 8, 4            # a2 <- A
-    PREFETCH_INST 2
-    bnez     a3, MterpPossibleException # bail out
-    .if 0
-    SET_VREG_OBJECT v0, a2              # fp[A] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[A] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2362,31 +2280,9 @@
 .L_op_iget_byte: /* 0x56 */
 /* File: mips64/op_iget_byte.S */
 /* File: mips64/op_iget.S */
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    .extern MterpIGetI8
-    EXPORT_PC
-    lhu      a0, 2(rPC)                 # a0 <- field ref CCCC
-    srl      a1, rINST, 12              # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ld       a2, OFF_FP_METHOD(rFP)     # a2 <- referrer
-    move     a3, rSELF                  # a3 <- self
-    jal      MterpIGetI8
-    ld       a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    ext      a2, rINST, 8, 4            # a2 <- A
-    PREFETCH_INST 2
-    bnez     a3, MterpPossibleException # bail out
-    .if 0
-    SET_VREG_OBJECT v0, a2              # fp[A] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[A] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2394,31 +2290,9 @@
 .L_op_iget_char: /* 0x57 */
 /* File: mips64/op_iget_char.S */
 /* File: mips64/op_iget.S */
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    .extern MterpIGetU16
-    EXPORT_PC
-    lhu      a0, 2(rPC)                 # a0 <- field ref CCCC
-    srl      a1, rINST, 12              # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ld       a2, OFF_FP_METHOD(rFP)     # a2 <- referrer
-    move     a3, rSELF                  # a3 <- self
-    jal      MterpIGetU16
-    ld       a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    ext      a2, rINST, 8, 4            # a2 <- A
-    PREFETCH_INST 2
-    bnez     a3, MterpPossibleException # bail out
-    .if 0
-    SET_VREG_OBJECT v0, a2              # fp[A] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[A] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2426,119 +2300,47 @@
 .L_op_iget_short: /* 0x58 */
 /* File: mips64/op_iget_short.S */
 /* File: mips64/op_iget.S */
-    /*
-     * General instance field get.
-     *
-     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
-     */
-    .extern MterpIGetI16
-    EXPORT_PC
-    lhu      a0, 2(rPC)                 # a0 <- field ref CCCC
-    srl      a1, rINST, 12              # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ld       a2, OFF_FP_METHOD(rFP)     # a2 <- referrer
-    move     a3, rSELF                  # a3 <- self
-    jal      MterpIGetI16
-    ld       a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    ext      a2, rINST, 8, 4            # a2 <- A
-    PREFETCH_INST 2
-    bnez     a3, MterpPossibleException # bail out
-    .if 0
-    SET_VREG_OBJECT v0, a2              # fp[A] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[A] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
     .balign 128
 .L_op_iput: /* 0x59 */
 /* File: mips64/op_iput.S */
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field//CCCC */
-    .extern MterpIPutU32
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref CCCC
-    srl     a1, rINST, 12               # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ext     a2, rINST, 8, 4             # a2 <- A
-    GET_VREG a2, a2                     # a2 <- fp[A]
-    ld      a3, OFF_FP_METHOD(rFP)      # a3 <- referrer
-    PREFETCH_INST 2
-    jal     MterpIPutU32
-    bnez    v0, MterpPossibleException  # bail out
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iput_wide: /* 0x5a */
 /* File: mips64/op_iput_wide.S */
-    /* iput-wide vA, vB, field//CCCC */
-    .extern MterpIPutU64
-    EXPORT_PC
-    lhu      a0, 2(rPC)                 # a0 <- field ref CCCC
-    srl      a1, rINST, 12              # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ext      a2, rINST, 8, 4            # a2 <- A
-    dlsa     a2, a2, rFP, 2             # a2 <- &fp[A]
-    ld       a3, OFF_FP_METHOD(rFP)     # a3 <- referrer
-    PREFETCH_INST 2
-    jal      MterpIPutU64
-    bnez     v0, MterpPossibleException # bail out
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/op_iput.S */
+/* File: mips64/field.S */
+TODO
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iput_object: /* 0x5b */
 /* File: mips64/op_iput_object.S */
-    .extern MterpIPutObj
-    EXPORT_PC
-    daddu   a0, rFP, OFF_FP_SHADOWFRAME
-    move    a1, rPC
-    move    a2, rINST
-    move    a3, rSELF
-    jal     MterpIPutObj
-    beqzc   v0, MterpException
-    FETCH_ADVANCE_INST 2                # advance rPC, load rINST
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/op_iput.S */
+/* File: mips64/field.S */
+TODO
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_iput_boolean: /* 0x5c */
 /* File: mips64/op_iput_boolean.S */
 /* File: mips64/op_iput.S */
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field//CCCC */
-    .extern MterpIPutU8
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref CCCC
-    srl     a1, rINST, 12               # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ext     a2, rINST, 8, 4             # a2 <- A
-    GET_VREG a2, a2                     # a2 <- fp[A]
-    ld      a3, OFF_FP_METHOD(rFP)      # a3 <- referrer
-    PREFETCH_INST 2
-    jal     MterpIPutU8
-    bnez    v0, MterpPossibleException  # bail out
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2546,26 +2348,9 @@
 .L_op_iput_byte: /* 0x5d */
 /* File: mips64/op_iput_byte.S */
 /* File: mips64/op_iput.S */
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field//CCCC */
-    .extern MterpIPutI8
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref CCCC
-    srl     a1, rINST, 12               # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ext     a2, rINST, 8, 4             # a2 <- A
-    GET_VREG a2, a2                     # a2 <- fp[A]
-    ld      a3, OFF_FP_METHOD(rFP)      # a3 <- referrer
-    PREFETCH_INST 2
-    jal     MterpIPutI8
-    bnez    v0, MterpPossibleException  # bail out
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2573,26 +2358,9 @@
 .L_op_iput_char: /* 0x5e */
 /* File: mips64/op_iput_char.S */
 /* File: mips64/op_iput.S */
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field//CCCC */
-    .extern MterpIPutU16
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref CCCC
-    srl     a1, rINST, 12               # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ext     a2, rINST, 8, 4             # a2 <- A
-    GET_VREG a2, a2                     # a2 <- fp[A]
-    ld      a3, OFF_FP_METHOD(rFP)      # a3 <- referrer
-    PREFETCH_INST 2
-    jal     MterpIPutU16
-    bnez    v0, MterpPossibleException  # bail out
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2600,111 +2368,37 @@
 .L_op_iput_short: /* 0x5f */
 /* File: mips64/op_iput_short.S */
 /* File: mips64/op_iput.S */
-    /*
-     * General 32-bit instance field put.
-     *
-     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
-     */
-    /* op vA, vB, field//CCCC */
-    .extern MterpIPutI16
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref CCCC
-    srl     a1, rINST, 12               # a1 <- B
-    GET_VREG_U a1, a1                   # a1 <- fp[B], the object pointer
-    ext     a2, rINST, 8, 4             # a2 <- A
-    GET_VREG a2, a2                     # a2 <- fp[A]
-    ld      a3, OFF_FP_METHOD(rFP)      # a3 <- referrer
-    PREFETCH_INST 2
-    jal     MterpIPutI16
-    bnez    v0, MterpPossibleException  # bail out
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
     .balign 128
 .L_op_sget: /* 0x60 */
 /* File: mips64/op_sget.S */
-    /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field//BBBB */
-    .extern MterpSGetU32
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    ld      a1, OFF_FP_METHOD(rFP)
-    move    a2, rSELF
-    jal     MterpSGetU32
-    ld      a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    srl     a2, rINST, 8                # a2 <- AA
-    
-    PREFETCH_INST 2
-    bnez    a3, MterpException          # bail out
-    .if 0
-    SET_VREG_OBJECT v0, a2              # fp[AA] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[AA] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sget_wide: /* 0x61 */
 /* File: mips64/op_sget_wide.S */
-    /*
-     * SGET_WIDE handler wrapper.
-     *
-     */
-    /* sget-wide vAA, field//BBBB */
-    .extern MterpSGetU64
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    ld      a1, OFF_FP_METHOD(rFP)
-    move    a2, rSELF
-    jal     MterpSGetU64
-    ld      a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    srl     a4, rINST, 8                # a4 <- AA
-    bnez    a3, MterpException          # bail out
-    FETCH_ADVANCE_INST 2                # advance rPC, load rINST
-    SET_VREG_WIDE v0, a4
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/op_sget.S */
+/* File: mips64/field.S */
+TODO
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sget_object: /* 0x62 */
 /* File: mips64/op_sget_object.S */
 /* File: mips64/op_sget.S */
-    /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field//BBBB */
-    .extern MterpSGetObj
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    ld      a1, OFF_FP_METHOD(rFP)
-    move    a2, rSELF
-    jal     MterpSGetObj
-    ld      a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    srl     a2, rINST, 8                # a2 <- AA
-    
-    PREFETCH_INST 2
-    bnez    a3, MterpException          # bail out
-    .if 1
-    SET_VREG_OBJECT v0, a2              # fp[AA] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[AA] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2712,31 +2406,9 @@
 .L_op_sget_boolean: /* 0x63 */
 /* File: mips64/op_sget_boolean.S */
 /* File: mips64/op_sget.S */
-    /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field//BBBB */
-    .extern MterpSGetU8
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    ld      a1, OFF_FP_METHOD(rFP)
-    move    a2, rSELF
-    jal     MterpSGetU8
-    ld      a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    srl     a2, rINST, 8                # a2 <- AA
-    and v0, v0, 0xff
-    PREFETCH_INST 2
-    bnez    a3, MterpException          # bail out
-    .if 0
-    SET_VREG_OBJECT v0, a2              # fp[AA] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[AA] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2744,31 +2416,9 @@
 .L_op_sget_byte: /* 0x64 */
 /* File: mips64/op_sget_byte.S */
 /* File: mips64/op_sget.S */
-    /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field//BBBB */
-    .extern MterpSGetI8
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    ld      a1, OFF_FP_METHOD(rFP)
-    move    a2, rSELF
-    jal     MterpSGetI8
-    ld      a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    srl     a2, rINST, 8                # a2 <- AA
-    seb v0, v0
-    PREFETCH_INST 2
-    bnez    a3, MterpException          # bail out
-    .if 0
-    SET_VREG_OBJECT v0, a2              # fp[AA] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[AA] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2776,31 +2426,9 @@
 .L_op_sget_char: /* 0x65 */
 /* File: mips64/op_sget_char.S */
 /* File: mips64/op_sget.S */
-    /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field//BBBB */
-    .extern MterpSGetU16
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    ld      a1, OFF_FP_METHOD(rFP)
-    move    a2, rSELF
-    jal     MterpSGetU16
-    ld      a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    srl     a2, rINST, 8                # a2 <- AA
-    and v0, v0, 0xffff
-    PREFETCH_INST 2
-    bnez    a3, MterpException          # bail out
-    .if 0
-    SET_VREG_OBJECT v0, a2              # fp[AA] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[AA] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2808,120 +2436,47 @@
 .L_op_sget_short: /* 0x66 */
 /* File: mips64/op_sget_short.S */
 /* File: mips64/op_sget.S */
-    /*
-     * General SGET handler wrapper.
-     *
-     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
-     */
-    /* op vAA, field//BBBB */
-    .extern MterpSGetI16
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    ld      a1, OFF_FP_METHOD(rFP)
-    move    a2, rSELF
-    jal     MterpSGetI16
-    ld      a3, THREAD_EXCEPTION_OFFSET(rSELF)
-    srl     a2, rINST, 8                # a2 <- AA
-    seh v0, v0
-    PREFETCH_INST 2
-    bnez    a3, MterpException          # bail out
-    .if 0
-    SET_VREG_OBJECT v0, a2              # fp[AA] <- v0
-    .else
-    SET_VREG v0, a2                     # fp[AA] <- v0
-    .endif
-    ADVANCE 2
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput: /* 0x67 */
 /* File: mips64/op_sput.S */
-    /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field//BBBB */
-    .extern MterpSPutU32
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    srl     a3, rINST, 8                # a3 <- AA
-    GET_VREG a1, a3                     # a1 <- fp[AA]
-    ld      a2, OFF_FP_METHOD(rFP)
-    move    a3, rSELF
-    PREFETCH_INST 2                     # Get next inst, but don't advance rPC
-    jal     MterpSPutU32
-    bnezc   v0, MterpException          # 0 on success
-    ADVANCE 2                           # Past exception point - now advance rPC
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput_wide: /* 0x68 */
 /* File: mips64/op_sput_wide.S */
-    /*
-     * SPUT_WIDE handler wrapper.
-     *
-     */
-    /* sput-wide vAA, field//BBBB */
-    .extern MterpSPutU64
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    srl     a1, rINST, 8                # a2 <- AA
-    dlsa    a1, a1, rFP, 2
-    ld      a2, OFF_FP_METHOD(rFP)
-    move    a3, rSELF
-    PREFETCH_INST 2                     # Get next inst, but don't advance rPC
-    jal     MterpSPutU64
-    bnezc   v0, MterpException          # 0 on success, -1 on failure
-    ADVANCE 2                           # Past exception point - now advance rPC
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/op_sput.S */
+/* File: mips64/field.S */
+TODO
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput_object: /* 0x69 */
 /* File: mips64/op_sput_object.S */
-    .extern MterpSPutObj
-    EXPORT_PC
-    daddu   a0, rFP, OFF_FP_SHADOWFRAME
-    move    a1, rPC
-    move    a2, rINST
-    move    a3, rSELF
-    jal     MterpSPutObj
-    beqzc   v0, MterpException
-    FETCH_ADVANCE_INST 2                # advance rPC, load rINST
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/op_sput.S */
+/* File: mips64/field.S */
+TODO
+
+
 
 /* ------------------------------ */
     .balign 128
 .L_op_sput_boolean: /* 0x6a */
 /* File: mips64/op_sput_boolean.S */
 /* File: mips64/op_sput.S */
-    /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field//BBBB */
-    .extern MterpSPutU8
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    srl     a3, rINST, 8                # a3 <- AA
-    GET_VREG a1, a3                     # a1 <- fp[AA]
-    ld      a2, OFF_FP_METHOD(rFP)
-    move    a3, rSELF
-    PREFETCH_INST 2                     # Get next inst, but don't advance rPC
-    jal     MterpSPutU8
-    bnezc   v0, MterpException          # 0 on success
-    ADVANCE 2                           # Past exception point - now advance rPC
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2929,25 +2484,9 @@
 .L_op_sput_byte: /* 0x6b */
 /* File: mips64/op_sput_byte.S */
 /* File: mips64/op_sput.S */
-    /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field//BBBB */
-    .extern MterpSPutI8
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    srl     a3, rINST, 8                # a3 <- AA
-    GET_VREG a1, a3                     # a1 <- fp[AA]
-    ld      a2, OFF_FP_METHOD(rFP)
-    move    a3, rSELF
-    PREFETCH_INST 2                     # Get next inst, but don't advance rPC
-    jal     MterpSPutI8
-    bnezc   v0, MterpException          # 0 on success
-    ADVANCE 2                           # Past exception point - now advance rPC
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2955,25 +2494,9 @@
 .L_op_sput_char: /* 0x6c */
 /* File: mips64/op_sput_char.S */
 /* File: mips64/op_sput.S */
-    /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field//BBBB */
-    .extern MterpSPutU16
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    srl     a3, rINST, 8                # a3 <- AA
-    GET_VREG a1, a3                     # a1 <- fp[AA]
-    ld      a2, OFF_FP_METHOD(rFP)
-    move    a3, rSELF
-    PREFETCH_INST 2                     # Get next inst, but don't advance rPC
-    jal     MterpSPutU16
-    bnezc   v0, MterpException          # 0 on success
-    ADVANCE 2                           # Past exception point - now advance rPC
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
@@ -2981,25 +2504,9 @@
 .L_op_sput_short: /* 0x6d */
 /* File: mips64/op_sput_short.S */
 /* File: mips64/op_sput.S */
-    /*
-     * General SPUT handler wrapper.
-     *
-     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
-     */
-    /* op vAA, field//BBBB */
-    .extern MterpSPutI16
-    EXPORT_PC
-    lhu     a0, 2(rPC)                  # a0 <- field ref BBBB
-    srl     a3, rINST, 8                # a3 <- AA
-    GET_VREG a1, a3                     # a1 <- fp[AA]
-    ld      a2, OFF_FP_METHOD(rFP)
-    move    a3, rSELF
-    PREFETCH_INST 2                     # Get next inst, but don't advance rPC
-    jal     MterpSPutI16
-    bnezc   v0, MterpException          # 0 on success
-    ADVANCE 2                           # Past exception point - now advance rPC
-    GET_INST_OPCODE v0                  # extract opcode from rINST
-    GOTO_OPCODE v0                      # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
 
 
 /* ------------------------------ */
diff --git a/runtime/interpreter/mterp/out/mterp_x86.S b/runtime/interpreter/mterp/out/mterp_x86.S
index 3f70919..32811ff 100644
--- a/runtime/interpreter/mterp/out/mterp_x86.S
+++ b/runtime/interpreter/mterp/out/mterp_x86.S
@@ -2120,832 +2120,694 @@
     .balign 128
 .L_op_iget: /* 0x52 */
 /* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax <- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx <- BA
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    mov     rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetU32
+    REFRESH_INST 82                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIGetU32)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    .if 0
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <-value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <-value
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_wide: /* 0x53 */
 /* File: x86/op_iget_wide.S */
-/*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax <- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx <- BA
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    mov     rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
+/* File: x86/op_iget.S */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetU64
+    REFRESH_INST 83                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIGetU64)
-    mov     rSELF, %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    SET_VREG %eax, rINST
-    SET_VREG_HIGH %edx, rINST
-    RESTORE_IBASE_FROM_SELF %ecx
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_object: /* 0x54 */
 /* File: x86/op_iget_object.S */
 /* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax <- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx <- BA
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    mov     rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetObj
+    REFRESH_INST 84                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIGetObj)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    .if 1
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <-value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <-value
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_boolean: /* 0x55 */
 /* File: x86/op_iget_boolean.S */
 /* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax <- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx <- BA
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    mov     rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetU8
+    REFRESH_INST 85                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIGetU8)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    .if 0
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <-value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <-value
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_byte: /* 0x56 */
 /* File: x86/op_iget_byte.S */
 /* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax <- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx <- BA
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    mov     rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetI8
+    REFRESH_INST 86                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIGetI8)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    .if 0
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <-value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <-value
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_char: /* 0x57 */
 /* File: x86/op_iget_char.S */
 /* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax <- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx <- BA
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    mov     rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetU16
+    REFRESH_INST 87                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIGetU16)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    .if 0
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <-value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <-value
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_short: /* 0x58 */
 /* File: x86/op_iget_short.S */
 /* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax <- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx <- BA
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    mov     rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetI16
+    REFRESH_INST 88                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIGetI16)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    .if 0
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <-value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <-value
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput: /* 0x59 */
 /* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
-    /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutU32
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax<- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx<- BA
-    sarl    $4, %ecx                       # ecx<- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    andb    $0xf, rINSTbl                  # rINST<- A
-    GET_VREG %eax, rINST
-    movl    %eax, OUT_ARG2(%esp)            # fp[A]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG3(%esp)            # referrer
+    REFRESH_INST 89                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIPutU32)
     testb   %al, %al
-    jnz     MterpPossibleException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput_wide: /* 0x5a */
 /* File: x86/op_iput_wide.S */
-    /* iput-wide vA, vB, field@CCCC */
+/* File: x86/op_iput.S */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutU64
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax <- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl,%ecx                    # ecx <- BA
-    sarl    $4,%ecx                        # ecx <- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    andb    $0xf,rINSTbl                   # rINST <- A
-    leal    VREG_ADDRESS(rINST), %eax
-    movl    %eax, OUT_ARG2(%esp)            # &fp[A]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG3(%esp)            # referrer
+    REFRESH_INST 90                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIPutU64)
     testb   %al, %al
-    jnz     MterpPossibleException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput_object: /* 0x5b */
 /* File: x86/op_iput_object.S */
-    EXPORT_PC
+/* File: x86/op_iput.S */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIPutObj
+    REFRESH_INST 91                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
     leal    OFF_FP_SHADOWFRAME(rFP), %eax
-    movl    %eax, OUT_ARG0(%esp)
-    movl    rPC, OUT_ARG1(%esp)
-    REFRESH_INST 91
-    movl    rINST, OUT_ARG2(%esp)
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
     movl    rSELF, %eax
-    movl    %eax, OUT_ARG3(%esp)
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIPutObj)
     testb   %al, %al
-    jz      MterpException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput_boolean: /* 0x5c */
 /* File: x86/op_iput_boolean.S */
 /* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
-    /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutU8
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax<- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx<- BA
-    sarl    $4, %ecx                       # ecx<- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    andb    $0xf, rINSTbl                  # rINST<- A
-    GET_VREG %eax, rINST
-    movl    %eax, OUT_ARG2(%esp)            # fp[A]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG3(%esp)            # referrer
+    REFRESH_INST 92                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIPutU8)
     testb   %al, %al
-    jnz     MterpPossibleException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput_byte: /* 0x5d */
 /* File: x86/op_iput_byte.S */
 /* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
-    /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutI8
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax<- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx<- BA
-    sarl    $4, %ecx                       # ecx<- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    andb    $0xf, rINSTbl                  # rINST<- A
-    GET_VREG %eax, rINST
-    movl    %eax, OUT_ARG2(%esp)            # fp[A]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG3(%esp)            # referrer
+    REFRESH_INST 93                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIPutI8)
     testb   %al, %al
-    jnz     MterpPossibleException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput_char: /* 0x5e */
 /* File: x86/op_iput_char.S */
 /* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
-    /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutU16
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax<- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx<- BA
-    sarl    $4, %ecx                       # ecx<- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    andb    $0xf, rINSTbl                  # rINST<- A
-    GET_VREG %eax, rINST
-    movl    %eax, OUT_ARG2(%esp)            # fp[A]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG3(%esp)            # referrer
+    REFRESH_INST 94                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIPutU16)
     testb   %al, %al
-    jnz     MterpPossibleException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput_short: /* 0x5f */
 /* File: x86/op_iput_short.S */
 /* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
-    /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutI16
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax<- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx<- BA
-    sarl    $4, %ecx                       # ecx<- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    andb    $0xf, rINSTbl                  # rINST<- A
-    GET_VREG %eax, rINST
-    movl    %eax, OUT_ARG2(%esp)            # fp[A]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG3(%esp)            # referrer
+    REFRESH_INST 95                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpIPutI16)
     testb   %al, %al
-    jnz     MterpPossibleException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget: /* 0x60 */
 /* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetU32
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG1(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG2(%esp)            # self
+    REFRESH_INST 96                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSGetU32)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException
-    .if 0
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <- value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <- value
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget_wide: /* 0x61 */
 /* File: x86/op_sget_wide.S */
-/*
- * SGET_WIDE handler wrapper.
- *
- */
-    /* sget-wide vAA, field@BBBB */
+/* File: x86/op_sget.S */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetU64
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG1(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG2(%esp)            # self
+    REFRESH_INST 97                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSGetU64)
-    movl    rSELF, %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException
-    SET_VREG %eax, rINST                    # fp[A]<- low part
-    SET_VREG_HIGH %edx, rINST               # fp[A+1]<- high part
-    RESTORE_IBASE_FROM_SELF %ecx
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget_object: /* 0x62 */
 /* File: x86/op_sget_object.S */
 /* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetObj
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG1(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG2(%esp)            # self
+    REFRESH_INST 98                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSGetObj)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException
-    .if 1
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <- value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <- value
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget_boolean: /* 0x63 */
 /* File: x86/op_sget_boolean.S */
 /* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetU8
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG1(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG2(%esp)            # self
+    REFRESH_INST 99                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSGetU8)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException
-    .if 0
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <- value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <- value
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget_byte: /* 0x64 */
 /* File: x86/op_sget_byte.S */
 /* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetI8
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG1(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG2(%esp)            # self
+    REFRESH_INST 100                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSGetI8)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException
-    .if 0
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <- value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <- value
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget_char: /* 0x65 */
 /* File: x86/op_sget_char.S */
 /* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetU16
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG1(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG2(%esp)            # self
+    REFRESH_INST 101                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSGetU16)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException
-    .if 0
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <- value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <- value
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget_short: /* 0x66 */
 /* File: x86/op_sget_short.S */
 /* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetI16
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG1(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG2(%esp)            # self
+    REFRESH_INST 102                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSGetI16)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException
-    .if 0
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <- value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <- value
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput: /* 0x67 */
 /* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSPutU32
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref BBBB
-    GET_VREG rINST, rINST
-    movl    rINST, OUT_ARG1(%esp)           # fp[AA]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
+    REFRESH_INST 103                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSPutU32)
     testb   %al, %al
-    jnz     MterpException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput_wide: /* 0x68 */
 /* File: x86/op_sput_wide.S */
-/*
- * SPUT_WIDE handler wrapper.
- *
- */
-    /* sput-wide vAA, field@BBBB */
+/* File: x86/op_sput.S */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSPutU64
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref BBBB
-    leal    VREG_ADDRESS(rINST), %eax
-    movl    %eax, OUT_ARG1(%esp)            # &fp[AA]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
+    REFRESH_INST 104                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSPutU64)
     testb   %al, %al
-    jnz     MterpException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput_object: /* 0x69 */
 /* File: x86/op_sput_object.S */
-    EXPORT_PC
+/* File: x86/op_sput.S */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpSPutObj
+    REFRESH_INST 105                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
     leal    OFF_FP_SHADOWFRAME(rFP), %eax
-    movl    %eax, OUT_ARG0(%esp)
-    movl    rPC, OUT_ARG1(%esp)
-    REFRESH_INST 105
-    movl    rINST, OUT_ARG2(%esp)
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSPutObj)
     testb   %al, %al
-    jz      MterpException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput_boolean: /* 0x6a */
 /* File: x86/op_sput_boolean.S */
 /* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSPutU8
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref BBBB
-    GET_VREG rINST, rINST
-    movl    rINST, OUT_ARG1(%esp)           # fp[AA]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
+    REFRESH_INST 106                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSPutU8)
     testb   %al, %al
-    jnz     MterpException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput_byte: /* 0x6b */
 /* File: x86/op_sput_byte.S */
 /* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSPutI8
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref BBBB
-    GET_VREG rINST, rINST
-    movl    rINST, OUT_ARG1(%esp)           # fp[AA]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
+    REFRESH_INST 107                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSPutI8)
     testb   %al, %al
-    jnz     MterpException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput_char: /* 0x6c */
 /* File: x86/op_sput_char.S */
 /* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSPutU16
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref BBBB
-    GET_VREG rINST, rINST
-    movl    rINST, OUT_ARG1(%esp)           # fp[AA]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
+    REFRESH_INST 108                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSPutU16)
     testb   %al, %al
-    jnz     MterpException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput_short: /* 0x6d */
 /* File: x86/op_sput_short.S */
 /* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSPutI16
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref BBBB
-    GET_VREG rINST, rINST
-    movl    rINST, OUT_ARG1(%esp)           # fp[AA]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
+    REFRESH_INST 109                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
     call    SYMBOL(MterpSPutI16)
     testb   %al, %al
-    jnz     MterpException
+    jz      MterpPossibleException
     RESTORE_IBASE
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_invoke_virtual: /* 0x6e */
diff --git a/runtime/interpreter/mterp/out/mterp_x86_64.S b/runtime/interpreter/mterp/out/mterp_x86_64.S
index 89d5637..6d8bb4c 100644
--- a/runtime/interpreter/mterp/out/mterp_x86_64.S
+++ b/runtime/interpreter/mterp/out/mterp_x86_64.S
@@ -2067,770 +2067,610 @@
     .balign 128
 .L_op_iget: /* 0x52 */
 /* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
-    EXPORT_PC
-    movzbq  rINSTbl, %rcx                   # rcx <- BA
-    movzwl  2(rPC), OUT_32_ARG0             # eax <- field ref CCCC
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetU32
+    REFRESH_INST 82                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIGetU32)
-    movq    rSELF, %rcx
-    cmpq    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    .if 0
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <-value
-    .else
-    .if 0
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <-value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <-value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_wide: /* 0x53 */
 /* File: x86_64/op_iget_wide.S */
 /* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
-    EXPORT_PC
-    movzbq  rINSTbl, %rcx                   # rcx <- BA
-    movzwl  2(rPC), OUT_32_ARG0             # eax <- field ref CCCC
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetU64
+    REFRESH_INST 83                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIGetU64)
-    movq    rSELF, %rcx
-    cmpq    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    .if 0
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <-value
-    .else
-    .if 1
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <-value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <-value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_object: /* 0x54 */
 /* File: x86_64/op_iget_object.S */
 /* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
-    EXPORT_PC
-    movzbq  rINSTbl, %rcx                   # rcx <- BA
-    movzwl  2(rPC), OUT_32_ARG0             # eax <- field ref CCCC
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetObj
+    REFRESH_INST 84                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIGetObj)
-    movq    rSELF, %rcx
-    cmpq    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    .if 1
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <-value
-    .else
-    .if 0
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <-value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <-value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_boolean: /* 0x55 */
 /* File: x86_64/op_iget_boolean.S */
 /* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
-    EXPORT_PC
-    movzbq  rINSTbl, %rcx                   # rcx <- BA
-    movzwl  2(rPC), OUT_32_ARG0             # eax <- field ref CCCC
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetU8
+    REFRESH_INST 85                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIGetU8)
-    movq    rSELF, %rcx
-    cmpq    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    .if 0
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <-value
-    .else
-    .if 0
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <-value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <-value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_byte: /* 0x56 */
 /* File: x86_64/op_iget_byte.S */
 /* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
-    EXPORT_PC
-    movzbq  rINSTbl, %rcx                   # rcx <- BA
-    movzwl  2(rPC), OUT_32_ARG0             # eax <- field ref CCCC
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetI8
+    REFRESH_INST 86                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIGetI8)
-    movq    rSELF, %rcx
-    cmpq    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    .if 0
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <-value
-    .else
-    .if 0
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <-value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <-value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_char: /* 0x57 */
 /* File: x86_64/op_iget_char.S */
 /* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
-    EXPORT_PC
-    movzbq  rINSTbl, %rcx                   # rcx <- BA
-    movzwl  2(rPC), OUT_32_ARG0             # eax <- field ref CCCC
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetU16
+    REFRESH_INST 87                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIGetU16)
-    movq    rSELF, %rcx
-    cmpq    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    .if 0
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <-value
-    .else
-    .if 0
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <-value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <-value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iget_short: /* 0x58 */
 /* File: x86_64/op_iget_short.S */
 /* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
-    EXPORT_PC
-    movzbq  rINSTbl, %rcx                   # rcx <- BA
-    movzwl  2(rPC), OUT_32_ARG0             # eax <- field ref CCCC
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIGetI16
+    REFRESH_INST 88                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIGetI16)
-    movq    rSELF, %rcx
-    cmpq    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException                  # bail out
-    andb    $0xf, rINSTbl                  # rINST <- A
-    .if 0
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <-value
-    .else
-    .if 0
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <-value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <-value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput: /* 0x59 */
 /* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
-    /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutU32
-    EXPORT_PC
-    movzwl  2(rPC), OUT_32_ARG0             # field ref <- 0000CCCC
-    movzbq  rINSTbl, %rcx                   # rcx<- BA
-    sarl    $4, %ecx                       # ecx<- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    andb    $0xf, rINSTbl                  # rINST<- A
-    GET_VREG OUT_32_ARG2, rINSTq            # fp[A]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG3    # referrer
+    REFRESH_INST 89                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIPutU32)
     testb   %al, %al
-    jnz     MterpPossibleException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput_wide: /* 0x5a */
 /* File: x86_64/op_iput_wide.S */
-    /* iput-wide vA, vB, field@CCCC */
+/* File: x86_64/op_iput.S */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutU64
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref CCCC
-    movzbq  rINSTbl, %rcx                   # rcx <- BA
-    sarl    $4, %ecx                       # ecx <- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    andb    $0xf, rINSTbl                  # rINST <- A
-    leaq    VREG_ADDRESS(rINSTq), OUT_ARG2  # &fp[A]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG3    # referrer
+    REFRESH_INST 90                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIPutU64)
     testb   %al, %al
-    jnz     MterpPossibleException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput_object: /* 0x5b */
 /* File: x86_64/op_iput_object.S */
-    EXPORT_PC
-    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
-    movq    rPC, OUT_ARG1
-    REFRESH_INST 91
-    movl    rINST, OUT_32_ARG2
-    movq    rSELF, OUT_ARG3
+/* File: x86_64/op_iput.S */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpIPutObj
+    REFRESH_INST 91                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIPutObj)
     testb   %al, %al
-    jz      MterpException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput_boolean: /* 0x5c */
 /* File: x86_64/op_iput_boolean.S */
 /* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
-    /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutU8
-    EXPORT_PC
-    movzwl  2(rPC), OUT_32_ARG0             # field ref <- 0000CCCC
-    movzbq  rINSTbl, %rcx                   # rcx<- BA
-    sarl    $4, %ecx                       # ecx<- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    andb    $0xf, rINSTbl                  # rINST<- A
-    GET_VREG OUT_32_ARG2, rINSTq            # fp[A]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG3    # referrer
+    REFRESH_INST 92                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIPutU8)
     testb   %al, %al
-    jnz     MterpPossibleException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput_byte: /* 0x5d */
 /* File: x86_64/op_iput_byte.S */
 /* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
-    /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutI8
-    EXPORT_PC
-    movzwl  2(rPC), OUT_32_ARG0             # field ref <- 0000CCCC
-    movzbq  rINSTbl, %rcx                   # rcx<- BA
-    sarl    $4, %ecx                       # ecx<- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    andb    $0xf, rINSTbl                  # rINST<- A
-    GET_VREG OUT_32_ARG2, rINSTq            # fp[A]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG3    # referrer
+    REFRESH_INST 93                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIPutI8)
     testb   %al, %al
-    jnz     MterpPossibleException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput_char: /* 0x5e */
 /* File: x86_64/op_iput_char.S */
 /* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
-    /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutU16
-    EXPORT_PC
-    movzwl  2(rPC), OUT_32_ARG0             # field ref <- 0000CCCC
-    movzbq  rINSTbl, %rcx                   # rcx<- BA
-    sarl    $4, %ecx                       # ecx<- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    andb    $0xf, rINSTbl                  # rINST<- A
-    GET_VREG OUT_32_ARG2, rINSTq            # fp[A]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG3    # referrer
+    REFRESH_INST 94                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIPutU16)
     testb   %al, %al
-    jnz     MterpPossibleException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_iput_short: /* 0x5f */
 /* File: x86_64/op_iput_short.S */
 /* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
-    /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpIPutI16
-    EXPORT_PC
-    movzwl  2(rPC), OUT_32_ARG0             # field ref <- 0000CCCC
-    movzbq  rINSTbl, %rcx                   # rcx<- BA
-    sarl    $4, %ecx                       # ecx<- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    andb    $0xf, rINSTbl                  # rINST<- A
-    GET_VREG OUT_32_ARG2, rINSTq            # fp[A]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG3    # referrer
+    REFRESH_INST 95                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpIPutI16)
     testb   %al, %al
-    jnz     MterpPossibleException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget: /* 0x60 */
 /* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
-    /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetU32
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref CCCC
-    movq    OFF_FP_METHOD(rFP), OUT_ARG1    # referrer
-    movq    rSELF, OUT_ARG2                 # self
+    REFRESH_INST 96                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSGetU32)
-    movq    rSELF, %rcx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException
-    .if 0
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <- value
-    .else
-    .if 0
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <- value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <- value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget_wide: /* 0x61 */
 /* File: x86_64/op_sget_wide.S */
 /* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
-    /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetU64
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref CCCC
-    movq    OFF_FP_METHOD(rFP), OUT_ARG1    # referrer
-    movq    rSELF, OUT_ARG2                 # self
+    REFRESH_INST 97                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSGetU64)
-    movq    rSELF, %rcx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException
-    .if 0
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <- value
-    .else
-    .if 1
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <- value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <- value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget_object: /* 0x62 */
 /* File: x86_64/op_sget_object.S */
 /* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
-    /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetObj
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref CCCC
-    movq    OFF_FP_METHOD(rFP), OUT_ARG1    # referrer
-    movq    rSELF, OUT_ARG2                 # self
+    REFRESH_INST 98                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSGetObj)
-    movq    rSELF, %rcx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException
-    .if 1
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <- value
-    .else
-    .if 0
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <- value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <- value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget_boolean: /* 0x63 */
 /* File: x86_64/op_sget_boolean.S */
 /* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
-    /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetU8
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref CCCC
-    movq    OFF_FP_METHOD(rFP), OUT_ARG1    # referrer
-    movq    rSELF, OUT_ARG2                 # self
+    REFRESH_INST 99                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSGetU8)
-    movq    rSELF, %rcx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException
-    .if 0
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <- value
-    .else
-    .if 0
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <- value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <- value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget_byte: /* 0x64 */
 /* File: x86_64/op_sget_byte.S */
 /* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
-    /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetI8
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref CCCC
-    movq    OFF_FP_METHOD(rFP), OUT_ARG1    # referrer
-    movq    rSELF, OUT_ARG2                 # self
+    REFRESH_INST 100                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSGetI8)
-    movq    rSELF, %rcx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException
-    .if 0
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <- value
-    .else
-    .if 0
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <- value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <- value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget_char: /* 0x65 */
 /* File: x86_64/op_sget_char.S */
 /* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
-    /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetU16
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref CCCC
-    movq    OFF_FP_METHOD(rFP), OUT_ARG1    # referrer
-    movq    rSELF, OUT_ARG2                 # self
+    REFRESH_INST 101                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSGetU16)
-    movq    rSELF, %rcx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException
-    .if 0
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <- value
-    .else
-    .if 0
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <- value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <- value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sget_short: /* 0x66 */
 /* File: x86_64/op_sget_short.S */
 /* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
-    /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSGetI16
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref CCCC
-    movq    OFF_FP_METHOD(rFP), OUT_ARG1    # referrer
-    movq    rSELF, OUT_ARG2                 # self
+    REFRESH_INST 102                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSGetI16)
-    movq    rSELF, %rcx
-    cmpl    $0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException
-    .if 0
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <- value
-    .else
-    .if 0
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <- value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <- value
-    .endif
-    .endif
+    testb   %al, %al
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput: /* 0x67 */
 /* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSPutU32
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref BBBB
-    GET_VREG OUT_32_ARG1, rINSTq            # fp[AA]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3                 # self
+    REFRESH_INST 103                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSPutU32)
     testb   %al, %al
-    jnz     MterpException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput_wide: /* 0x68 */
 /* File: x86_64/op_sput_wide.S */
-/*
- * SPUT_WIDE handler wrapper.
- *
- */
-    /* sput-wide vAA, field@BBBB */
+/* File: x86_64/op_sput.S */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSPutU64
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref BBBB
-    leaq    VREG_ADDRESS(rINSTq), OUT_ARG1  # &fp[AA]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3                 # self
+    REFRESH_INST 104                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSPutU64)
     testb   %al, %al
-    jnz     MterpException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput_object: /* 0x69 */
 /* File: x86_64/op_sput_object.S */
-    EXPORT_PC
-    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
-    movq    rPC, OUT_ARG1
-    REFRESH_INST 105
-    movq    rINSTq, OUT_ARG2
-    movq    rSELF, OUT_ARG3
+/* File: x86_64/op_sput.S */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern MterpSPutObj
+    REFRESH_INST 105                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSPutObj)
     testb   %al, %al
-    jz      MterpException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
+
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput_boolean: /* 0x6a */
 /* File: x86_64/op_sput_boolean.S */
 /* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSPutU8
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref BBBB
-    GET_VREG OUT_32_ARG1, rINSTq            # fp[AA]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3                 # self
+    REFRESH_INST 106                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSPutU8)
     testb   %al, %al
-    jnz     MterpException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput_byte: /* 0x6b */
 /* File: x86_64/op_sput_byte.S */
 /* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSPutI8
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref BBBB
-    GET_VREG OUT_32_ARG1, rINSTq            # fp[AA]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3                 # self
+    REFRESH_INST 107                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSPutI8)
     testb   %al, %al
-    jnz     MterpException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput_char: /* 0x6c */
 /* File: x86_64/op_sput_char.S */
 /* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSPutU16
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref BBBB
-    GET_VREG OUT_32_ARG1, rINSTq            # fp[AA]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3                 # self
+    REFRESH_INST 108                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSPutU16)
     testb   %al, %al
-    jnz     MterpException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_sput_short: /* 0x6d */
 /* File: x86_64/op_sput_short.S */
 /* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
-    /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
     .extern MterpSPutI16
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref BBBB
-    GET_VREG OUT_32_ARG1, rINSTq            # fp[AA]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3                 # self
+    REFRESH_INST 109                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
     call    SYMBOL(MterpSPutI16)
     testb   %al, %al
-    jnz     MterpException
+    jz      MterpPossibleException
     ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
 
 
+
 /* ------------------------------ */
     .balign 128
 .L_op_invoke_virtual: /* 0x6e */
diff --git a/runtime/interpreter/mterp/x86/field.S b/runtime/interpreter/mterp/x86/field.S
new file mode 100644
index 0000000..8432c74
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/field.S
@@ -0,0 +1,17 @@
+%default { }
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern $helper
+    REFRESH_INST ${opnum}                   # fix rINST to include opcode
+    movl    rPC, OUT_ARG0(%esp)             # arg0: Instruction* inst
+    movl    rINST, OUT_ARG1(%esp)           # arg1: uint16_t inst_data
+    leal    OFF_FP_SHADOWFRAME(rFP), %eax
+    movl    %eax, OUT_ARG2(%esp)            # arg2: ShadowFrame* sf
+    movl    rSELF, %eax
+    movl    %eax, OUT_ARG3(%esp)            # arg3: Thread* self
+    call    SYMBOL($helper)
+    testb   %al, %al
+    jz      MterpPossibleException
+    RESTORE_IBASE
+    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_iget.S b/runtime/interpreter/mterp/x86/op_iget.S
index 0af1bec..d85d54c 100644
--- a/runtime/interpreter/mterp/x86/op_iget.S
+++ b/runtime/interpreter/mterp/x86/op_iget.S
@@ -1,29 +1,2 @@
 %default { "is_object":"0", "helper":"MterpIGetU32"}
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax <- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx <- BA
-    sarl    $$4, %ecx                       # ecx <- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    mov     rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
-    call    SYMBOL($helper)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $$0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException                  # bail out
-    andb    $$0xf, rINSTbl                  # rINST <- A
-    .if $is_object
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <-value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <-value
-    .endif
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/field.S" { }
diff --git a/runtime/interpreter/mterp/x86/op_iget_wide.S b/runtime/interpreter/mterp/x86/op_iget_wide.S
index da27df9..741a64e 100644
--- a/runtime/interpreter/mterp/x86/op_iget_wide.S
+++ b/runtime/interpreter/mterp/x86/op_iget_wide.S
@@ -1,25 +1 @@
-/*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax <- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx <- BA
-    sarl    $$4, %ecx                       # ecx <- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    mov     rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
-    call    SYMBOL(MterpIGetU64)
-    mov     rSELF, %ecx
-    cmpl    $$0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException                  # bail out
-    andb    $$0xf, rINSTbl                  # rINST <- A
-    SET_VREG %eax, rINST
-    SET_VREG_HIGH %edx, rINST
-    RESTORE_IBASE_FROM_SELF %ecx
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/x86/op_iput.S b/runtime/interpreter/mterp/x86/op_iput.S
index 4c6603a..3628ffd 100644
--- a/runtime/interpreter/mterp/x86/op_iput.S
+++ b/runtime/interpreter/mterp/x86/op_iput.S
@@ -1,25 +1,2 @@
-%default { "helper":"MterpIPutU32" }
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
-    /* op vA, vB, field@CCCC */
-    .extern $helper
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax<- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl, %ecx                   # ecx<- BA
-    sarl    $$4, %ecx                       # ecx<- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    andb    $$0xf, rINSTbl                  # rINST<- A
-    GET_VREG %eax, rINST
-    movl    %eax, OUT_ARG2(%esp)            # fp[A]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG3(%esp)            # referrer
-    call    SYMBOL($helper)
-    testb   %al, %al
-    jnz     MterpPossibleException
-    RESTORE_IBASE
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpIPutU32" }
+%include "x86/field.S" { }
diff --git a/runtime/interpreter/mterp/x86/op_iput_object.S b/runtime/interpreter/mterp/x86/op_iput_object.S
index 56e026e..a124b7e 100644
--- a/runtime/interpreter/mterp/x86/op_iput_object.S
+++ b/runtime/interpreter/mterp/x86/op_iput_object.S
@@ -1,13 +1 @@
-    EXPORT_PC
-    leal    OFF_FP_SHADOWFRAME(rFP), %eax
-    movl    %eax, OUT_ARG0(%esp)
-    movl    rPC, OUT_ARG1(%esp)
-    REFRESH_INST ${opnum}
-    movl    rINST, OUT_ARG2(%esp)
-    movl    rSELF, %eax
-    movl    %eax, OUT_ARG3(%esp)
-    call    SYMBOL(MterpIPutObj)
-    testb   %al, %al
-    jz      MterpException
-    RESTORE_IBASE
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/x86/op_iput_wide.S b/runtime/interpreter/mterp/x86/op_iput_wide.S
index ea22b91..2820ede 100644
--- a/runtime/interpreter/mterp/x86/op_iput_wide.S
+++ b/runtime/interpreter/mterp/x86/op_iput_wide.S
@@ -1,19 +1 @@
-    /* iput-wide vA, vB, field@CCCC */
-    .extern MterpIPutU64
-    EXPORT_PC
-    movzwl  2(rPC), %eax                    # eax <- 0000CCCC
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movzbl  rINSTbl,%ecx                    # ecx <- BA
-    sarl    $$4,%ecx                        # ecx <- B
-    GET_VREG %ecx, %ecx
-    movl    %ecx, OUT_ARG1(%esp)            # the object pointer
-    andb    $$0xf,rINSTbl                   # rINST <- A
-    leal    VREG_ADDRESS(rINST), %eax
-    movl    %eax, OUT_ARG2(%esp)            # &fp[A]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG3(%esp)            # referrer
-    call    SYMBOL(MterpIPutU64)
-    testb   %al, %al
-    jnz     MterpPossibleException
-    RESTORE_IBASE
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/x86/op_sget.S b/runtime/interpreter/mterp/x86/op_sget.S
index 66c7b0b..ada4e0e 100644
--- a/runtime/interpreter/mterp/x86/op_sget.S
+++ b/runtime/interpreter/mterp/x86/op_sget.S
@@ -1,26 +1,2 @@
 %default { "is_object":"0", "helper":"MterpSGetU32" }
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
-    /* op vAA, field@BBBB */
-    .extern $helper
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG1(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG2(%esp)            # self
-    call    SYMBOL($helper)
-    movl    rSELF, %ecx
-    RESTORE_IBASE_FROM_SELF %ecx
-    cmpl    $$0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException
-    .if $is_object
-    SET_VREG_OBJECT %eax, rINST             # fp[A] <- value
-    .else
-    SET_VREG %eax, rINST                    # fp[A] <- value
-    .endif
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/field.S" { }
diff --git a/runtime/interpreter/mterp/x86/op_sget_wide.S b/runtime/interpreter/mterp/x86/op_sget_wide.S
index 994cc3a..5923274 100644
--- a/runtime/interpreter/mterp/x86/op_sget_wide.S
+++ b/runtime/interpreter/mterp/x86/op_sget_wide.S
@@ -1,21 +1 @@
-/*
- * SGET_WIDE handler wrapper.
- *
- */
-    /* sget-wide vAA, field@BBBB */
-    .extern MterpSGetU64
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref CCCC
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG1(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG2(%esp)            # self
-    call    SYMBOL(MterpSGetU64)
-    movl    rSELF, %ecx
-    cmpl    $$0, THREAD_EXCEPTION_OFFSET(%ecx)
-    jnz     MterpException
-    SET_VREG %eax, rINST                    # fp[A]<- low part
-    SET_VREG_HIGH %edx, rINST               # fp[A+1]<- high part
-    RESTORE_IBASE_FROM_SELF %ecx
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/x86/op_sput.S b/runtime/interpreter/mterp/x86/op_sput.S
index e99e7a7..2ad68e7 100644
--- a/runtime/interpreter/mterp/x86/op_sput.S
+++ b/runtime/interpreter/mterp/x86/op_sput.S
@@ -1,22 +1,2 @@
-%default { "helper":"MterpSPutU32"}
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
-    /* op vAA, field@BBBB */
-    .extern $helper
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref BBBB
-    GET_VREG rINST, rINST
-    movl    rINST, OUT_ARG1(%esp)           # fp[AA]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
-    call    SYMBOL($helper)
-    testb   %al, %al
-    jnz     MterpException
-    RESTORE_IBASE
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "x86/field.S" { }
diff --git a/runtime/interpreter/mterp/x86/op_sput_object.S b/runtime/interpreter/mterp/x86/op_sput_object.S
index 941b072..4452dba 100644
--- a/runtime/interpreter/mterp/x86/op_sput_object.S
+++ b/runtime/interpreter/mterp/x86/op_sput_object.S
@@ -1,13 +1 @@
-    EXPORT_PC
-    leal    OFF_FP_SHADOWFRAME(rFP), %eax
-    movl    %eax, OUT_ARG0(%esp)
-    movl    rPC, OUT_ARG1(%esp)
-    REFRESH_INST ${opnum}
-    movl    rINST, OUT_ARG2(%esp)
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)
-    call    SYMBOL(MterpSPutObj)
-    testb   %al, %al
-    jz      MterpException
-    RESTORE_IBASE
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/x86/op_sput_wide.S b/runtime/interpreter/mterp/x86/op_sput_wide.S
index f581507..d79b068 100644
--- a/runtime/interpreter/mterp/x86/op_sput_wide.S
+++ b/runtime/interpreter/mterp/x86/op_sput_wide.S
@@ -1,20 +1 @@
-/*
- * SPUT_WIDE handler wrapper.
- *
- */
-    /* sput-wide vAA, field@BBBB */
-    .extern MterpSPutU64
-    EXPORT_PC
-    movzwl  2(rPC), %eax
-    movl    %eax, OUT_ARG0(%esp)            # field ref BBBB
-    leal    VREG_ADDRESS(rINST), %eax
-    movl    %eax, OUT_ARG1(%esp)            # &fp[AA]
-    movl    OFF_FP_METHOD(rFP), %eax
-    movl    %eax, OUT_ARG2(%esp)            # referrer
-    movl    rSELF, %ecx
-    movl    %ecx, OUT_ARG3(%esp)            # self
-    call    SYMBOL(MterpSPutU64)
-    testb   %al, %al
-    jnz     MterpException
-    RESTORE_IBASE
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/x86_64/field.S b/runtime/interpreter/mterp/x86_64/field.S
new file mode 100644
index 0000000..f8b0588
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/field.S
@@ -0,0 +1,14 @@
+%default { }
+    /*
+     * General field read / write (iget-* iput-* sget-* sput-*).
+     */
+    .extern $helper
+    REFRESH_INST ${opnum}                      # fix rINST to include opcode
+    movq    rPC, OUT_ARG0                      # arg0: Instruction* inst
+    movl    rINST, OUT_32_ARG1                 # arg1: uint16_t inst_data
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG2  # arg2: ShadowFrame* sf
+    movq    rSELF, OUT_ARG3                    # arg3: Thread* self
+    call    SYMBOL($helper)
+    testb   %al, %al
+    jz      MterpPossibleException
+    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_iget.S b/runtime/interpreter/mterp/x86_64/op_iget.S
index 5c6cab6..4ab7c27 100644
--- a/runtime/interpreter/mterp/x86_64/op_iget.S
+++ b/runtime/interpreter/mterp/x86_64/op_iget.S
@@ -1,28 +1,2 @@
-%default { "is_object":"0", "helper":"MterpIGetU32", "wide":"0"}
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
-    EXPORT_PC
-    movzbq  rINSTbl, %rcx                   # rcx <- BA
-    movzwl  2(rPC), OUT_32_ARG0             # eax <- field ref CCCC
-    sarl    $$4, %ecx                       # ecx <- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3
-    call    SYMBOL($helper)
-    movq    rSELF, %rcx
-    cmpq    $$0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException                  # bail out
-    andb    $$0xf, rINSTbl                  # rINST <- A
-    .if $is_object
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <-value
-    .else
-    .if $wide
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <-value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <-value
-    .endif
-    .endif
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpIGetU32"}
+%include "x86_64/field.S" { }
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_wide.S b/runtime/interpreter/mterp/x86_64/op_iget_wide.S
index d9d1744..a85a474 100644
--- a/runtime/interpreter/mterp/x86_64/op_iget_wide.S
+++ b/runtime/interpreter/mterp/x86_64/op_iget_wide.S
@@ -1 +1 @@
-%include "x86_64/op_iget.S" { "helper":"MterpIGetU64", "wide":"1" }
+%include "x86_64/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/x86_64/op_iput.S b/runtime/interpreter/mterp/x86_64/op_iput.S
index 12affdb..dad5af6 100644
--- a/runtime/interpreter/mterp/x86_64/op_iput.S
+++ b/runtime/interpreter/mterp/x86_64/op_iput.S
@@ -1,20 +1,2 @@
-%default { "helper":"MterpIPutU32"}
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
-    /* op vA, vB, field@CCCC */
-    .extern $helper
-    EXPORT_PC
-    movzwl  2(rPC), OUT_32_ARG0             # field ref <- 0000CCCC
-    movzbq  rINSTbl, %rcx                   # rcx<- BA
-    sarl    $$4, %ecx                       # ecx<- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    andb    $$0xf, rINSTbl                  # rINST<- A
-    GET_VREG OUT_32_ARG2, rINSTq            # fp[A]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG3    # referrer
-    call    SYMBOL($helper)
-    testb   %al, %al
-    jnz     MterpPossibleException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpIPutU32" }
+%include "x86_64/field.S" { }
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_object.S b/runtime/interpreter/mterp/x86_64/op_iput_object.S
index 22648cd..202e33f 100644
--- a/runtime/interpreter/mterp/x86_64/op_iput_object.S
+++ b/runtime/interpreter/mterp/x86_64/op_iput_object.S
@@ -1,10 +1 @@
-    EXPORT_PC
-    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
-    movq    rPC, OUT_ARG1
-    REFRESH_INST ${opnum}
-    movl    rINST, OUT_32_ARG2
-    movq    rSELF, OUT_ARG3
-    call    SYMBOL(MterpIPutObj)
-    testb   %al, %al
-    jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86_64/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_wide.S b/runtime/interpreter/mterp/x86_64/op_iput_wide.S
index 4f8c47c..db52016 100644
--- a/runtime/interpreter/mterp/x86_64/op_iput_wide.S
+++ b/runtime/interpreter/mterp/x86_64/op_iput_wide.S
@@ -1,14 +1 @@
-    /* iput-wide vA, vB, field@CCCC */
-    .extern MterpIPutU64
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref CCCC
-    movzbq  rINSTbl, %rcx                   # rcx <- BA
-    sarl    $$4, %ecx                       # ecx <- B
-    GET_VREG OUT_32_ARG1, %rcx              # the object pointer
-    andb    $$0xf, rINSTbl                  # rINST <- A
-    leaq    VREG_ADDRESS(rINSTq), OUT_ARG2  # &fp[A]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG3    # referrer
-    call    SYMBOL(MterpIPutU64)
-    testb   %al, %al
-    jnz     MterpPossibleException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86_64/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/x86_64/op_sget.S b/runtime/interpreter/mterp/x86_64/op_sget.S
index c15ac1e..21e8e64 100644
--- a/runtime/interpreter/mterp/x86_64/op_sget.S
+++ b/runtime/interpreter/mterp/x86_64/op_sget.S
@@ -1,26 +1,2 @@
-%default { "is_object":"0", "helper":"MterpSGetU32", "wide":"0" }
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
-    /* op vAA, field@BBBB */
-    .extern $helper
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref CCCC
-    movq    OFF_FP_METHOD(rFP), OUT_ARG1    # referrer
-    movq    rSELF, OUT_ARG2                 # self
-    call    SYMBOL($helper)
-    movq    rSELF, %rcx
-    cmpl    $$0, THREAD_EXCEPTION_OFFSET(%rcx)
-    jnz     MterpException
-    .if $is_object
-    SET_VREG_OBJECT %eax, rINSTq            # fp[A] <- value
-    .else
-    .if $wide
-    SET_WIDE_VREG %rax, rINSTq              # fp[A] <- value
-    .else
-    SET_VREG %eax, rINSTq                   # fp[A] <- value
-    .endif
-    .endif
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpSGetU32" }
+%include "x86_64/field.S" { }
diff --git a/runtime/interpreter/mterp/x86_64/op_sget_wide.S b/runtime/interpreter/mterp/x86_64/op_sget_wide.S
index 65ddb8a..c53c077 100644
--- a/runtime/interpreter/mterp/x86_64/op_sget_wide.S
+++ b/runtime/interpreter/mterp/x86_64/op_sget_wide.S
@@ -1 +1 @@
-%include "x86_64/op_sget.S" {"helper":"MterpSGetU64", "wide":"1"}
+%include "x86_64/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/x86_64/op_sput.S b/runtime/interpreter/mterp/x86_64/op_sput.S
index 9a33d52..7dd2498 100644
--- a/runtime/interpreter/mterp/x86_64/op_sput.S
+++ b/runtime/interpreter/mterp/x86_64/op_sput.S
@@ -1,17 +1,2 @@
-%default { "helper":"MterpSPutU32"}
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
-    /* op vAA, field@BBBB */
-    .extern $helper
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref BBBB
-    GET_VREG OUT_32_ARG1, rINSTq            # fp[AA]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3                 # self
-    call    SYMBOL($helper)
-    testb   %al, %al
-    jnz     MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "x86_64/field.S" { }
diff --git a/runtime/interpreter/mterp/x86_64/op_sput_object.S b/runtime/interpreter/mterp/x86_64/op_sput_object.S
index 8a47074..c2bd07b 100644
--- a/runtime/interpreter/mterp/x86_64/op_sput_object.S
+++ b/runtime/interpreter/mterp/x86_64/op_sput_object.S
@@ -1,10 +1 @@
-    EXPORT_PC
-    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
-    movq    rPC, OUT_ARG1
-    REFRESH_INST ${opnum}
-    movq    rINSTq, OUT_ARG2
-    movq    rSELF, OUT_ARG3
-    call    SYMBOL(MterpSPutObj)
-    testb   %al, %al
-    jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86_64/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/x86_64/op_sput_wide.S b/runtime/interpreter/mterp/x86_64/op_sput_wide.S
index 464d169..7e77072 100644
--- a/runtime/interpreter/mterp/x86_64/op_sput_wide.S
+++ b/runtime/interpreter/mterp/x86_64/op_sput_wide.S
@@ -1,15 +1 @@
-/*
- * SPUT_WIDE handler wrapper.
- *
- */
-    /* sput-wide vAA, field@BBBB */
-    .extern MterpSPutU64
-    EXPORT_PC
-    movzwq  2(rPC), OUT_ARG0                # field ref BBBB
-    leaq    VREG_ADDRESS(rINSTq), OUT_ARG1  # &fp[AA]
-    movq    OFF_FP_METHOD(rFP), OUT_ARG2    # referrer
-    movq    rSELF, OUT_ARG3                 # self
-    call    SYMBOL(MterpSPutU64)
-    testb   %al, %al
-    jnz     MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86_64/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index bd89907..40832bc 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -364,7 +364,7 @@
 template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
 inline int8_t Object::GetFieldByte(MemberOffset field_offset) {
   Verify<kVerifyFlags>();
-  return GetField<int8_t, kIsVolatile>(field_offset);
+  return GetFieldPrimitive<int8_t, kIsVolatile>(field_offset);
 }
 
 template<VerifyObjectFlags kVerifyFlags>
@@ -391,7 +391,7 @@
         kIsVolatile);
   }
   Verify<kVerifyFlags>();
-  SetField<uint8_t, kIsVolatile>(field_offset, new_value);
+  SetFieldPrimitive<uint8_t, kIsVolatile>(field_offset, new_value);
 }
 
 template<bool kTransactionActive,
@@ -407,7 +407,7 @@
                                              kIsVolatile);
   }
   Verify<kVerifyFlags>();
-  SetField<int8_t, kIsVolatile>(field_offset, new_value);
+  SetFieldPrimitive<int8_t, kIsVolatile>(field_offset, new_value);
 }
 
 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
@@ -425,13 +425,13 @@
 template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
 inline uint16_t Object::GetFieldChar(MemberOffset field_offset) {
   Verify<kVerifyFlags>();
-  return GetField<uint16_t, kIsVolatile>(field_offset);
+  return GetFieldPrimitive<uint16_t, kIsVolatile>(field_offset);
 }
 
 template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
 inline int16_t Object::GetFieldShort(MemberOffset field_offset) {
   Verify<kVerifyFlags>();
-  return GetField<int16_t, kIsVolatile>(field_offset);
+  return GetFieldPrimitive<int16_t, kIsVolatile>(field_offset);
 }
 
 template<VerifyObjectFlags kVerifyFlags>
@@ -457,7 +457,7 @@
                                              kIsVolatile);
   }
   Verify<kVerifyFlags>();
-  SetField<uint16_t, kIsVolatile>(field_offset, new_value);
+  SetFieldPrimitive<uint16_t, kIsVolatile>(field_offset, new_value);
 }
 
 template<bool kTransactionActive,
@@ -473,7 +473,7 @@
                                              kIsVolatile);
   }
   Verify<kVerifyFlags>();
-  SetField<int16_t, kIsVolatile>(field_offset, new_value);
+  SetFieldPrimitive<int16_t, kIsVolatile>(field_offset, new_value);
 }
 
 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
@@ -501,7 +501,7 @@
                                            kIsVolatile);
   }
   Verify<kVerifyFlags>();
-  SetField<int32_t, kIsVolatile>(field_offset, new_value);
+  SetFieldPrimitive<int32_t, kIsVolatile>(field_offset, new_value);
 }
 
 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
@@ -531,7 +531,7 @@
                                            kIsVolatile);
   }
   Verify<kVerifyFlags>();
-  SetField<int64_t, kIsVolatile>(field_offset, new_value);
+  SetFieldPrimitive<int64_t, kIsVolatile>(field_offset, new_value);
 }
 
 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
diff --git a/runtime/mirror/object-readbarrier-inl.h b/runtime/mirror/object-readbarrier-inl.h
index cc375bd..8689e4d 100644
--- a/runtime/mirror/object-readbarrier-inl.h
+++ b/runtime/mirror/object-readbarrier-inl.h
@@ -131,7 +131,7 @@
     UNREACHABLE();
   }
   DCHECK(kUseBakerReadBarrier);
-  LockWord lw(GetField<uint32_t, /*kIsVolatile*/false>(MonitorOffset()));
+  LockWord lw(GetFieldPrimitive<uint32_t, /*kIsVolatile*/false>(MonitorOffset()));
   uint32_t rb_state = lw.ReadBarrierState();
   DCHECK(ReadBarrier::IsValidReadBarrierState(rb_state)) << rb_state;
   return rb_state;
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index 47aded3..35946d7 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -349,11 +349,35 @@
   HeapReference<Object>* GetFieldObjectReferenceAddr(MemberOffset field_offset)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  template<typename kType, bool kIsVolatile>
+  ALWAYS_INLINE void SetFieldPrimitive(MemberOffset field_offset, kType new_value)
+      REQUIRES_SHARED(Locks::mutator_lock_) {
+    uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
+    kType* addr = reinterpret_cast<kType*>(raw_addr);
+    if (kIsVolatile) {
+      reinterpret_cast<Atomic<kType>*>(addr)->store(new_value, std::memory_order_seq_cst);
+    } else {
+      reinterpret_cast<Atomic<kType>*>(addr)->StoreJavaData(new_value);
+    }
+  }
+
+  template<typename kType, bool kIsVolatile>
+  ALWAYS_INLINE kType GetFieldPrimitive(MemberOffset field_offset)
+      REQUIRES_SHARED(Locks::mutator_lock_) {
+    const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value();
+    const kType* addr = reinterpret_cast<const kType*>(raw_addr);
+    if (kIsVolatile) {
+      return reinterpret_cast<const Atomic<kType>*>(addr)->load(std::memory_order_seq_cst);
+    } else {
+      return reinterpret_cast<const Atomic<kType>*>(addr)->LoadJavaData();
+    }
+  }
+
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kIsVolatile = false>
   ALWAYS_INLINE uint8_t GetFieldBoolean(MemberOffset field_offset)
       REQUIRES_SHARED(Locks::mutator_lock_) {
     Verify<kVerifyFlags>();
-    return GetField<uint8_t, kIsVolatile>(field_offset);
+    return GetFieldPrimitive<uint8_t, kIsVolatile>(field_offset);
   }
 
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kIsVolatile = false>
@@ -440,7 +464,7 @@
   ALWAYS_INLINE int32_t GetField32(MemberOffset field_offset)
       REQUIRES_SHARED(Locks::mutator_lock_) {
     Verify<kVerifyFlags>();
-    return GetField<int32_t, kIsVolatile>(field_offset);
+    return GetFieldPrimitive<int32_t, kIsVolatile>(field_offset);
   }
 
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -482,7 +506,7 @@
   ALWAYS_INLINE int64_t GetField64(MemberOffset field_offset)
       REQUIRES_SHARED(Locks::mutator_lock_) {
     Verify<kVerifyFlags>();
-    return GetField<int64_t, kIsVolatile>(field_offset);
+    return GetFieldPrimitive<int64_t, kIsVolatile>(field_offset);
   }
 
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -683,30 +707,6 @@
       REQUIRES_SHARED(Locks::mutator_lock_);
 
  private:
-  template<typename kSize, bool kIsVolatile>
-  ALWAYS_INLINE void SetField(MemberOffset field_offset, kSize new_value)
-      REQUIRES_SHARED(Locks::mutator_lock_) {
-    uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
-    kSize* addr = reinterpret_cast<kSize*>(raw_addr);
-    if (kIsVolatile) {
-      reinterpret_cast<Atomic<kSize>*>(addr)->store(new_value, std::memory_order_seq_cst);
-    } else {
-      reinterpret_cast<Atomic<kSize>*>(addr)->StoreJavaData(new_value);
-    }
-  }
-
-  template<typename kSize, bool kIsVolatile>
-  ALWAYS_INLINE kSize GetField(MemberOffset field_offset)
-      REQUIRES_SHARED(Locks::mutator_lock_) {
-    const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value();
-    const kSize* addr = reinterpret_cast<const kSize*>(raw_addr);
-    if (kIsVolatile) {
-      return reinterpret_cast<const Atomic<kSize>*>(addr)->load(std::memory_order_seq_cst);
-    } else {
-      return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadJavaData();
-    }
-  }
-
   // Get a field with acquire semantics.
   template<typename kSize>
   ALWAYS_INLINE kSize GetFieldAcquire(MemberOffset field_offset)