Revert^2 "Move native ABI asm out of quick_entrypoints*.S"

This reverts commit 003071c7fc8f19cefe82b4f95bffeeec88b0658c.

Reason for revert: Replace a riscv64 conditional branch with a tail
call to increase the range and fix a failing build where the branch
target is too far away.

Test: test.py --host --target
Test: lunch riscv64-trunk_staging-eng && m libart-gtest
Change-Id: I3d384242581eadbcae9b62a43c237c375c2f19ad
diff --git a/runtime/Android.bp b/runtime/Android.bp
index aaaa725..f933216 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -479,6 +479,7 @@
                 "arch/arm/jni_entrypoints_arm.S",
                 "arch/arm/memcmp16_arm.S",
                 "arch/arm/quick_entrypoints_arm.S",
+                "arch/arm/native_entrypoints_arm.S",
                 "arch/arm/quick_entrypoints_cc_arm.cc",
                 "arch/arm/thread_arm.cc",
                 "arch/arm/fault_handler_arm.cc",
@@ -493,6 +494,7 @@
                 "arch/arm64/jni_entrypoints_arm64.S",
                 "arch/arm64/memcmp16_arm64.S",
                 "arch/arm64/quick_entrypoints_arm64.S",
+                "arch/arm64/native_entrypoints_arm64.S",
                 "arch/arm64/thread_arm64.cc",
                 "monitor_pool.cc",
                 "arch/arm64/fault_handler_arm64.cc",
@@ -506,6 +508,7 @@
                 "arch/riscv64/fault_handler_riscv64.cc",
                 "arch/riscv64/jni_entrypoints_riscv64.S",
                 "arch/riscv64/quick_entrypoints_riscv64.S",
+                "arch/riscv64/native_entrypoints_riscv64.S",
                 "arch/riscv64/thread_riscv64.cc",
                 "interpreter/mterp/nterp.cc",
                 "monitor_pool.cc",
@@ -520,6 +523,7 @@
                 "arch/x86/jni_entrypoints_x86.S",
                 "arch/x86/memcmp16_x86.S",
                 "arch/x86/quick_entrypoints_x86.S",
+                "arch/x86/native_entrypoints_x86.S",
                 "arch/x86/thread_x86.cc",
                 "arch/x86/fault_handler_x86.cc",
             ],
@@ -541,6 +545,7 @@
                 "arch/x86_64/jni_entrypoints_x86_64.S",
                 "arch/x86_64/memcmp16_x86_64.S",
                 "arch/x86_64/quick_entrypoints_x86_64.S",
+                "arch/x86_64/native_entrypoints_x86_64.S",
                 "arch/x86_64/thread_x86_64.cc",
                 "monitor_pool.cc",
                 "arch/x86/fault_handler_x86.cc",
diff --git a/runtime/arch/arm/jni_entrypoints_arm.S b/runtime/arch/arm/jni_entrypoints_arm.S
index 8c80c33..8b57983 100644
--- a/runtime/arch/arm/jni_entrypoints_arm.S
+++ b/runtime/arch/arm/jni_entrypoints_arm.S
@@ -84,47 +84,6 @@
 .endm
 
     /*
-     * Jni dlsym lookup stub.
-     */
-    .extern artFindNativeMethod
-    .extern artFindNativeMethodRunnable
-ENTRY art_jni_dlsym_lookup_stub
-    push   {r0, r1, r2, r3, lr}           @ spill regs
-    .cfi_adjust_cfa_offset 20
-    .cfi_rel_offset lr, 16
-    sub    sp, #12                        @ pad stack pointer to align frame
-    .cfi_adjust_cfa_offset 12
-
-    mov    r0, rSELF                      @ pass Thread::Current()
-    // Call artFindNativeMethod() for normal native and artFindNativeMethodRunnable()
-    // for @FastNative or @CriticalNative.
-    ldr    ip, [r0, #THREAD_TOP_QUICK_FRAME_OFFSET]   // uintptr_t tagged_quick_frame
-    bic    ip, #TAGGED_JNI_SP_MASK                    // ArtMethod** sp
-    ldr    ip, [ip]                                   // ArtMethod* method
-    ldr    ip, [ip, #ART_METHOD_ACCESS_FLAGS_OFFSET]  // uint32_t access_flags
-    tst    ip, #(ACCESS_FLAGS_METHOD_IS_FAST_NATIVE | ACCESS_FLAGS_METHOD_IS_CRITICAL_NATIVE)
-    bne    .Llookup_stub_fast_or_critical_native
-    blx    artFindNativeMethod
-    b      .Llookup_stub_continue
-.Llookup_stub_fast_or_critical_native:
-    blx    artFindNativeMethodRunnable
-.Llookup_stub_continue:
-    mov    r12, r0                        @ save result in r12
-
-    add    sp, #12                        @ restore stack pointer
-    .cfi_adjust_cfa_offset -12
-    CFI_REMEMBER_STATE
-    cbz    r0, 1f                         @ is method code null?
-    pop    {r0, r1, r2, r3, lr}           @ restore regs
-    .cfi_adjust_cfa_offset -20
-    .cfi_restore lr
-    bx     r12                            @ if non-null, tail call to method's code
-1:
-    CFI_RESTORE_STATE_AND_DEF_CFA sp, 20
-    pop    {r0, r1, r2, r3, pc}           @ restore regs and return to caller to handle exception
-END art_jni_dlsym_lookup_stub
-
-    /*
      * Jni dlsym lookup stub for @CriticalNative.
      */
 ENTRY art_jni_dlsym_lookup_critical_stub
diff --git a/runtime/arch/arm/native_entrypoints_arm.S b/runtime/arch/arm/native_entrypoints_arm.S
new file mode 100644
index 0000000..1666dc8
--- /dev/null
+++ b/runtime/arch/arm/native_entrypoints_arm.S
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "asm_support_arm.S"
+#include "interpreter/cfi_asm_support.h"
+
+/*
+ * This file contains all native entrypoints that are called using the native ABI and do not
+ * transition to the quick ABI. For example: the switch interpreter (using the native ABI) directly
+ * calls ExecuteSwitchImplAsm and this code will always return back to the switch interpreter,
+ * again using the native ABI. Because of this behaviour ExecuteSwitchImplAsm should be included in
+ * this file. This is done so these native entrypoints can be compiled independently to quick
+ * entrypoints for cases when the kRuntimeISA and kRuntimeQuickCodeISA do not match.
+ *
+ * See comment on StackType (thread.h) for definitions and examples of quick ABI/code and
+ * native ABI/code.
+ */
+
+// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
+//  Argument 0: r0: The context pointer for ExecuteSwitchImpl.
+//  Argument 1: r1: Pointer to the templated ExecuteSwitchImpl to call.
+//  Argument 2: r2: The value of DEX PC (memory address of the methods bytecode).
+ENTRY ExecuteSwitchImplAsm
+    push {r4, lr}                                 // 2 words of callee saves.
+    .cfi_adjust_cfa_offset 8
+    .cfi_rel_offset r4, 0
+    .cfi_rel_offset lr, 4
+    mov r4, r2                                    // r4 = DEX PC
+    CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* r0 */, 4 /* r4 */, 0)
+    blx r1                                        // Call the wrapped method.
+    pop {r4, pc}
+END ExecuteSwitchImplAsm
+
+    /*
+     * Jni dlsym lookup stub.
+     */
+    .extern artFindNativeMethod
+    .extern artFindNativeMethodRunnable
+ENTRY art_jni_dlsym_lookup_stub
+    push   {r0, r1, r2, r3, lr}           @ spill regs
+    .cfi_adjust_cfa_offset 20
+    .cfi_rel_offset lr, 16
+    sub    sp, #12                        @ pad stack pointer to align frame
+    .cfi_adjust_cfa_offset 12
+
+    mov    r0, rSELF                      @ pass Thread::Current()
+    // Call artFindNativeMethod() for normal native and artFindNativeMethodRunnable()
+    // for @FastNative or @CriticalNative.
+    ldr    ip, [r0, #THREAD_TOP_QUICK_FRAME_OFFSET]   // uintptr_t tagged_quick_frame
+    bic    ip, #TAGGED_JNI_SP_MASK                    // ArtMethod** sp
+    ldr    ip, [ip]                                   // ArtMethod* method
+    ldr    ip, [ip, #ART_METHOD_ACCESS_FLAGS_OFFSET]  // uint32_t access_flags
+    tst    ip, #(ACCESS_FLAGS_METHOD_IS_FAST_NATIVE | ACCESS_FLAGS_METHOD_IS_CRITICAL_NATIVE)
+    bne    .Llookup_stub_fast_or_critical_native
+    blx    artFindNativeMethod
+    b      .Llookup_stub_continue
+.Llookup_stub_fast_or_critical_native:
+    blx    artFindNativeMethodRunnable
+.Llookup_stub_continue:
+    mov    r12, r0                        @ save result in r12
+
+    add    sp, #12                        @ restore stack pointer
+    .cfi_adjust_cfa_offset -12
+    CFI_REMEMBER_STATE
+    cbz    r0, 1f                         @ is method code null?
+    pop    {r0, r1, r2, r3, lr}           @ restore regs
+    .cfi_adjust_cfa_offset -20
+    .cfi_restore lr
+    bx     r12                            @ if non-null, tail call to method's code
+1:
+    CFI_RESTORE_STATE_AND_DEF_CFA sp, 20
+    pop    {r0, r1, r2, r3, pc}           @ restore regs and return to caller to handle exception
+END art_jni_dlsym_lookup_stub
+
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index 2621918..ddfe70d 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -2354,21 +2354,6 @@
     RETURN_OR_DELIVER_PENDING_EXCEPTION_REG r2
 END art_quick_invoke_custom
 
-// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
-//  Argument 0: r0: The context pointer for ExecuteSwitchImpl.
-//  Argument 1: r1: Pointer to the templated ExecuteSwitchImpl to call.
-//  Argument 2: r2: The value of DEX PC (memory address of the methods bytecode).
-ENTRY ExecuteSwitchImplAsm
-    push {r4, lr}                                 // 2 words of callee saves.
-    .cfi_adjust_cfa_offset 8
-    .cfi_rel_offset r4, 0
-    .cfi_rel_offset lr, 4
-    mov r4, r2                                    // r4 = DEX PC
-    CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* r0 */, 4 /* r4 */, 0)
-    blx r1                                        // Call the wrapped method.
-    pop {r4, pc}
-END ExecuteSwitchImplAsm
-
 // r0 contains the class, r4 contains the inline cache. We can use ip as temporary.
 ENTRY art_quick_update_inline_cache
 #if (INLINE_CACHE_SIZE != 5)
diff --git a/runtime/arch/arm64/asm_support_arm64.S b/runtime/arch/arm64/asm_support_arm64.S
index 56ce037..ae96530 100644
--- a/runtime/arch/arm64/asm_support_arm64.S
+++ b/runtime/arch/arm64/asm_support_arm64.S
@@ -152,6 +152,13 @@
     SAVE_TWO_REGS_BASE sp, \reg1, \reg2, \offset
 .endm
 
+.macro SAVE_TWO_REGS_INCREASE_FRAME reg1, reg2, frame_adjustment
+    stp \reg1, \reg2, [sp, #-(\frame_adjustment)]!
+    .cfi_adjust_cfa_offset (\frame_adjustment)
+    .cfi_rel_offset \reg1, 0
+    .cfi_rel_offset \reg2, 8
+.endm
+
 .macro RESTORE_TWO_REGS_BASE base, reg1, reg2, offset
     ldp \reg1, \reg2, [\base, #(\offset)]
     .cfi_restore \reg1
@@ -162,6 +169,40 @@
     RESTORE_TWO_REGS_BASE sp, \reg1, \reg2, \offset
 .endm
 
+.macro RESTORE_TWO_REGS_DECREASE_FRAME reg1, reg2, frame_adjustment
+    ldp \reg1, \reg2, [sp], #(\frame_adjustment)
+    .cfi_restore \reg1
+    .cfi_restore \reg2
+    .cfi_adjust_cfa_offset -(\frame_adjustment)
+.endm
+
+#define ALL_ARGS_SIZE (/*x0-x7*/ 8 * 8 + /*d0-d7*/ 8 * 8)
+
+.macro SAVE_ALL_ARGS_INCREASE_FRAME extra_space
+    // Save register args x0-x7, d0-d7 and return address.
+    stp    x0, x1, [sp, #-(ALL_ARGS_SIZE + \extra_space)]!
+    .cfi_adjust_cfa_offset (ALL_ARGS_SIZE + \extra_space)
+    stp    x2, x3, [sp, #16]
+    stp    x4, x5, [sp, #32]
+    stp    x6, x7, [sp, #48]
+    stp    d0, d1, [sp, #64]
+    stp    d2, d3, [sp, #80]
+    stp    d4, d5, [sp, #96]
+    stp    d6, d7, [sp, #112]
+.endm
+
+.macro RESTORE_ALL_ARGS_DECREASE_FRAME extra_space
+    ldp    x2, x3, [sp, #16]
+    ldp    x4, x5, [sp, #32]
+    ldp    x6, x7, [sp, #48]
+    ldp    d0, d1, [sp, #64]
+    ldp    d2, d3, [sp, #80]
+    ldp    d4, d5, [sp, #96]
+    ldp    d6, d7, [sp, #112]
+    ldp    x0, x1, [sp], #(ALL_ARGS_SIZE + \extra_space)
+    .cfi_adjust_cfa_offset -(ALL_ARGS_SIZE + \extra_space)
+.endm
+
 .macro LOAD_RUNTIME_INSTANCE reg
 #if __has_feature(hwaddress_sanitizer)
     adrp \reg, :pg_hi21_nc:_ZN3art7Runtime9instance_E
diff --git a/runtime/arch/arm64/jni_entrypoints_arm64.S b/runtime/arch/arm64/jni_entrypoints_arm64.S
index 2bfb02d..2b0a214 100644
--- a/runtime/arch/arm64/jni_entrypoints_arm64.S
+++ b/runtime/arch/arm64/jni_entrypoints_arm64.S
@@ -16,33 +16,6 @@
 
 #include "asm_support_arm64.S"
 
-#define ALL_ARGS_SIZE (/*x0-x7*/ 8 * 8 + /*d0-d7*/ 8 * 8)
-
-.macro SAVE_ALL_ARGS_INCREASE_FRAME extra_space
-    // Save register args x0-x7, d0-d7 and return address.
-    stp    x0, x1, [sp, #-(ALL_ARGS_SIZE + \extra_space)]!
-    .cfi_adjust_cfa_offset (ALL_ARGS_SIZE + \extra_space)
-    stp    x2, x3, [sp, #16]
-    stp    x4, x5, [sp, #32]
-    stp    x6, x7, [sp, #48]
-    stp    d0, d1, [sp, #64]
-    stp    d2, d3, [sp, #80]
-    stp    d4, d5, [sp, #96]
-    stp    d6, d7, [sp, #112]
-.endm
-
-.macro RESTORE_ALL_ARGS_DECREASE_FRAME extra_space
-    ldp    x2, x3, [sp, #16]
-    ldp    x4, x5, [sp, #32]
-    ldp    x6, x7, [sp, #48]
-    ldp    d0, d1, [sp, #64]
-    ldp    d2, d3, [sp, #80]
-    ldp    d4, d5, [sp, #96]
-    ldp    d6, d7, [sp, #112]
-    ldp    x0, x1, [sp], #(ALL_ARGS_SIZE + \extra_space)
-    .cfi_adjust_cfa_offset -(ALL_ARGS_SIZE + \extra_space)
-.endm
-
 .macro JNI_SAVE_MANAGED_ARGS_TRAMPOLINE name, cxx_name, arg1 = "none"
     .extern \cxx_name
 ENTRY \name
@@ -87,56 +60,17 @@
 .endm
 
     /*
-     * Jni dlsym lookup stub.
-     */
-    .extern artFindNativeMethod
-    .extern artFindNativeMethodRunnable
-ENTRY art_jni_dlsym_lookup_stub
-    // spill regs.
-    SAVE_ALL_ARGS_INCREASE_FRAME 2 * 8
-    stp   x29, x30, [sp, ALL_ARGS_SIZE]
-    .cfi_rel_offset x29, ALL_ARGS_SIZE
-    .cfi_rel_offset x30, ALL_ARGS_SIZE + 8
-    add   x29, sp, ALL_ARGS_SIZE
-
-    mov x0, xSELF   // pass Thread::Current()
-    // Call artFindNativeMethod() for normal native and artFindNativeMethodRunnable()
-    // for @FastNative or @CriticalNative.
-    ldr   xIP0, [x0, #THREAD_TOP_QUICK_FRAME_OFFSET]      // uintptr_t tagged_quick_frame
-    bic   xIP0, xIP0, #TAGGED_JNI_SP_MASK                 // ArtMethod** sp
-    ldr   xIP0, [xIP0]                                    // ArtMethod* method
-    ldr   xIP0, [xIP0, #ART_METHOD_ACCESS_FLAGS_OFFSET]   // uint32_t access_flags
-    mov   xIP1, #(ACCESS_FLAGS_METHOD_IS_FAST_NATIVE | ACCESS_FLAGS_METHOD_IS_CRITICAL_NATIVE)
-    tst   xIP0, xIP1
-    b.ne  .Llookup_stub_fast_or_critical_native
-    bl    artFindNativeMethod
-    b     .Llookup_stub_continue
-    .Llookup_stub_fast_or_critical_native:
-    bl    artFindNativeMethodRunnable
-.Llookup_stub_continue:
-    mov   x17, x0    // store result in scratch reg.
-
-    // load spill regs.
-    ldp   x29, x30, [sp, #ALL_ARGS_SIZE]
-    .cfi_restore x29
-    .cfi_restore x30
-    RESTORE_ALL_ARGS_DECREASE_FRAME 2 * 8
-
-    cbz   x17, 1f   // is method code null ?
-    br    x17       // if non-null, tail call to method's code.
-
-1:
-    ret             // restore regs and return to caller to handle exception.
-END art_jni_dlsym_lookup_stub
-
-    /*
      * Jni dlsym lookup stub for @CriticalNative.
      */
 ENTRY art_jni_dlsym_lookup_critical_stub
     // The hidden arg holding the tagged method (bit 0 set means GenericJNI) is x15.
     // For Generic JNI we already have a managed frame, so we reuse the art_jni_dlsym_lookup_stub.
-    tbnz  x15, #0, art_jni_dlsym_lookup_stub
+    // Note: 'tbnz' doesn't always have enough range (+/-32KB) to reach art_jni_dlsym_lookup_stub
+    // so 'b' (+/-128MB) is used instead.
+    tbz  x15, #0, .Lcritical_not_generic_jni
+    b art_jni_dlsym_lookup_stub
 
+.Lcritical_not_generic_jni:
     // Save args, the hidden arg and caller PC. No CFI needed for args and the hidden arg.
     SAVE_ALL_ARGS_INCREASE_FRAME 2 * 8
     stp   x15, lr, [sp, #ALL_ARGS_SIZE]
diff --git a/runtime/arch/arm64/native_entrypoints_arm64.S b/runtime/arch/arm64/native_entrypoints_arm64.S
new file mode 100644
index 0000000..747e572
--- /dev/null
+++ b/runtime/arch/arm64/native_entrypoints_arm64.S
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "asm_support_arm64.S"
+#include "interpreter/cfi_asm_support.h"
+
+/*
+ * This file contains all native entrypoints that are called using the native ABI and do not
+ * transition to the quick ABI. For example: the switch interpreter (using the native ABI) directly
+ * calls ExecuteSwitchImplAsm and this code will always return back to the switch interpreter,
+ * again using the native ABI. Because of this behaviour ExecuteSwitchImplAsm should be included in
+ * this file. This is done so these native entrypoints can be compiled independently to quick
+ * entrypoints for cases when the kRuntimeISA and kRuntimeQuickCodeISA do not match.
+ *
+ * See comment on StackType (thread.h) for definitions and examples of quick ABI/code and
+ * native ABI/code.
+ */
+
+// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
+//  Argument 0: x0: The context pointer for ExecuteSwitchImpl.
+//  Argument 1: x1: Pointer to the templated ExecuteSwitchImpl to call.
+//  Argument 2: x2: The value of DEX PC (memory address of the methods bytecode).
+ENTRY ExecuteSwitchImplAsm
+    SAVE_TWO_REGS_INCREASE_FRAME x19, xLR, 16
+    mov x19, x2                                   // x19 = DEX PC
+    CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* x0 */, 19 /* x19 */, 0)
+    blr x1                                        // Call the wrapped method.
+    RESTORE_TWO_REGS_DECREASE_FRAME x19, xLR, 16
+    ret
+END ExecuteSwitchImplAsm
+
+    /*
+     * Jni dlsym lookup stub.
+     */
+    .extern artFindNativeMethod
+    .extern artFindNativeMethodRunnable
+ENTRY art_jni_dlsym_lookup_stub
+    // spill regs.
+    SAVE_ALL_ARGS_INCREASE_FRAME 2 * 8
+    stp   x29, x30, [sp, ALL_ARGS_SIZE]
+    .cfi_rel_offset x29, ALL_ARGS_SIZE
+    .cfi_rel_offset x30, ALL_ARGS_SIZE + 8
+    add   x29, sp, ALL_ARGS_SIZE
+
+    mov x0, xSELF   // pass Thread::Current()
+    // Call artFindNativeMethod() for normal native and artFindNativeMethodRunnable()
+    // for @FastNative or @CriticalNative.
+    ldr   xIP0, [x0, #THREAD_TOP_QUICK_FRAME_OFFSET]      // uintptr_t tagged_quick_frame
+    bic   xIP0, xIP0, #TAGGED_JNI_SP_MASK                 // ArtMethod** sp
+    ldr   xIP0, [xIP0]                                    // ArtMethod* method
+    ldr   xIP0, [xIP0, #ART_METHOD_ACCESS_FLAGS_OFFSET]   // uint32_t access_flags
+    mov   xIP1, #(ACCESS_FLAGS_METHOD_IS_FAST_NATIVE | ACCESS_FLAGS_METHOD_IS_CRITICAL_NATIVE)
+    tst   xIP0, xIP1
+    b.ne  .Llookup_stub_fast_or_critical_native
+    bl    artFindNativeMethod
+    b     .Llookup_stub_continue
+    .Llookup_stub_fast_or_critical_native:
+    bl    artFindNativeMethodRunnable
+.Llookup_stub_continue:
+    mov   x17, x0    // store result in scratch reg.
+
+    // load spill regs.
+    ldp   x29, x30, [sp, #ALL_ARGS_SIZE]
+    .cfi_restore x29
+    .cfi_restore x30
+    RESTORE_ALL_ARGS_DECREASE_FRAME 2 * 8
+
+    cbz   x17, 1f   // is method code null ?
+    br    x17       // if non-null, tail call to method's code.
+
+1:
+    ret             // restore regs and return to caller to handle exception.
+END art_jni_dlsym_lookup_stub
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 3bb3b69..90ea19e 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -32,20 +32,6 @@
     .cfi_adjust_cfa_offset -(\frame_adjustment)
 .endm
 
-.macro SAVE_TWO_REGS_INCREASE_FRAME reg1, reg2, frame_adjustment
-    stp \reg1, \reg2, [sp, #-(\frame_adjustment)]!
-    .cfi_adjust_cfa_offset (\frame_adjustment)
-    .cfi_rel_offset \reg1, 0
-    .cfi_rel_offset \reg2, 8
-.endm
-
-.macro RESTORE_TWO_REGS_DECREASE_FRAME reg1, reg2, frame_adjustment
-    ldp \reg1, \reg2, [sp], #(\frame_adjustment)
-    .cfi_restore \reg1
-    .cfi_restore \reg2
-    .cfi_adjust_cfa_offset -(\frame_adjustment)
-.endm
-
 .macro POP_SAVE_REFS_ONLY_FRAME
     DECREASE_FRAME 96
 .endm
@@ -2467,19 +2453,6 @@
     RETURN_OR_DELIVER_PENDING_EXCEPTION
 END  art_quick_invoke_custom
 
-// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
-//  Argument 0: x0: The context pointer for ExecuteSwitchImpl.
-//  Argument 1: x1: Pointer to the templated ExecuteSwitchImpl to call.
-//  Argument 2: x2: The value of DEX PC (memory address of the methods bytecode).
-ENTRY ExecuteSwitchImplAsm
-    SAVE_TWO_REGS_INCREASE_FRAME x19, xLR, 16
-    mov x19, x2                                   // x19 = DEX PC
-    CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* x0 */, 19 /* x19 */, 0)
-    blr x1                                        // Call the wrapped method.
-    RESTORE_TWO_REGS_DECREASE_FRAME x19, xLR, 16
-    ret
-END ExecuteSwitchImplAsm
-
 // x0 contains the class, x8 contains the inline cache. x9-x15 can be used.
 ENTRY art_quick_update_inline_cache
 #if (INLINE_CACHE_SIZE != 5)
diff --git a/runtime/arch/riscv64/asm_support_riscv64.S b/runtime/arch/riscv64/asm_support_riscv64.S
index f8e3b48..accdb05 100644
--- a/runtime/arch/riscv64/asm_support_riscv64.S
+++ b/runtime/arch/riscv64/asm_support_riscv64.S
@@ -161,6 +161,61 @@
 .endm
 
 
+// 8 argument GPRS: a0 - a7 and 8 argument FPRs: fa0 - fa7
+#define ALL_ARGS_SIZE (8 * (8 + 8))
+
+
+.macro SAVE_ALL_ARGS_INCREASE_FRAME extra_space
+    // Reserve space for all argument registers, plus the extra space.
+    INCREASE_FRAME (ALL_ARGS_SIZE + \extra_space)
+
+    // Argument GPRs a0 - a7.
+    sd    a0, (8*0)(sp)
+    sd    a1, (8*1)(sp)
+    sd    a2, (8*2)(sp)
+    sd    a3, (8*3)(sp)
+    sd    a4, (8*4)(sp)
+    sd    a5, (8*5)(sp)
+    sd    a6, (8*6)(sp)
+    sd    a7, (8*7)(sp)
+
+    // Argument FPRs fa0 - fa7.
+    fsd   fa0, (8*8)(sp)
+    fsd   fa1, (8*9)(sp)
+    fsd   fa2, (8*10)(sp)
+    fsd   fa3, (8*11)(sp)
+    fsd   fa4, (8*12)(sp)
+    fsd   fa5, (8*13)(sp)
+    fsd   fa6, (8*14)(sp)
+    fsd   fa7, (8*15)(sp)
+.endm
+
+
+.macro RESTORE_ALL_ARGS_DECREASE_FRAME extra_space
+    // Argument GPRs a0 - a7.
+    ld    a0, (8*0)(sp)
+    ld    a1, (8*1)(sp)
+    ld    a2, (8*2)(sp)
+    ld    a3, (8*3)(sp)
+    ld    a4, (8*4)(sp)
+    ld    a5, (8*5)(sp)
+    ld    a6, (8*6)(sp)
+    ld    a7, (8*7)(sp)
+
+    // Argument FPRs fa0 - fa7.
+    fld   fa0, (8*8)(sp)
+    fld   fa1, (8*9)(sp)
+    fld   fa2, (8*10)(sp)
+    fld   fa3, (8*11)(sp)
+    fld   fa4, (8*12)(sp)
+    fld   fa5, (8*13)(sp)
+    fld   fa6, (8*14)(sp)
+    fld   fa7, (8*15)(sp)
+
+    DECREASE_FRAME (ALL_ARGS_SIZE + \extra_space)
+.endm
+
+
 .macro LOAD_RUNTIME_INSTANCE reg
 #if __has_feature(hwaddress_sanitizer)
 #error "ART does not support HWASAN on RISC-V yet"
diff --git a/runtime/arch/riscv64/jni_entrypoints_riscv64.S b/runtime/arch/riscv64/jni_entrypoints_riscv64.S
index c1f855b..2cec0b4 100644
--- a/runtime/arch/riscv64/jni_entrypoints_riscv64.S
+++ b/runtime/arch/riscv64/jni_entrypoints_riscv64.S
@@ -17,61 +17,6 @@
 #include "asm_support_riscv64.S"
 
 
-// 8 argument GPRS: a0 - a7 and 8 argument FPRs: fa0 - fa7
-#define ALL_ARGS_SIZE (8 * (8 + 8))
-
-
-.macro SAVE_ALL_ARGS_INCREASE_FRAME extra_space
-    // Reserve space for all argument registers, plus the extra space.
-    INCREASE_FRAME (ALL_ARGS_SIZE + \extra_space)
-
-    // Argument GPRs a0 - a7.
-    sd    a0, (8*0)(sp)
-    sd    a1, (8*1)(sp)
-    sd    a2, (8*2)(sp)
-    sd    a3, (8*3)(sp)
-    sd    a4, (8*4)(sp)
-    sd    a5, (8*5)(sp)
-    sd    a6, (8*6)(sp)
-    sd    a7, (8*7)(sp)
-
-    // Argument FPRs fa0 - fa7.
-    fsd   fa0, (8*8)(sp)
-    fsd   fa1, (8*9)(sp)
-    fsd   fa2, (8*10)(sp)
-    fsd   fa3, (8*11)(sp)
-    fsd   fa4, (8*12)(sp)
-    fsd   fa5, (8*13)(sp)
-    fsd   fa6, (8*14)(sp)
-    fsd   fa7, (8*15)(sp)
-.endm
-
-
-.macro RESTORE_ALL_ARGS_DECREASE_FRAME extra_space
-    // Argument GPRs a0 - a7.
-    ld    a0, (8*0)(sp)
-    ld    a1, (8*1)(sp)
-    ld    a2, (8*2)(sp)
-    ld    a3, (8*3)(sp)
-    ld    a4, (8*4)(sp)
-    ld    a5, (8*5)(sp)
-    ld    a6, (8*6)(sp)
-    ld    a7, (8*7)(sp)
-
-    // Argument FPRs fa0 - fa7.
-    fld   fa0, (8*8)(sp)
-    fld   fa1, (8*9)(sp)
-    fld   fa2, (8*10)(sp)
-    fld   fa3, (8*11)(sp)
-    fld   fa4, (8*12)(sp)
-    fld   fa5, (8*13)(sp)
-    fld   fa6, (8*14)(sp)
-    fld   fa7, (8*15)(sp)
-
-    DECREASE_FRAME (ALL_ARGS_SIZE + \extra_space)
-.endm
-
-
 .macro JNI_SAVE_MANAGED_ARGS_TRAMPOLINE name, cxx_name, arg1 = "none"
     .extern \cxx_name
 ENTRY \name
@@ -115,53 +60,18 @@
 .endm
 
 
-// JNI dlsym lookup stub.
-.extern artFindNativeMethod
-.extern artFindNativeMethodRunnable
-ENTRY art_jni_dlsym_lookup_stub
-    SAVE_ALL_ARGS_INCREASE_FRAME 2*8
-    SAVE_GPR fp, (ALL_ARGS_SIZE + 0)
-    SAVE_GPR ra, (ALL_ARGS_SIZE + 8)
-    add  fp, sp, ALL_ARGS_SIZE
-
-    // Call artFindNativeMethod for normal native.
-    // Call artFindNativeMethodRunnable for @FastNative or @CriticalNative.
-    // Both functions have a single argument: Thread::Current() in a0.
-    mv   a0, xSELF
-    ld   t0, THREAD_TOP_QUICK_FRAME_OFFSET(a0)   // uintptr_t tagged_quick_frame
-    andi t0, t0, ~TAGGED_JNI_SP_MASK             // ArtMethod** sp
-    ld   t0, (t0)                                // ArtMethod* method
-    lw   t0, ART_METHOD_ACCESS_FLAGS_OFFSET(t0)  // uint32_t access_flags
-    li   t1, (ACCESS_FLAGS_METHOD_IS_FAST_NATIVE | ACCESS_FLAGS_METHOD_IS_CRITICAL_NATIVE)
-    and  t0, t0, t1
-    bnez t0, .Llookup_stub_fast_or_critical_native
-    call artFindNativeMethod
-    j    .Llookup_stub_continue
-
-.Llookup_stub_fast_or_critical_native:
-    call  artFindNativeMethodRunnable
-
-.Llookup_stub_continue:
-    mv    t0, a0  // store result in a temp reg.
-    RESTORE_GPR fp, (ALL_ARGS_SIZE + 0)
-    RESTORE_GPR ra, (ALL_ARGS_SIZE + 8)
-    RESTORE_ALL_ARGS_DECREASE_FRAME 2*8
-
-    beqz  t0, 1f  // is method code null?
-    jr    t0      // if non-null, tail call to method code.
-1:
-    ret           // restore regs and return to caller to handle exception.
-END art_jni_dlsym_lookup_stub
-
-
 // JNI dlsym lookup stub for @CriticalNative.
 ENTRY art_jni_dlsym_lookup_critical_stub
     // The hidden arg holding the tagged method is t0 (loaded by compiled JNI stub, compiled
     // managed code, or `art_quick_generic_jni_trampoline`). Bit 0 set means generic JNI.
     // For generic JNI we already have a managed frame, so we reuse the art_jni_dlsym_lookup_stub.
+    // Note: 'bnez' doesn't always have enough range (+/-4KB) to reach art_jni_dlsym_lookup_stub so
+    // 'tail' is used instead.
     andi  t6, t0, 1
-    bnez  t6, art_jni_dlsym_lookup_stub
+    beqz  t6, .Lcritical_not_generic_jni
+    tail  art_jni_dlsym_lookup_stub
 
+.Lcritical_not_generic_jni:
     // Save args, the hidden arg and caller PC. No CFI needed for args and the hidden arg.
     SAVE_ALL_ARGS_INCREASE_FRAME 2*8
     SAVE_GPR t0, (ALL_ARGS_SIZE + 0)
diff --git a/runtime/arch/riscv64/native_entrypoints_riscv64.S b/runtime/arch/riscv64/native_entrypoints_riscv64.S
new file mode 100644
index 0000000..24c8205
--- /dev/null
+++ b/runtime/arch/riscv64/native_entrypoints_riscv64.S
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "asm_support_riscv64.S"
+#include "interpreter/cfi_asm_support.h"
+
+/*
+ * This file contains all native entrypoints that are called using the native ABI and do not
+ * transition to the quick ABI. For example: the switch interpreter (using the native ABI) directly
+ * calls ExecuteSwitchImplAsm and this code will always return back to the switch interpreter,
+ * again using the native ABI. Because of this behaviour ExecuteSwitchImplAsm should be included in
+ * this file. This is done so these native entrypoints can be compiled independently to quick
+ * entrypoints for cases when the kRuntimeISA and kRuntimeQuickCodeISA do not match.
+ *
+ * See comment on StackType (thread.h) for definitions and examples of quick ABI/code and
+ * native ABI/code.
+ */
+
+// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
+//  Argument 0: a0: The context pointer for ExecuteSwitchImpl.
+//  Argument 1: a1: Pointer to the templated ExecuteSwitchImpl to call.
+//  Argument 2: a2: The value of DEX PC (memory address of the methods bytecode).
+ENTRY ExecuteSwitchImplAsm
+    INCREASE_FRAME 16
+    SAVE_GPR s1, 0
+    SAVE_GPR ra, 8
+
+    mv s1, a2   // s1 = DEX PC
+    CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* a0 */, 9 /* s1, a.k.a. x9 */, 0)
+    jalr a1     // Call the wrapped method.
+
+    RESTORE_GPR s1, 0
+    RESTORE_GPR ra, 8
+    DECREASE_FRAME 16
+    ret
+END ExecuteSwitchImplAsm
+
+// JNI dlsym lookup stub.
+.extern artFindNativeMethod
+.extern artFindNativeMethodRunnable
+ENTRY art_jni_dlsym_lookup_stub
+    SAVE_ALL_ARGS_INCREASE_FRAME 2*8
+    SAVE_GPR fp, (ALL_ARGS_SIZE + 0)
+    SAVE_GPR ra, (ALL_ARGS_SIZE + 8)
+    add  fp, sp, ALL_ARGS_SIZE
+
+    // Call artFindNativeMethod for normal native.
+    // Call artFindNativeMethodRunnable for @FastNative or @CriticalNative.
+    // Both functions have a single argument: Thread::Current() in a0.
+    mv   a0, xSELF
+    ld   t0, THREAD_TOP_QUICK_FRAME_OFFSET(a0)   // uintptr_t tagged_quick_frame
+    andi t0, t0, ~TAGGED_JNI_SP_MASK             // ArtMethod** sp
+    ld   t0, (t0)                                // ArtMethod* method
+    lw   t0, ART_METHOD_ACCESS_FLAGS_OFFSET(t0)  // uint32_t access_flags
+    li   t1, (ACCESS_FLAGS_METHOD_IS_FAST_NATIVE | ACCESS_FLAGS_METHOD_IS_CRITICAL_NATIVE)
+    and  t0, t0, t1
+    bnez t0, .Llookup_stub_fast_or_critical_native
+    call artFindNativeMethod
+    j    .Llookup_stub_continue
+
+.Llookup_stub_fast_or_critical_native:
+    call  artFindNativeMethodRunnable
+
+.Llookup_stub_continue:
+    mv    t0, a0  // store result in a temp reg.
+    RESTORE_GPR fp, (ALL_ARGS_SIZE + 0)
+    RESTORE_GPR ra, (ALL_ARGS_SIZE + 8)
+    RESTORE_ALL_ARGS_DECREASE_FRAME 2*8
+
+    beqz  t0, 1f  // is method code null?
+    jr    t0      // if non-null, tail call to method code.
+1:
+    ret           // restore regs and return to caller to handle exception.
+END art_jni_dlsym_lookup_stub
diff --git a/runtime/arch/riscv64/quick_entrypoints_riscv64.S b/runtime/arch/riscv64/quick_entrypoints_riscv64.S
index 06b9e9b..49de49f 100644
--- a/runtime/arch/riscv64/quick_entrypoints_riscv64.S
+++ b/runtime/arch/riscv64/quick_entrypoints_riscv64.S
@@ -21,26 +21,6 @@
 #include "arch/quick_field_entrypoints.S"
 
 
-// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
-//  Argument 0: a0: The context pointer for ExecuteSwitchImpl.
-//  Argument 1: a1: Pointer to the templated ExecuteSwitchImpl to call.
-//  Argument 2: a2: The value of DEX PC (memory address of the methods bytecode).
-ENTRY ExecuteSwitchImplAsm
-    INCREASE_FRAME 16
-    SAVE_GPR s1, 0
-    SAVE_GPR ra, 8
-
-    mv s1, a2   // s1 = DEX PC
-    CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* a0 */, 9 /* s1, a.k.a. x9 */, 0)
-    jalr a1     // Call the wrapped method.
-
-    RESTORE_GPR s1, 0
-    RESTORE_GPR ra, 8
-    DECREASE_FRAME 16
-    ret
-END ExecuteSwitchImplAsm
-
-
 .macro INVOKE_STUB_CREATE_FRAME
     // Save RA, FP, xSELF (current thread), A4, A5 (they will be needed in the invoke stub return).
     INCREASE_FRAME 48
diff --git a/runtime/arch/x86/jni_entrypoints_x86.S b/runtime/arch/x86/jni_entrypoints_x86.S
index 09b4d5a..531f3c7 100644
--- a/runtime/arch/x86/jni_entrypoints_x86.S
+++ b/runtime/arch/x86/jni_entrypoints_x86.S
@@ -88,35 +88,6 @@
 END_MACRO
 
     /*
-     * Jni dlsym lookup stub.
-     */
-DEFINE_FUNCTION art_jni_dlsym_lookup_stub
-    INCREASE_FRAME 8              // Align stack.
-    pushl %fs:THREAD_SELF_OFFSET  // Pass Thread::Current().
-    CFI_ADJUST_CFA_OFFSET(4)
-    // Call artFindNativeMethod() for normal native and artFindNativeMethodRunnable()
-    // for @FastNative or @CriticalNative.
-    movl (%esp), %eax                                // Thread* self
-    movl THREAD_TOP_QUICK_FRAME_OFFSET(%eax), %eax   // uintptr_t tagged_quick_frame
-    andl LITERAL(TAGGED_JNI_SP_MASK_TOGGLED32), %eax // ArtMethod** sp
-    movl (%eax), %eax                                // ArtMethod* method
-    testl LITERAL(ACCESS_FLAGS_METHOD_IS_FAST_NATIVE | ACCESS_FLAGS_METHOD_IS_CRITICAL_NATIVE), \
-          ART_METHOD_ACCESS_FLAGS_OFFSET(%eax)
-    jne .Llookup_stub_fast_or_critical_native
-    call SYMBOL(artFindNativeMethod)  // (Thread*)
-    jmp .Llookup_stub_continue
-.Llookup_stub_fast_or_critical_native:
-    call SYMBOL(artFindNativeMethodRunnable)  // (Thread*)
-.Llookup_stub_continue:
-    DECREASE_FRAME 12             // Remove argument & padding.
-    testl %eax, %eax              // Check if returned method code is null.
-    jz .Lno_native_code_found     // If null, jump to return to handle.
-    jmp *%eax                     // Otherwise, tail call to intended method.
-.Lno_native_code_found:
-    ret
-END_FUNCTION art_jni_dlsym_lookup_stub
-
-    /*
      * Jni dlsym lookup stub for @CriticalNative.
      */
 DEFINE_FUNCTION art_jni_dlsym_lookup_critical_stub
diff --git a/runtime/arch/x86/native_entrypoints_x86.S b/runtime/arch/x86/native_entrypoints_x86.S
new file mode 100644
index 0000000..9d1c41a
--- /dev/null
+++ b/runtime/arch/x86/native_entrypoints_x86.S
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "asm_support_x86.S"
+#include "interpreter/cfi_asm_support.h"
+
+/*
+ * This file contains all native entrypoints that are called using the native ABI and do not
+ * transition to the quick ABI. For example: the switch interpreter (using the native ABI) directly
+ * calls ExecuteSwitchImplAsm and this code will always return back to the switch interpreter,
+ * again using the native ABI. Because of this behaviour ExecuteSwitchImplAsm should be included in
+ * this file. This is done so these native entrypoints can be compiled independently to quick
+ * entrypoints for cases when the kRuntimeISA and kRuntimeQuickCodeISA do not match.
+ *
+ * See comment on StackType (thread.h) for definitions and examples of quick ABI/code and
+ * native ABI/code.
+ */
+
+// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
+//  Argument 0: ESP+4: The context pointer for ExecuteSwitchImpl.
+//  Argument 1: ESP+8: Pointer to the templated ExecuteSwitchImpl to call.
+//  Argument 2: ESP+12: The value of DEX PC (memory address of the methods bytecode).
+DEFINE_FUNCTION ExecuteSwitchImplAsm
+    PUSH ebx                 // Spill EBX; Increments ESP, so arg0 is at ESP+8 now.
+    mov 12(%esp), %eax       // EAX = C++ templated interpreter function
+    mov 16(%esp), %ebx       // EBX = DEX PC (callee save register)
+    mov 8(%esp), %ecx        // ECX = Context argument for the function
+    CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* EAX */, 3 /* EBX */, 0)
+
+    sub LITERAL(4), %esp     // Alignment padding
+    CFI_ADJUST_CFA_OFFSET(4)
+    push %ecx                // Push argument
+    CFI_ADJUST_CFA_OFFSET(4)
+    call *%eax               // Call the wrapped function
+    addl LITERAL(8), %esp
+    CFI_ADJUST_CFA_OFFSET(-8)
+
+    POP ebx                  // Restore EBX
+    ret
+END_FUNCTION ExecuteSwitchImplAsm
+
+    /*
+     * Jni dlsym lookup stub.
+     */
+DEFINE_FUNCTION art_jni_dlsym_lookup_stub
+    INCREASE_FRAME 8              // Align stack.
+    pushl %fs:THREAD_SELF_OFFSET  // Pass Thread::Current().
+    CFI_ADJUST_CFA_OFFSET(4)
+    // Call artFindNativeMethod() for normal native and artFindNativeMethodRunnable()
+    // for @FastNative or @CriticalNative.
+    movl (%esp), %eax                                // Thread* self
+    movl THREAD_TOP_QUICK_FRAME_OFFSET(%eax), %eax   // uintptr_t tagged_quick_frame
+    andl LITERAL(TAGGED_JNI_SP_MASK_TOGGLED32), %eax // ArtMethod** sp
+    movl (%eax), %eax                                // ArtMethod* method
+    testl LITERAL(ACCESS_FLAGS_METHOD_IS_FAST_NATIVE | ACCESS_FLAGS_METHOD_IS_CRITICAL_NATIVE), \
+          ART_METHOD_ACCESS_FLAGS_OFFSET(%eax)
+    jne .Llookup_stub_fast_or_critical_native
+    call SYMBOL(artFindNativeMethod)  // (Thread*)
+    jmp .Llookup_stub_continue
+.Llookup_stub_fast_or_critical_native:
+    call SYMBOL(artFindNativeMethodRunnable)  // (Thread*)
+.Llookup_stub_continue:
+    DECREASE_FRAME 12             // Remove argument & padding.
+    testl %eax, %eax              // Check if returned method code is null.
+    jz .Lno_native_code_found     // If null, jump to return to handle.
+    jmp *%eax                     // Otherwise, tail call to intended method.
+.Lno_native_code_found:
+    ret
+END_FUNCTION art_jni_dlsym_lookup_stub
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index d5c186e..1078480 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -2132,29 +2132,6 @@
     RETURN_OR_DELIVER_PENDING_EXCEPTION
 END_FUNCTION art_quick_invoke_custom
 
-// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
-//  Argument 0: ESP+4: The context pointer for ExecuteSwitchImpl.
-//  Argument 1: ESP+8: Pointer to the templated ExecuteSwitchImpl to call.
-//  Argument 2: ESP+12: The value of DEX PC (memory address of the methods bytecode).
-DEFINE_FUNCTION ExecuteSwitchImplAsm
-    PUSH ebx                 // Spill EBX; Increments ESP, so arg0 is at ESP+8 now.
-    mov 12(%esp), %eax       // EAX = C++ templated interpreter function
-    mov 16(%esp), %ebx       // EBX = DEX PC (callee save register)
-    mov 8(%esp), %ecx        // ECX = Context argument for the function
-    CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* EAX */, 3 /* EBX */, 0)
-
-    sub LITERAL(4), %esp     // Alignment padding
-    CFI_ADJUST_CFA_OFFSET(4)
-    push %ecx                // Push argument
-    CFI_ADJUST_CFA_OFFSET(4)
-    call *%eax               // Call the wrapped function
-    addl LITERAL(8), %esp
-    CFI_ADJUST_CFA_OFFSET(-8)
-
-    POP ebx                  // Restore EBX
-    ret
-END_FUNCTION ExecuteSwitchImplAsm
-
 // On entry: eax is the class, ebp is the inline cache.
 DEFINE_FUNCTION art_quick_update_inline_cache
 #if (INLINE_CACHE_SIZE != 5)
diff --git a/runtime/arch/x86_64/jni_entrypoints_x86_64.S b/runtime/arch/x86_64/jni_entrypoints_x86_64.S
index a635de8..49b59bf 100644
--- a/runtime/arch/x86_64/jni_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/jni_entrypoints_x86_64.S
@@ -92,66 +92,6 @@
 END_MACRO
 
     /*
-     * Jni dlsym lookup stub.
-     */
-DEFINE_FUNCTION art_jni_dlsym_lookup_stub
-    // Save callee and GPR args.
-    PUSH_ARG r9   // Arg.
-    PUSH_ARG r8   // Arg.
-    PUSH_ARG rdi  // Arg. (JniEnv for normal and @FastNative)
-    PUSH_ARG rsi  // Arg.
-    PUSH_ARG rdx  // Arg.
-    PUSH_ARG rcx  // Arg.
-    // Create space for FPR args, plus padding for alignment
-    INCREASE_FRAME 72
-    // Save FPRs.
-    movq %xmm0, 0(%rsp)
-    movq %xmm1, 8(%rsp)
-    movq %xmm2, 16(%rsp)
-    movq %xmm3, 24(%rsp)
-    movq %xmm4, 32(%rsp)
-    movq %xmm5, 40(%rsp)
-    movq %xmm6, 48(%rsp)
-    movq %xmm7, 56(%rsp)
-    // prepare call
-    movq %gs:THREAD_SELF_OFFSET, %rdi      // RDI := Thread::Current()
-    // Call artFindNativeMethod() for normal native and artFindNativeMethodRunnable()
-    // for @FastNative or @CriticalNative.
-    movq THREAD_TOP_QUICK_FRAME_OFFSET(%rdi), %rax   // uintptr_t tagged_quick_frame
-    andq LITERAL(TAGGED_JNI_SP_MASK_TOGGLED64), %rax // ArtMethod** sp
-    movq (%rax), %rax                                // ArtMethod* method
-    testl LITERAL(ACCESS_FLAGS_METHOD_IS_FAST_NATIVE | ACCESS_FLAGS_METHOD_IS_CRITICAL_NATIVE), \
-          ART_METHOD_ACCESS_FLAGS_OFFSET(%rax)
-    jne .Llookup_stub_fast_or_critical_native
-    call SYMBOL(artFindNativeMethod)  // (Thread*)
-    jmp .Llookup_stub_continue
-.Llookup_stub_fast_or_critical_native:
-    call SYMBOL(artFindNativeMethodRunnable)  // (Thread*)
-.Llookup_stub_continue:
-    // restore arguments
-    movq 0(%rsp), %xmm0
-    movq 8(%rsp), %xmm1
-    movq 16(%rsp), %xmm2
-    movq 24(%rsp), %xmm3
-    movq 32(%rsp), %xmm4
-    movq 40(%rsp), %xmm5
-    movq 48(%rsp), %xmm6
-    movq 56(%rsp), %xmm7
-    DECREASE_FRAME 72
-    POP_ARG rcx  // Arg.
-    POP_ARG rdx  // Arg.
-    POP_ARG rsi  // Arg.
-    POP_ARG rdi  // Arg. (JniEnv for normal and @FastNative)
-    POP_ARG r8   // Arg.
-    POP_ARG r9   // Arg.
-    testq %rax, %rax              // check if returned method code is null
-    jz .Lno_native_code_found     // if null, jump to return to handle
-    jmp *%rax                     // otherwise, tail call to intended method
-.Lno_native_code_found:
-    ret
-END_FUNCTION art_jni_dlsym_lookup_stub
-
-    /*
      * Jni dlsym lookup stub for @CriticalNative.
      */
 DEFINE_FUNCTION art_jni_dlsym_lookup_critical_stub
diff --git a/runtime/arch/x86_64/native_entrypoints_x86_64.S b/runtime/arch/x86_64/native_entrypoints_x86_64.S
new file mode 100644
index 0000000..12194ef
--- /dev/null
+++ b/runtime/arch/x86_64/native_entrypoints_x86_64.S
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "asm_support_x86_64.S"
+#include "interpreter/cfi_asm_support.h"
+
+/*
+ * This file contains all native entrypoints that are called using the native ABI and do not
+ * transition to the quick ABI. For example: the switch interpreter (using the native ABI) directly
+ * calls ExecuteSwitchImplAsm and this code will always return back to the switch interpreter,
+ * again using the native ABI. Because of this behaviour ExecuteSwitchImplAsm should be included in
+ * this file. This is done so these native entrypoints can be compiled independently to quick
+ * entrypoints for cases when the kRuntimeISA and kRuntimeQuickCodeISA do not match.
+ *
+ * See comment on StackType (thread.h) for definitions and examples of quick ABI/code and
+ * native ABI/code.
+ */
+
+// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
+//  Argument 0: RDI: The context pointer for ExecuteSwitchImpl.
+//  Argument 1: RSI: Pointer to the templated ExecuteSwitchImpl to call.
+//  Argument 2: RDX: The value of DEX PC (memory address of the methods bytecode).
+DEFINE_FUNCTION ExecuteSwitchImplAsm
+    PUSH rbx                 // Spill RBX
+    movq %rdx, %rbx          // RBX = DEX PC (callee save register)
+    CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* RAX */, 3 /* RBX */, 0)
+
+    call *%rsi               // Call the wrapped function
+
+    POP rbx                  // Restore RBX
+    ret
+END_FUNCTION ExecuteSwitchImplAsm
+
+    /*
+     * Jni dlsym lookup stub.
+     */
+DEFINE_FUNCTION art_jni_dlsym_lookup_stub
+    // Save callee and GPR args.
+    PUSH_ARG r9   // Arg.
+    PUSH_ARG r8   // Arg.
+    PUSH_ARG rdi  // Arg. (JniEnv for normal and @FastNative)
+    PUSH_ARG rsi  // Arg.
+    PUSH_ARG rdx  // Arg.
+    PUSH_ARG rcx  // Arg.
+    // Create space for FPR args, plus padding for alignment
+    INCREASE_FRAME 72
+    // Save FPRs.
+    movq %xmm0, 0(%rsp)
+    movq %xmm1, 8(%rsp)
+    movq %xmm2, 16(%rsp)
+    movq %xmm3, 24(%rsp)
+    movq %xmm4, 32(%rsp)
+    movq %xmm5, 40(%rsp)
+    movq %xmm6, 48(%rsp)
+    movq %xmm7, 56(%rsp)
+    // prepare call
+    movq %gs:THREAD_SELF_OFFSET, %rdi      // RDI := Thread::Current()
+    // Call artFindNativeMethod() for normal native and artFindNativeMethodRunnable()
+    // for @FastNative or @CriticalNative.
+    movq THREAD_TOP_QUICK_FRAME_OFFSET(%rdi), %rax   // uintptr_t tagged_quick_frame
+    andq LITERAL(TAGGED_JNI_SP_MASK_TOGGLED64), %rax // ArtMethod** sp
+    movq (%rax), %rax                                // ArtMethod* method
+    testl LITERAL(ACCESS_FLAGS_METHOD_IS_FAST_NATIVE | ACCESS_FLAGS_METHOD_IS_CRITICAL_NATIVE), \
+          ART_METHOD_ACCESS_FLAGS_OFFSET(%rax)
+    jne .Llookup_stub_fast_or_critical_native
+    call SYMBOL(artFindNativeMethod)  // (Thread*)
+    jmp .Llookup_stub_continue
+.Llookup_stub_fast_or_critical_native:
+    call SYMBOL(artFindNativeMethodRunnable)  // (Thread*)
+.Llookup_stub_continue:
+    // restore arguments
+    movq 0(%rsp), %xmm0
+    movq 8(%rsp), %xmm1
+    movq 16(%rsp), %xmm2
+    movq 24(%rsp), %xmm3
+    movq 32(%rsp), %xmm4
+    movq 40(%rsp), %xmm5
+    movq 48(%rsp), %xmm6
+    movq 56(%rsp), %xmm7
+    DECREASE_FRAME 72
+    POP_ARG rcx  // Arg.
+    POP_ARG rdx  // Arg.
+    POP_ARG rsi  // Arg.
+    POP_ARG rdi  // Arg. (JniEnv for normal and @FastNative)
+    POP_ARG r8   // Arg.
+    POP_ARG r9   // Arg.
+    testq %rax, %rax              // check if returned method code is null
+    jz .Lno_native_code_found     // if null, jump to return to handle
+    jmp *%rax                     // otherwise, tail call to intended method
+.Lno_native_code_found:
+    ret
+END_FUNCTION art_jni_dlsym_lookup_stub
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index b72890d..4d00022 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -2000,21 +2000,6 @@
     RETURN_OR_DELIVER_PENDING_EXCEPTION
 END_FUNCTION art_quick_invoke_custom
 
-// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding.
-//  Argument 0: RDI: The context pointer for ExecuteSwitchImpl.
-//  Argument 1: RSI: Pointer to the templated ExecuteSwitchImpl to call.
-//  Argument 2: RDX: The value of DEX PC (memory address of the methods bytecode).
-DEFINE_FUNCTION ExecuteSwitchImplAsm
-    PUSH rbx                 // Spill RBX
-    movq %rdx, %rbx          // RBX = DEX PC (callee save register)
-    CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* RAX */, 3 /* RBX */, 0)
-
-    call *%rsi               // Call the wrapped function
-
-    POP rbx                  // Restore RBX
-    ret
-END_FUNCTION ExecuteSwitchImplAsm
-
 // On entry: edi is the class, r11 is the inline cache. r10 and rax are available.
 DEFINE_FUNCTION art_quick_update_inline_cache
 #if (INLINE_CACHE_SIZE != 5)