Fix and clean up field get/set entrypoints.

Fix `is_ref` argument for `*get_obj*` deoptimization.

Test: m test-art-host-gtest  # x86, x86-64
Test: testrunner.py --host --optimizing  # x86, x86-64
Test: testrunner.py --target --optimizing  # arm, arm64, riscv64
Bug: 283082089
Change-Id: I1f0c5e6233cb14c8b3c2149a756e8f72e84379e0
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index 5d378d3..eca5c4b 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -18,6 +18,7 @@
 #include "interpreter/cfi_asm_support.h"
 
 #include "arch/quick_alloc_entrypoints.S"
+#include "arch/quick_field_entrypoints.S"
 
     /* Deliver the given exception */
     .extern artDeliverExceptionFromCode
@@ -134,14 +135,19 @@
     .cfi_adjust_cfa_offset -52
 .endm
 
-.macro RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-    ldr r1, [rSELF, # THREAD_EXCEPTION_OFFSET]  // Get exception field.
-    cbnz r1, 1f
-    DEOPT_OR_RETURN r1                          // Check if deopt is required
+.macro RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION is_ref = 0
+    // Use R2 to allow returning 64-bit values in R0-R1.
+    ldr r2, [rSELF, # THREAD_EXCEPTION_OFFSET]  // Get exception field.
+    cbnz r2, 1f
+    DEOPT_OR_RETURN r2, \is_ref                 // Check if deopt is required
 1:
     DELIVER_PENDING_EXCEPTION
 .endm
 
+.macro RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+    RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION /* is_ref= */ 1
+.endm
+
 .macro DEOPT_OR_RETURN temp, is_ref = 0
   ldr \temp, [rSELF, #THREAD_DEOPT_CHECK_REQUIRED_OFFSET]
   cbnz \temp, 2f
@@ -214,7 +220,7 @@
 END \c_name
 .endm
 
-.macro RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+.macro RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
     cbnz   r0, 1f              @ result non-zero branch over
     DEOPT_OR_RETURN r1
 1:
@@ -223,43 +229,47 @@
 
 .macro RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER
     cbz    r0, 1f              @ result zero branch over
-    DEOPT_OR_RETURN r1, /*is_ref=*/1
+    DEOPT_OR_RETURN r1, /* is_ref= */ 1
 1:
     DELIVER_PENDING_EXCEPTION
 .endm
 
 // Macros taking opportunity of code similarities for downcalls.
-.macro  ONE_ARG_REF_DOWNCALL name, entrypoint, return
+// Used for field and allocation entrypoints.
+.macro N_ARG_DOWNCALL n, name, entrypoint, return
     .extern \entrypoint
 ENTRY \name
-    SETUP_SAVE_REFS_ONLY_FRAME r1        @ save callee saves in case of GC
-    mov    r1, rSELF                     @ pass Thread::Current
-    bl     \entrypoint                   @ (uint32_t field_idx, Thread*)
+    SETUP_SAVE_REFS_ONLY_FRAME r\n        @ save callee saves in case of GC
+    mov    r\n, rSELF                     @ pass Thread::Current
+    bl     \entrypoint                    @ (<args>, Thread*)
     RESTORE_SAVE_REFS_ONLY_FRAME
     REFRESH_MARKING_REGISTER
     \return
 END \name
 .endm
 
-.macro  TWO_ARG_REF_DOWNCALL name, entrypoint, return
-    .extern \entrypoint
-ENTRY \name
-    SETUP_SAVE_REFS_ONLY_FRAME r2        @ save callee saves in case of GC
-    mov    r2, rSELF                     @ pass Thread::Current
-    bl     \entrypoint                   @ (field_idx, Object*, Thread*)
-    RESTORE_SAVE_REFS_ONLY_FRAME
-    REFRESH_MARKING_REGISTER
-    \return
-END \name
+.macro ONE_ARG_DOWNCALL name, entrypoint, return
+    N_ARG_DOWNCALL 1, \name, \entrypoint, \return
 .endm
 
-.macro THREE_ARG_REF_DOWNCALL name, entrypoint, return
+.macro TWO_ARG_DOWNCALL name, entrypoint, return
+    N_ARG_DOWNCALL 2, \name, \entrypoint, \return
+.endm
+
+.macro THREE_ARG_DOWNCALL name, entrypoint, return
+    N_ARG_DOWNCALL 3, \name, \entrypoint, \return
+.endm
+
+// Macro to facilitate adding new allocation entrypoints.
+.macro FOUR_ARG_DOWNCALL name, entrypoint, return
     .extern \entrypoint
 ENTRY \name
-    SETUP_SAVE_REFS_ONLY_FRAME r3        @ save callee saves in case of GC
-    mov    r3, rSELF                     @ pass Thread::Current
-    bl     \entrypoint                   @ (field_idx, Object*, new_val, Thread*)
-    RESTORE_SAVE_REFS_ONLY_FRAME         @ TODO: we can clearly save an add here
+    SETUP_SAVE_REFS_ONLY_FRAME r12        @ save callee saves in case of GC
+    str    rSELF, [sp, #-16]!             @ expand the frame and pass Thread::Current
+    .cfi_adjust_cfa_offset 16
+    bl     \entrypoint                    @ (<args>, Thread*)
+    DECREASE_FRAME 16                     @ strip the extra frame
+    RESTORE_SAVE_REFS_ONLY_FRAME
     REFRESH_MARKING_REGISTER
     \return
 END \name
@@ -526,7 +536,9 @@
      * Entry from managed code that calls artHandleFillArrayDataFromCode and delivers exception on
      * failure.
      */
-TWO_ARG_REF_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+TWO_ARG_DOWNCALL art_quick_handle_fill_data, \
+                 artHandleFillArrayDataFromCode, \
+                 RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 
     /*
      * Entry from managed code that tries to lock the object in a fast path and
@@ -553,7 +565,7 @@
     bl     artLockObjectFromCode      @ (Object* obj, Thread*)
     RESTORE_SAVE_REFS_ONLY_FRAME
     REFRESH_MARKING_REGISTER
-    RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 END art_quick_lock_object_no_inline
 
     /*
@@ -583,7 +595,7 @@
     bl     artUnlockObjectFromCode    @ (Object* obj, Thread*)
     RESTORE_SAVE_REFS_ONLY_FRAME
     REFRESH_MARKING_REGISTER
-    RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 END art_quick_unlock_object_no_inline
 
     /*
@@ -804,62 +816,6 @@
 #endif  // defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER)
 END art_quick_aput_obj
 
-// Macro to facilitate adding new allocation entrypoints.
-.macro ONE_ARG_DOWNCALL name, entrypoint, return
-    .extern \entrypoint
-ENTRY \name
-    SETUP_SAVE_REFS_ONLY_FRAME r1     @ save callee saves in case of GC
-    mov    r1, rSELF                  @ pass Thread::Current
-    bl     \entrypoint     @ (uint32_t type_idx, Method* method, Thread*)
-    RESTORE_SAVE_REFS_ONLY_FRAME
-    REFRESH_MARKING_REGISTER
-    \return
-END \name
-.endm
-
-// Macro to facilitate adding new allocation entrypoints.
-.macro TWO_ARG_DOWNCALL name, entrypoint, return
-    .extern \entrypoint
-ENTRY \name
-    SETUP_SAVE_REFS_ONLY_FRAME r2     @ save callee saves in case of GC
-    mov    r2, rSELF                  @ pass Thread::Current
-    bl     \entrypoint     @ (uint32_t type_idx, Method* method, Thread*)
-    RESTORE_SAVE_REFS_ONLY_FRAME
-    REFRESH_MARKING_REGISTER
-    \return
-END \name
-.endm
-
-// Macro to facilitate adding new array allocation entrypoints.
-.macro THREE_ARG_DOWNCALL name, entrypoint, return
-    .extern \entrypoint
-ENTRY \name
-    SETUP_SAVE_REFS_ONLY_FRAME r3     @ save callee saves in case of GC
-    mov    r3, rSELF                  @ pass Thread::Current
-    @ (uint32_t type_idx, Method* method, int32_t component_count, Thread*)
-    bl     \entrypoint
-    RESTORE_SAVE_REFS_ONLY_FRAME
-    REFRESH_MARKING_REGISTER
-    \return
-END \name
-.endm
-
-// Macro to facilitate adding new allocation entrypoints.
-.macro FOUR_ARG_DOWNCALL name, entrypoint, return
-    .extern \entrypoint
-ENTRY \name
-    SETUP_SAVE_REFS_ONLY_FRAME r12    @ save callee saves in case of GC
-    str    rSELF, [sp, #-16]!         @ expand the frame and pass Thread::Current
-    .cfi_adjust_cfa_offset 16
-    bl     \entrypoint
-    add    sp, #16                    @ strip the extra frame
-    .cfi_adjust_cfa_offset -16
-    RESTORE_SAVE_REFS_ONLY_FRAME
-    REFRESH_MARKING_REGISTER
-    \return
-END \name
-.endm
-
     /*
      * Macro for resolution and initialization of indexed DEX file
      * constants such as classes and strings.
@@ -892,75 +848,13 @@
 // Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are
 // defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc.
 
-    /*
-     * Called by managed code to resolve a static field and load a non-wide value.
-     */
-ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference!
-ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-    /*
-     * Called by managed code to resolve a static field and load a 64-bit primitive value.
-     */
-    .extern artGet64StaticFromCompiledCode
-ENTRY art_quick_get64_static
-    SETUP_SAVE_REFS_ONLY_FRAME r2        @ save callee saves in case of GC
-    mov    r1, rSELF                     @ pass Thread::Current
-    bl     artGet64StaticFromCompiledCode  @ (uint32_t field_idx, Thread*)
-    ldr    r2, [rSELF, #THREAD_EXCEPTION_OFFSET]  @ load Thread::Current()->exception_
-    RESTORE_SAVE_REFS_ONLY_FRAME
-    REFRESH_MARKING_REGISTER
-    cbnz   r2, 1f                        @ success if no exception pending
-    DEOPT_OR_RETURN r2                   @ check if deopt is required or return
-1:
-    DELIVER_PENDING_EXCEPTION
-END art_quick_get64_static
+GENERATE_STATIC_FIELD_GETTERS
 
-    /*
-     * Called by managed code to resolve an instance field and load a non-wide value.
-     */
-TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference!
-TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-    /*
-     * Called by managed code to resolve an instance field and load a 64-bit primitive value.
-     */
-    .extern artGet64InstanceFromCompiledCode
-ENTRY art_quick_get64_instance
-    SETUP_SAVE_REFS_ONLY_FRAME r2        @ save callee saves in case of GC
-    mov    r2, rSELF                     @ pass Thread::Current
-    bl     artGet64InstanceFromCompiledCode  @ (field_idx, Object*, Thread*)
-    ldr    r2, [rSELF, #THREAD_EXCEPTION_OFFSET]  @ load Thread::Current()->exception_
-    RESTORE_SAVE_REFS_ONLY_FRAME
-    REFRESH_MARKING_REGISTER
-    cbnz   r2, 1f                        @ success if no exception pending
-    DEOPT_OR_RETURN r2                   @ check if deopt is required or return
-1:
-    DELIVER_PENDING_EXCEPTION
-END art_quick_get64_instance
+GENERATE_INSTANCE_FIELD_GETTERS
 
-    /*
-     * Called by managed code to resolve a static field and store a value.
-     */
-TWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
-TWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
-TWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
-TWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+GENERATE_STATIC_FIELD_SETTERS /* emit64= */ 0
 
-    /*
-     * Called by managed code to resolve an instance field and store a non-wide value.
-     */
-THREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
-THREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
-THREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
-THREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+GENERATE_INSTANCE_FIELD_SETTERS /* emit64= */ 0
 
     /*
      * Called by managed code to resolve an instance field and store a wide value.
@@ -976,7 +870,7 @@
     .cfi_adjust_cfa_offset -16
     RESTORE_SAVE_REFS_ONLY_FRAME         @ TODO: we can clearly save an add here
     REFRESH_MARKING_REGISTER
-    RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 END art_quick_set64_instance
 
     .extern artSet64StaticFromCompiledCode
@@ -990,7 +884,7 @@
     .cfi_adjust_cfa_offset -16
     RESTORE_SAVE_REFS_ONLY_FRAME          @ TODO: we can clearly save an add here
     REFRESH_MARKING_REGISTER
-    RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 END art_quick_set64_static
 
 // Generate the allocation entrypoints for each allocator.
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 34f0fdb..3c2445c 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -18,6 +18,7 @@
 #include "interpreter/cfi_asm_support.h"
 
 #include "arch/quick_alloc_entrypoints.S"
+#include "arch/quick_field_entrypoints.S"
 
 .macro SAVE_REG_INCREASE_FRAME reg, frame_adjustment
     str \reg, [sp, #-(\frame_adjustment)]!
@@ -195,14 +196,18 @@
     RESTORE_SAVE_EVERYTHING_FRAME_KEEP_X0
 .endm
 
-.macro RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+.macro RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION is_ref = 0
     ldr x1, [xSELF, # THREAD_EXCEPTION_OFFSET]  // Get exception field.
     cbnz x1, 1f
-    DEOPT_OR_RETURN x1                         // Check if deopt is required
+    DEOPT_OR_RETURN x1, \is_ref                // Check if deopt is required
 1:                                             // deliver exception on current thread
     DELIVER_PENDING_EXCEPTION
 .endm
 
+.macro RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+    RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION /* is_ref= */ 1
+.endm
+
 .macro DEOPT_OR_RETURN temp, is_ref = 0
   ldr \temp, [xSELF, #THREAD_DEOPT_CHECK_REQUIRED_OFFSET]
   cbnz \temp, 2f
@@ -240,7 +245,7 @@
 .endm
 
 
-.macro RETURN_IF_W0_IS_ZERO_OR_DELIVER
+.macro RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
     cbnz w0, 1f                // result non-zero branch over
     DEOPT_OR_RETURN x1
 1:
@@ -849,7 +854,7 @@
     bl     artLockObjectFromCode      // (Object* obj, Thread*)
     RESTORE_SAVE_REFS_ONLY_FRAME
     REFRESH_MARKING_REGISTER
-    RETURN_IF_W0_IS_ZERO_OR_DELIVER
+    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 END art_quick_lock_object_no_inline
 
     /*
@@ -874,7 +879,7 @@
     bl     artUnlockObjectFromCode    // (Object* obj, Thread*)
     RESTORE_SAVE_REFS_ONLY_FRAME
     REFRESH_MARKING_REGISTER
-    RETURN_IF_W0_IS_ZERO_OR_DELIVER
+    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 END art_quick_unlock_object_no_inline
 
     /*
@@ -1152,43 +1157,6 @@
 END \name
 .endm
 
-// Macros taking opportunity of code similarities for downcalls.
-.macro ONE_ARG_REF_DOWNCALL name, entrypoint, return
-    .extern \entrypoint
-ENTRY \name
-    SETUP_SAVE_REFS_ONLY_FRAME        // save callee saves in case of GC
-    mov    x1, xSELF                  // pass Thread::Current
-    bl     \entrypoint                // (uint32_t type_idx, Thread*)
-    RESTORE_SAVE_REFS_ONLY_FRAME
-    REFRESH_MARKING_REGISTER
-    \return
-END \name
-.endm
-
-.macro TWO_ARG_REF_DOWNCALL name, entrypoint, return
-    .extern \entrypoint
-ENTRY \name
-    SETUP_SAVE_REFS_ONLY_FRAME        // save callee saves in case of GC
-    mov    x2, xSELF                  // pass Thread::Current
-    bl     \entrypoint
-    RESTORE_SAVE_REFS_ONLY_FRAME
-    REFRESH_MARKING_REGISTER
-    \return
-END \name
-.endm
-
-.macro THREE_ARG_REF_DOWNCALL name, entrypoint, return
-    .extern \entrypoint
-ENTRY \name
-    SETUP_SAVE_REFS_ONLY_FRAME        // save callee saves in case of GC
-    mov    x3, xSELF                  // pass Thread::Current
-    bl     \entrypoint
-    RESTORE_SAVE_REFS_ONLY_FRAME
-    REFRESH_MARKING_REGISTER
-    \return
-END \name
-.endm
-
     /*
      * Macro for resolution and initialization of indexed DEX file
      * constants such as classes and strings.
@@ -1224,8 +1192,9 @@
      * Entry from managed code that calls artHandleFillArrayDataFromCode and delivers exception on
      * failure.
      */
-TWO_ARG_REF_DOWNCALL \
-        art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
+TWO_ARG_DOWNCALL art_quick_handle_fill_data, \
+                 artHandleFillArrayDataFromCode, \
+                 RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 
     /*
      * Entry from managed code when uninitialized static storage, this stub will run the class
@@ -1241,76 +1210,7 @@
 ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode
 ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode
 
-// Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are
-// defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc.
-
-ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, \
-                     artGetBooleanStaticFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, \
-                     artGetByteStaticFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get_char_static, \
-                     artGetCharStaticFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get_short_static, \
-                     artGetShortStaticFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get32_static, \
-                     artGet32StaticFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get64_static, \
-                     artGet64StaticFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference!
-ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, \
-                     artGetObjStaticFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-
-TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, \
-                     artGetBooleanInstanceFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, \
-                     artGetByteInstanceFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, \
-                     artGetCharInstanceFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, \
-                     artGetShortInstanceFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get32_instance, \
-                     artGet32InstanceFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get64_instance, \
-                     artGet64InstanceFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference!
-TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, \
-                     artGetObjInstanceFromCompiledCode, \
-                     RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-
-TWO_ARG_REF_DOWNCALL \
-    art_quick_set8_static, artSet8StaticFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
-TWO_ARG_REF_DOWNCALL \
-    art_quick_set16_static, artSet16StaticFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
-TWO_ARG_REF_DOWNCALL \
-    art_quick_set32_static, artSet32StaticFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
-TWO_ARG_REF_DOWNCALL \
-    art_quick_set64_static, artSet64StaticFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
-TWO_ARG_REF_DOWNCALL \
-    art_quick_set_obj_static, artSetObjStaticFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
-
-THREE_ARG_REF_DOWNCALL \
-    art_quick_set8_instance, artSet8InstanceFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
-THREE_ARG_REF_DOWNCALL \
-    art_quick_set16_instance, artSet16InstanceFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
-THREE_ARG_REF_DOWNCALL \
-    art_quick_set32_instance, artSet32InstanceFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
-THREE_ARG_REF_DOWNCALL \
-    art_quick_set64_instance, artSet64InstanceFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
-THREE_ARG_REF_DOWNCALL \
-    art_quick_set_obj_instance, artSetObjInstanceFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
+GENERATE_FIELD_ENTRYPOINTS
 
 // Generate the allocation entrypoints for each allocator.
 GENERATE_ALLOC_ENTRYPOINTS_FOR_NON_TLAB_ALLOCATORS
diff --git a/runtime/arch/quick_field_entrypoints.S b/runtime/arch/quick_field_entrypoints.S
new file mode 100644
index 0000000..0bea803
--- /dev/null
+++ b/runtime/arch/quick_field_entrypoints.S
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are
+// defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc.
+
+.macro GENERATE_STATIC_FIELD_GETTERS
+ONE_ARG_DOWNCALL art_quick_get_boolean_static, \
+                 artGetBooleanStaticFromCompiledCode, \
+                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_DOWNCALL art_quick_get_byte_static, \
+                 artGetByteStaticFromCompiledCode, \
+                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_DOWNCALL art_quick_get_char_static, \
+                 artGetCharStaticFromCompiledCode, \
+                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_DOWNCALL art_quick_get_short_static, \
+                 artGetShortStaticFromCompiledCode, \
+                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_DOWNCALL art_quick_get32_static, \
+                 artGet32StaticFromCompiledCode, \
+                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_DOWNCALL art_quick_get_obj_static, \
+                 artGetObjStaticFromCompiledCode, \
+                 RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_DOWNCALL art_quick_get64_static, \
+                 artGet64StaticFromCompiledCode, \
+                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+.endm
+
+.macro GENERATE_INSTANCE_FIELD_GETTERS
+TWO_ARG_DOWNCALL art_quick_get_boolean_instance, \
+                 artGetBooleanInstanceFromCompiledCode, \
+                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_DOWNCALL art_quick_get_byte_instance, \
+                 artGetByteInstanceFromCompiledCode, \
+                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_DOWNCALL art_quick_get_char_instance, \
+                 artGetCharInstanceFromCompiledCode, \
+                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_DOWNCALL art_quick_get_short_instance, \
+                 artGetShortInstanceFromCompiledCode, \
+                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_DOWNCALL art_quick_get32_instance, \
+                 artGet32InstanceFromCompiledCode, \
+                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_DOWNCALL art_quick_get_obj_instance, \
+                 artGetObjInstanceFromCompiledCode, \
+                 RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_DOWNCALL art_quick_get64_instance, \
+                 artGet64InstanceFromCompiledCode, \
+                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+.endm
+
+.macro GENERATE_STATIC_FIELD_SETTERS emit64 = 1
+TWO_ARG_DOWNCALL art_quick_set8_static, \
+                 artSet8StaticFromCompiledCode, \
+                 RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
+TWO_ARG_DOWNCALL art_quick_set16_static, \
+                 artSet16StaticFromCompiledCode, \
+                 RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
+TWO_ARG_DOWNCALL art_quick_set32_static, \
+                 artSet32StaticFromCompiledCode, \
+                 RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
+TWO_ARG_DOWNCALL art_quick_set_obj_static, \
+                 artSetObjStaticFromCompiledCode, \
+                 RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
+.if \emit64
+TWO_ARG_DOWNCALL art_quick_set64_static, \
+                 artSet64StaticFromCompiledCode, \
+                 RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
+.endif
+.endm
+
+.macro GENERATE_INSTANCE_FIELD_SETTERS emit64 = 1
+THREE_ARG_DOWNCALL art_quick_set8_instance, \
+                   artSet8InstanceFromCompiledCode, \
+                   RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
+THREE_ARG_DOWNCALL art_quick_set16_instance, \
+                   artSet16InstanceFromCompiledCode, \
+                   RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
+THREE_ARG_DOWNCALL art_quick_set32_instance, \
+                   artSet32InstanceFromCompiledCode, \
+                   RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
+THREE_ARG_DOWNCALL art_quick_set_obj_instance, \
+                   artSetObjInstanceFromCompiledCode, \
+                   RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
+.if \emit64
+THREE_ARG_DOWNCALL art_quick_set64_instance, \
+                   artSet64InstanceFromCompiledCode, \
+                   RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
+.endif
+.endm
+
+.macro GENERATE_FIELD_ENTRYPOINTS
+    GENERATE_STATIC_FIELD_GETTERS
+    GENERATE_INSTANCE_FIELD_GETTERS
+    GENERATE_STATIC_FIELD_SETTERS
+    GENERATE_INSTANCE_FIELD_SETTERS
+.endm
diff --git a/runtime/arch/riscv64/quick_entrypoints_riscv64.S b/runtime/arch/riscv64/quick_entrypoints_riscv64.S
index ad506a8..ccccb2e 100644
--- a/runtime/arch/riscv64/quick_entrypoints_riscv64.S
+++ b/runtime/arch/riscv64/quick_entrypoints_riscv64.S
@@ -18,6 +18,7 @@
 #include "interpreter/cfi_asm_support.h"
 
 #include "arch/quick_alloc_entrypoints.S"
+#include "arch/quick_field_entrypoints.S"
 
 
 // Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
@@ -561,7 +562,7 @@
 .endm
 
 
-.macro RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER
+.macro RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
     bnez  a0, 1f
     DEOPT_OR_RETURN a1
 1:
@@ -620,7 +621,7 @@
     mv    a1, xSELF                   // pass Thread::Current
     call  artLockObjectFromCode       // (Object*, Thread*)
     RESTORE_SAVE_REFS_ONLY_FRAME
-    RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER
+    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 END art_quick_lock_object_no_inline
 
 
@@ -642,7 +643,7 @@
     mv    a1, xSELF                   // pass Thread::Current
     call  artUnlockObjectFromCode     // (Object*, Thread*)
     RESTORE_SAVE_REFS_ONLY_FRAME
-    RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER
+    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 END art_quick_unlock_object_no_inline
 
 
@@ -1894,84 +1895,7 @@
                           COMPUTE_ARRAY_SIZE_64
 
 
-// Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are
-// defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc.
-
-ONE_ARG_DOWNCALL art_quick_get_boolean_static, \
-                 artGetBooleanStaticFromCompiledCode, \
-                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_DOWNCALL art_quick_get_byte_static, \
-                 artGetByteStaticFromCompiledCode, \
-                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_DOWNCALL art_quick_get_char_static, \
-                 artGetCharStaticFromCompiledCode, \
-                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_DOWNCALL art_quick_get_short_static, \
-                 artGetShortStaticFromCompiledCode, \
-                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_DOWNCALL art_quick_get32_static, \
-                 artGet32StaticFromCompiledCode, \
-                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_DOWNCALL art_quick_get64_static, \
-                 artGet64StaticFromCompiledCode, \
-                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_DOWNCALL art_quick_get_obj_static, \
-                 artGetObjStaticFromCompiledCode, \
-                 RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-
-TWO_ARG_DOWNCALL art_quick_get_boolean_instance, \
-                 artGetBooleanInstanceFromCompiledCode, \
-                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_DOWNCALL art_quick_get_byte_instance, \
-                 artGetByteInstanceFromCompiledCode, \
-                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_DOWNCALL art_quick_get_char_instance, \
-                 artGetCharInstanceFromCompiledCode, \
-                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_DOWNCALL art_quick_get_short_instance, \
-                 artGetShortInstanceFromCompiledCode, \
-                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_DOWNCALL art_quick_get32_instance, \
-                 artGet32InstanceFromCompiledCode, \
-                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_DOWNCALL art_quick_get64_instance, \
-                 artGet64InstanceFromCompiledCode, \
-                 RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_DOWNCALL art_quick_get_obj_instance, \
-                 artGetObjInstanceFromCompiledCode, \
-                 RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-
-TWO_ARG_DOWNCALL art_quick_set8_static, \
-                 artSet8StaticFromCompiledCode, \
-                 RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER
-TWO_ARG_DOWNCALL art_quick_set16_static, \
-                 artSet16StaticFromCompiledCode, \
-                 RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER
-TWO_ARG_DOWNCALL art_quick_set32_static, \
-                 artSet32StaticFromCompiledCode, \
-                 RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER
-TWO_ARG_DOWNCALL art_quick_set64_static, \
-                 artSet64StaticFromCompiledCode, \
-                 RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER
-TWO_ARG_DOWNCALL art_quick_set_obj_static, \
-                 artSetObjStaticFromCompiledCode, \
-                 RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER
-
-THREE_ARG_DOWNCALL art_quick_set8_instance, \
-                   artSet8InstanceFromCompiledCode, \
-                   RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER
-THREE_ARG_DOWNCALL art_quick_set16_instance, \
-                   artSet16InstanceFromCompiledCode, \
-                   RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER
-THREE_ARG_DOWNCALL art_quick_set32_instance, \
-                   artSet32InstanceFromCompiledCode, \
-                   RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER
-THREE_ARG_DOWNCALL art_quick_set64_instance, \
-                   artSet64InstanceFromCompiledCode, \
-                   RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER
-THREE_ARG_DOWNCALL art_quick_set_obj_instance, \
-                   artSetObjInstanceFromCompiledCode, \
-                   RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER
+GENERATE_FIELD_ENTRYPOINTS
 
 
 UNDEFINED art_quick_indexof
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index da17ed9..cfc3e42 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -18,6 +18,7 @@
 #include "interpreter/cfi_asm_support.h"
 
 #include "arch/quick_alloc_entrypoints.S"
+#include "arch/quick_field_entrypoints.S"
 
 // For x86, the CFA is esp+4, the address above the pushed return address on the stack.
 
@@ -709,53 +710,6 @@
     END_FUNCTION VAR(c_name)
 END_MACRO
 
-MACRO3(ONE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro)
-    DEFINE_FUNCTION VAR(c_name)
-    SETUP_SAVE_REFS_ONLY_FRAME ebx                    // save ref containing registers for GC
-    // Outgoing argument set up
-    INCREASE_FRAME 8                                  // alignment padding
-    pushl %fs:THREAD_SELF_OFFSET                      // pass Thread::Current()
-    CFI_ADJUST_CFA_OFFSET(4)
-    PUSH eax                                          // pass arg1
-    call CALLVAR(cxx_name)                            // cxx_name(arg1, Thread*)
-    DECREASE_FRAME 16                                 // pop arguments
-    RESTORE_SAVE_REFS_ONLY_FRAME                      // restore frame up to return address
-    CALL_MACRO(return_macro)                          // return or deliver exception
-    END_FUNCTION VAR(c_name)
-END_MACRO
-
-MACRO3(TWO_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro)
-    DEFINE_FUNCTION VAR(c_name)
-    SETUP_SAVE_REFS_ONLY_FRAME ebx                    // save ref containing registers for GC
-    // Outgoing argument set up
-    PUSH eax                                          // alignment padding
-    pushl %fs:THREAD_SELF_OFFSET                      // pass Thread::Current()
-    CFI_ADJUST_CFA_OFFSET(4)
-    PUSH ecx                                          // pass arg2
-    PUSH eax                                          // pass arg1
-    call CALLVAR(cxx_name)                            // cxx_name(arg1, arg2, referrer, Thread*)
-    DECREASE_FRAME 16                                 // pop arguments
-    RESTORE_SAVE_REFS_ONLY_FRAME                      // restore frame up to return address
-    CALL_MACRO(return_macro)                          // return or deliver exception
-    END_FUNCTION VAR(c_name)
-END_MACRO
-
-MACRO3(THREE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro)
-    DEFINE_FUNCTION VAR(c_name)
-    SETUP_SAVE_REFS_ONLY_FRAME ebx                    // save ref containing registers for GC
-    // Outgoing argument set up
-    pushl %fs:THREAD_SELF_OFFSET                      // pass Thread::Current()
-    CFI_ADJUST_CFA_OFFSET(4)
-    PUSH edx                                          // pass arg3
-    PUSH ecx                                          // pass arg2
-    PUSH eax                                          // pass arg1
-    call CALLVAR(cxx_name)                            // cxx_name(arg1, arg2, arg3, Thread*)
-    DECREASE_FRAME 16                                 // pop arguments
-    RESTORE_SAVE_REFS_ONLY_FRAME                      // restore frame up to return address
-    CALL_MACRO(return_macro)                          // return or deliver exception
-    END_FUNCTION VAR(c_name)
-END_MACRO
-
     /*
      * Macro for resolution and initialization of indexed DEX file
      * constants such as classes and strings.
@@ -790,14 +744,18 @@
     DELIVER_PENDING_EXCEPTION
 END_MACRO
 
-MACRO0(RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION)
+MACRO1(RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION, is_ref = 0)
     cmpl MACRO_LITERAL(0),%fs:THREAD_EXCEPTION_OFFSET // exception field == 0 ?
     jne 1f                                            // if exception field != 0 goto 1
-    DEOPT_OR_RETURN ebx                               // check if deopt is required
+    DEOPT_OR_RETURN ebx, \is_ref                      // check if deopt is required
 1:                                                    // deliver exception on current thread
     DELIVER_PENDING_EXCEPTION
 END_MACRO
 
+MACRO0(RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION)
+    RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION /*is_ref=*/1
+END_MACRO
+
 MACRO2(DEOPT_OR_RETURN, temp, is_ref = 0)
   cmpl LITERAL(0), %fs:THREAD_DEOPT_CHECK_REQUIRED_OFFSET
   jne 2f
@@ -840,7 +798,7 @@
 END_MACRO
 
 
-MACRO0(RETURN_IF_EAX_ZERO)
+MACRO0(RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER)
     testl %eax, %eax               // eax == 0 ?
     jnz  1f                        // if eax != 0 goto 1
     DEOPT_OR_RETURN ebx            // check if deopt is needed
@@ -1156,7 +1114,9 @@
 ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode
 ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode
 
-TWO_ARG_REF_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO
+TWO_ARG_DOWNCALL art_quick_handle_fill_data, \
+                 artHandleFillArrayDataFromCode, \
+                 RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 
     /*
      * Entry from managed code that tries to lock the object in a fast path and
@@ -1188,7 +1148,7 @@
     call SYMBOL(artLockObjectFromCode)    // artLockObjectFromCode(object, Thread*)
     DECREASE_FRAME 16                     // pop arguments
     RESTORE_SAVE_REFS_ONLY_FRAME          // restore frame up to return address
-    RETURN_IF_EAX_ZERO
+    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 END_FUNCTION art_quick_lock_object_no_inline
 
     /*
@@ -1222,7 +1182,7 @@
     call SYMBOL(artUnlockObjectFromCode)  // artUnlockObjectFromCode(object, Thread*)
     DECREASE_FRAME 16                     // pop arguments
     RESTORE_SAVE_REFS_ONLY_FRAME          // restore frame up to return address
-    RETURN_IF_EAX_ZERO
+    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 END_FUNCTION art_quick_unlock_object_no_inline
 
 DEFINE_FUNCTION art_quick_instance_of
@@ -1496,37 +1456,17 @@
     ret
 END_FUNCTION art_quick_lushr
 
-// Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are
-// defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc.
+GENERATE_STATIC_FIELD_GETTERS
 
-ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference!
-ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+GENERATE_INSTANCE_FIELD_GETTERS
 
-TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference!
-TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+GENERATE_STATIC_FIELD_SETTERS /*emit64=*/0
 
-TWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCompiledCode, RETURN_IF_EAX_ZERO
-TWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCompiledCode, RETURN_IF_EAX_ZERO
-TWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCompiledCode, RETURN_IF_EAX_ZERO
-TWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCompiledCode, RETURN_IF_EAX_ZERO
+THREE_ARG_DOWNCALL art_quick_set64_static, \
+                   artSet64StaticFromCompiledCode, \
+                   RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 
-THREE_ARG_REF_DOWNCALL art_quick_set64_static, artSet64StaticFromCompiledCode, RETURN_IF_EAX_ZERO
-THREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCompiledCode, RETURN_IF_EAX_ZERO
-THREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCompiledCode, RETURN_IF_EAX_ZERO
-THREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCompiledCode, RETURN_IF_EAX_ZERO
-THREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCompiledCode, RETURN_IF_EAX_ZERO
+GENERATE_INSTANCE_FIELD_SETTERS /*emit64=*/0
 
 // Call artSet64InstanceFromCode with 4 word size arguments.
 DEFINE_FUNCTION art_quick_set64_instance
@@ -1546,7 +1486,7 @@
     addl LITERAL(32), %esp        // pop arguments
     CFI_ADJUST_CFA_OFFSET(-32)
     RESTORE_SAVE_REFS_ONLY_FRAME  // restore frame up to return address
-    RETURN_IF_EAX_ZERO            // return or deliver exception
+    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER  // return or deliver exception
 END_FUNCTION art_quick_set64_instance
 
 DEFINE_FUNCTION art_quick_proxy_invoke_handler
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index 9a60781..7207ab8 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -18,6 +18,7 @@
 #include "interpreter/cfi_asm_support.h"
 
 #include "arch/quick_alloc_entrypoints.S"
+#include "arch/quick_field_entrypoints.S"
 
 MACRO0(ASSERT_USE_READ_BARRIER)
 #if !defined(USE_READ_BARRIER)
@@ -684,39 +685,6 @@
     END_FUNCTION VAR(c_name)
 END_MACRO
 
-MACRO3(ONE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro)
-    DEFINE_FUNCTION VAR(c_name)
-    SETUP_SAVE_REFS_ONLY_FRAME
-                                        // arg0 is in rdi
-    movq %gs:THREAD_SELF_OFFSET, %rsi   // pass Thread::Current()
-    call CALLVAR(cxx_name)              // cxx_name(arg0, Thread*)
-    RESTORE_SAVE_REFS_ONLY_FRAME        // restore frame up to return address
-    CALL_MACRO(return_macro)
-    END_FUNCTION VAR(c_name)
-END_MACRO
-
-MACRO3(TWO_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro)
-    DEFINE_FUNCTION VAR(c_name)
-    SETUP_SAVE_REFS_ONLY_FRAME
-                                        // arg0 and arg1 are in rdi/rsi
-    movq %gs:THREAD_SELF_OFFSET, %rdx   // pass Thread::Current()
-    call CALLVAR(cxx_name)              // (arg0, arg1, Thread*)
-    RESTORE_SAVE_REFS_ONLY_FRAME        // restore frame up to return address
-    CALL_MACRO(return_macro)
-    END_FUNCTION VAR(c_name)
-END_MACRO
-
-MACRO3(THREE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro)
-    DEFINE_FUNCTION VAR(c_name)
-    SETUP_SAVE_REFS_ONLY_FRAME
-                                        // arg0, arg1, and arg2 are in rdi/rsi/rdx
-    movq %gs:THREAD_SELF_OFFSET, %rcx   // pass Thread::Current()
-    call CALLVAR(cxx_name)              // cxx_name(arg0, arg1, arg2, Thread*)
-    RESTORE_SAVE_REFS_ONLY_FRAME        // restore frame up to return address
-    CALL_MACRO(return_macro)            // return or deliver exception
-    END_FUNCTION VAR(c_name)
-END_MACRO
-
     /*
      * Macro for resolution and initialization of indexed DEX file
      * constants such as classes and strings.
@@ -749,15 +717,19 @@
 END_MACRO
 
 
-MACRO0(RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION)
+MACRO1(RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION, is_ref = 0)
     movq %gs:THREAD_EXCEPTION_OFFSET, %rcx // get exception field
     testq %rcx, %rcx               // rcx == 0 ?
     jnz 1f                         // if rcx != 0 goto 1
-    DEOPT_OR_RETURN                // Check if deopt is required
+    DEOPT_OR_RETURN \is_ref        // Check if deopt is required
 1:                                 // deliver exception on current thread
     DELIVER_PENDING_EXCEPTION
 END_MACRO
 
+MACRO0(RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION)
+    RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION /*is_ref=*/1
+END_MACRO
+
 MACRO1(DEOPT_OR_RETURN, is_ref = 0)
   cmpl LITERAL(0), %gs:THREAD_DEOPT_CHECK_REQUIRED_OFFSET
   jne 2f
@@ -793,7 +765,7 @@
 
 
 
-MACRO0(RETURN_IF_EAX_ZERO)
+MACRO0(RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER)
     testl %eax, %eax               // eax == 0 ?
     jnz  1f                        // if eax != 0 goto 1
     DEOPT_OR_RETURN                // Check if we need a deopt
@@ -1103,7 +1075,9 @@
 ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode
 ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode
 
-TWO_ARG_REF_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO
+TWO_ARG_DOWNCALL art_quick_handle_fill_data, \
+                 artHandleFillArrayDataFromCode, \
+                 RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 
     /*
      * Entry from managed code that tries to lock the object in a fast path and
@@ -1126,7 +1100,7 @@
     movq %gs:THREAD_SELF_OFFSET, %rsi     // pass Thread::Current()
     call SYMBOL(artLockObjectFromCode)    // artLockObjectFromCode(object, Thread*)
     RESTORE_SAVE_REFS_ONLY_FRAME          // restore frame up to return address
-    RETURN_IF_EAX_ZERO
+    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 END_FUNCTION art_quick_lock_object_no_inline
 
     /*
@@ -1151,7 +1125,7 @@
     movq %gs:THREAD_SELF_OFFSET, %rsi     // pass Thread::Current()
     call SYMBOL(artUnlockObjectFromCode)  // artUnlockObjectFromCode(object, Thread*)
     RESTORE_SAVE_REFS_ONLY_FRAME          // restore frame up to return address
-    RETURN_IF_EAX_ZERO
+    RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
 END_FUNCTION art_quick_unlock_object_no_inline
 
 DEFINE_FUNCTION art_quick_check_instance_of
@@ -1304,38 +1278,7 @@
 UNIMPLEMENTED art_quick_lshr
 UNIMPLEMENTED art_quick_lushr
 
-// Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are
-// defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc.
-
-THREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCompiledCode, RETURN_IF_EAX_ZERO
-THREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCompiledCode, RETURN_IF_EAX_ZERO
-THREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCompiledCode, RETURN_IF_EAX_ZERO
-THREE_ARG_REF_DOWNCALL art_quick_set64_instance, artSet64InstanceFromCompiledCode, RETURN_IF_EAX_ZERO
-THREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCompiledCode, RETURN_IF_EAX_ZERO
-
-TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference!
-TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-
-TWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCompiledCode, RETURN_IF_EAX_ZERO
-TWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCompiledCode, RETURN_IF_EAX_ZERO
-TWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCompiledCode, RETURN_IF_EAX_ZERO
-TWO_ARG_REF_DOWNCALL art_quick_set64_static, artSet64StaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-TWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCompiledCode, RETURN_IF_EAX_ZERO
-
-ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-ONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
-// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference!
-ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION
+GENERATE_FIELD_ENTRYPOINTS
 
 DEFINE_FUNCTION art_quick_proxy_invoke_handler
     SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_RDI