10f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes/*
20f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Copyright (C) 2012 The Android Open Source Project
30f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes *
40f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
50f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * you may not use this file except in compliance with the License.
60f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * You may obtain a copy of the License at
70f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes *
80f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
90f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes *
100f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Unless required by applicable law or agreed to in writing, software
110f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
120f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * See the License for the specific language governing permissions and
140f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * limitations under the License.
150f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes */
160f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes
177655f29fabc0a12765de828914a18314382e5a35Ian Rogers#include "asm_support_arm.S"
189651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers
197410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier#include "arch/quick_alloc_entrypoints.S"
207410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier
21ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    /* Deliver the given exception */
22ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    .extern artDeliverExceptionFromCode
23ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    /* Deliver an exception pending on a thread */
24ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    .extern artDeliverPendingException
25ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers
264f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    /*
274f0d07c783afef89703dce32c94440fc8621a29bIan Rogers     * Macro that sets up the callee save frame to conform with
284f0d07c783afef89703dce32c94440fc8621a29bIan Rogers     * Runtime::CreateCalleeSaveMethod(kSaveAll)
294f0d07c783afef89703dce32c94440fc8621a29bIan Rogers     */
301d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers.macro SETUP_SAVE_ALL_CALLEE_SAVE_FRAME rTemp1, rTemp2
311d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    push {r4-r11, lr}                             @ 9 words (36 bytes) of callee saves.
329329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset 36
339329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r4, 0
349329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r5, 4
359329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r6, 8
369329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r7, 12
379329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r8, 16
389329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r9, 20
399329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r10, 24
409329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r11, 28
419329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset lr, 32
425667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vpush {s16-s31}                               @ 16 words (64 bytes) of floats.
435667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset 64
445667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    sub sp, #12                                   @ 3 words of space, bottom word will hold Method*
459329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset 12
461d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RUNTIME_CURRENT1 \rTemp1, \rTemp2             @ Load Runtime::Current into rTemp1.
471d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    THIS_LOAD_REQUIRES_READ_BARRIER
481d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr \rTemp1, [\rTemp1, #RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET] @ rTemp1 is kSaveAll Method*.
491d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str \rTemp1, [sp, #0]                         @ Place Method* at bottom of stack.
501d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str sp, [r9, #THREAD_TOP_QUICK_FRAME_OFFSET]  @ Place sp in Thread::Current()->top_quick_frame.
515c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe
525c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe     // Ugly compile-time check, but we only have the preprocessor.
535667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 36 + 64 + 12)
545c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#error "SAVE_ALL_CALLEE_SAVE_FRAME(ARM) size not as expected."
555c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif
564f0d07c783afef89703dce32c94440fc8621a29bIan Rogers.endm
574f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
584f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    /*
594f0d07c783afef89703dce32c94440fc8621a29bIan Rogers     * Macro that sets up the callee save frame to conform with
601984152ac92aad244ae15184d12f9ceade686b7bMathieu Chartier     * Runtime::CreateCalleeSaveMethod(kRefsOnly).
614f0d07c783afef89703dce32c94440fc8621a29bIan Rogers     */
621d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers.macro SETUP_REFS_ONLY_CALLEE_SAVE_FRAME rTemp1, rTemp2
631d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    push {r5-r8, r10-r11, lr}                     @ 7 words of callee saves
649329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset 28
659329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r5, 0
669329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r6, 4
679329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r7, 8
689329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r8, 12
699329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r10, 16
709329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r11, 20
719329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset lr, 24
721d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    sub sp, #4                                    @ bottom word will hold Method*
739329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset 4
741d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RUNTIME_CURRENT2 \rTemp1, \rTemp2             @ Load Runtime::Current into rTemp1.
751d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    THIS_LOAD_REQUIRES_READ_BARRIER
761d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr \rTemp1, [\rTemp1, #RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET] @ rTemp1 is kRefsOnly Method*.
771d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str \rTemp1, [sp, #0]                         @ Place Method* at bottom of stack.
781d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str sp, [r9, #THREAD_TOP_QUICK_FRAME_OFFSET]  @ Place sp in Thread::Current()->top_quick_frame.
795c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe
805c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe    // Ugly compile-time check, but we only have the preprocessor.
815c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 28 + 4)
825c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#error "REFS_ONLY_CALLEE_SAVE_FRAME(ARM) size not as expected."
835c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif
844f0d07c783afef89703dce32c94440fc8621a29bIan Rogers.endm
854f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
861d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers.macro RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
872a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier    add sp, #4               @ bottom word holds Method*
88d0a0b3e189e6f46d410d61dab4d0cce113be41d5Christopher Ferris    .cfi_adjust_cfa_offset -4
892a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier    pop {r5-r8, r10-r11, lr} @ 7 words of callee saves
90bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r5
91bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r6
92bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r7
93bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r8
94bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r10
95bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r11
96d0a0b3e189e6f46d410d61dab4d0cce113be41d5Christopher Ferris    .cfi_restore lr
97d0a0b3e189e6f46d410d61dab4d0cce113be41d5Christopher Ferris    .cfi_adjust_cfa_offset -28
984f0d07c783afef89703dce32c94440fc8621a29bIan Rogers.endm
994f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
1001d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers.macro RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME_AND_RETURN
1015667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
1022a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier    bx  lr                   @ return
1034f0d07c783afef89703dce32c94440fc8621a29bIan Rogers.endm
1044f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
1054f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    /*
1064f0d07c783afef89703dce32c94440fc8621a29bIan Rogers     * Macro that sets up the callee save frame to conform with
1071984152ac92aad244ae15184d12f9ceade686b7bMathieu Chartier     * Runtime::CreateCalleeSaveMethod(kRefsAndArgs).
1084f0d07c783afef89703dce32c94440fc8621a29bIan Rogers     */
1095667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu.macro SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_REGISTERS_ONLY
1105667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    push {r1-r3, r5-r8, r10-r11, lr}   @ 10 words of callee saves and args.
1115667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset 40
1125d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset r1, 0
1135d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset r2, 4
1145d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset r3, 8
1155d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset r5, 12
1165d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset r6, 16
1175d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset r7, 20
1185d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset r8, 24
1195d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset r10, 28
1205d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset r11, 32
1215d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset lr, 36
1225667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vpush {s0-s15}                     @ 16 words of float args.
1235667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset 64
1241d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    sub sp, #8                         @ 2 words of space, bottom word will hold Method*
1259329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset 8
1265667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    // Ugly compile-time check, but we only have the preprocessor.
1275667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu#if (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE != 40 + 64 + 8)
1285667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu#error "REFS_AND_ARGS_CALLEE_SAVE_FRAME(ARM) size not as expected."
1295667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu#endif
1305667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu.endm
1315667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
1325667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu.macro SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME rTemp1, rTemp2
1335667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_REGISTERS_ONLY
1341d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RUNTIME_CURRENT3 \rTemp1, \rTemp2  @ Load Runtime::Current into rTemp1.
1351d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    THIS_LOAD_REQUIRES_READ_BARRIER
1361d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers     @ rTemp1 is kRefsAndArgs Method*.
1371d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr \rTemp1, [\rTemp1, #RUNTIME_REFS_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET]
1381d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str \rTemp1, [sp, #0]                         @ Place Method* at bottom of stack.
1391d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str sp, [r9, #THREAD_TOP_QUICK_FRAME_OFFSET]  @ Place sp in Thread::Current()->top_quick_frame.
1404f0d07c783afef89703dce32c94440fc8621a29bIan Rogers.endm
1414f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
1421d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers.macro SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_R0
1435667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_REGISTERS_ONLY
1441d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str r0, [sp, #0]                   @ Store ArtMethod* to bottom of stack.
1451d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str sp, [r9, #THREAD_TOP_QUICK_FRAME_OFFSET]  @ Place sp in Thread::Current()->top_quick_frame.
1461d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers.endm
1471d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers
1481d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers.macro RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
1492a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier    add  sp, #8                      @ rewind sp
1505667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset -8
1515667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vpop {s0-s15}
1525667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset -64
1532a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier    pop {r1-r3, r5-r8, r10-r11, lr}  @ 10 words of callee saves
154bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r1
155bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r2
156bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r3
157bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r5
158bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r6
159bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r7
160bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r8
161bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r10
162bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r11
163d0a0b3e189e6f46d410d61dab4d0cce113be41d5Christopher Ferris    .cfi_restore lr
1645667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset -40
16515fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers.endm
16615fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers
1671d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers
168637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers.macro RETURN_IF_RESULT_IS_ZERO
169637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    cbnz   r0, 1f              @ result non-zero branch over
170637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    bx     lr                  @ return
171637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers1:
172637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers.endm
173637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers
174637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers.macro RETURN_IF_RESULT_IS_NON_ZERO
175637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    cbz    r0, 1f              @ result zero branch over
176637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    bx     lr                  @ return
177637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers1:
178637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers.endm
179637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers
180ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    /*
181ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers     * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending
182ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers     * exception is Thread::Current()->exception_
183ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers     */
184ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers.macro DELIVER_PENDING_EXCEPTION
1859329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .fnend
1869329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .fnstart
1871d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_SAVE_ALL_CALLEE_SAVE_FRAME r0, r1    @ save callee saves for throw
188ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    mov    r0, r9                              @ pass Thread::Current
1891d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    b      artDeliverPendingExceptionFromCode  @ artDeliverPendingExceptionFromCode(Thread*)
190ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers.endm
191ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers
19257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers.macro NO_ARG_RUNTIME_EXCEPTION c_name, cxx_name
19357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    .extern \cxx_name
1949329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersENTRY \c_name
1951d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_SAVE_ALL_CALLEE_SAVE_FRAME  r0, r1 // save all registers as basis for long jump context
19657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    mov r0, r9                      @ pass Thread::Current
1971d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    b   \cxx_name                   @ \cxx_name(Thread*)
1989329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND \c_name
19957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers.endm
20057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
20157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers.macro ONE_ARG_RUNTIME_EXCEPTION c_name, cxx_name
20257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    .extern \cxx_name
2039329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersENTRY \c_name
2041d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_SAVE_ALL_CALLEE_SAVE_FRAME r1, r2  // save all registers as basis for long jump context
20557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    mov r1, r9                      @ pass Thread::Current
2061d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    b   \cxx_name                   @ \cxx_name(Thread*)
2079329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND \c_name
20857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers.endm
20957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
21057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers.macro TWO_ARG_RUNTIME_EXCEPTION c_name, cxx_name
21157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    .extern \cxx_name
2129329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersENTRY \c_name
2131d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_SAVE_ALL_CALLEE_SAVE_FRAME  r2, r3  // save all registers as basis for long jump context
21457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    mov r2, r9                      @ pass Thread::Current
2151d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    b   \cxx_name                   @ \cxx_name(Thread*)
2169329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND \c_name
21757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers.endm
21857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
21937f05ef45e0393de812d51261dc293240c17294dFred Shih.macro  RETURN_OR_DELIVER_PENDING_EXCEPTION_REG reg
22037f05ef45e0393de812d51261dc293240c17294dFred Shih    ldr \reg, [r9, #THREAD_EXCEPTION_OFFSET]   // Get exception field.
22137f05ef45e0393de812d51261dc293240c17294dFred Shih    cbnz \reg, 1f
22237f05ef45e0393de812d51261dc293240c17294dFred Shih    bx lr
22337f05ef45e0393de812d51261dc293240c17294dFred Shih1:
22437f05ef45e0393de812d51261dc293240c17294dFred Shih    DELIVER_PENDING_EXCEPTION
22537f05ef45e0393de812d51261dc293240c17294dFred Shih.endm
22637f05ef45e0393de812d51261dc293240c17294dFred Shih
22737f05ef45e0393de812d51261dc293240c17294dFred Shih.macro  RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
22837f05ef45e0393de812d51261dc293240c17294dFred Shih    RETURN_OR_DELIVER_PENDING_EXCEPTION_REG r1
22937f05ef45e0393de812d51261dc293240c17294dFred Shih.endm
23037f05ef45e0393de812d51261dc293240c17294dFred Shih
23137f05ef45e0393de812d51261dc293240c17294dFred Shih.macro RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
23237f05ef45e0393de812d51261dc293240c17294dFred Shih    RETURN_IF_RESULT_IS_ZERO
23337f05ef45e0393de812d51261dc293240c17294dFred Shih    DELIVER_PENDING_EXCEPTION
23437f05ef45e0393de812d51261dc293240c17294dFred Shih.endm
23537f05ef45e0393de812d51261dc293240c17294dFred Shih
2361cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe.macro RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
2371cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    RETURN_IF_RESULT_IS_NON_ZERO
2381cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    DELIVER_PENDING_EXCEPTION
2391cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe.endm
2401cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe
24137f05ef45e0393de812d51261dc293240c17294dFred Shih// Macros taking opportunity of code similarities for downcalls with referrer for non-wide fields.
24237f05ef45e0393de812d51261dc293240c17294dFred Shih.macro  ONE_ARG_REF_DOWNCALL name, entrypoint, return
24337f05ef45e0393de812d51261dc293240c17294dFred Shih    .extern \entrypoint
24437f05ef45e0393de812d51261dc293240c17294dFred ShihENTRY \name
2451d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME r1, r2  @ save callee saves in case of GC
2461d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr    r1, [sp, #FRAME_SIZE_REFS_ONLY_CALLEE_SAVE]  @ pass referrer
24737f05ef45e0393de812d51261dc293240c17294dFred Shih    mov    r2, r9                        @ pass Thread::Current
2481d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    bl     \entrypoint                   @ (uint32_t field_idx, const Method* referrer, Thread*)
2491d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
25037f05ef45e0393de812d51261dc293240c17294dFred Shih    \return
25137f05ef45e0393de812d51261dc293240c17294dFred ShihEND \name
25237f05ef45e0393de812d51261dc293240c17294dFred Shih.endm
25337f05ef45e0393de812d51261dc293240c17294dFred Shih
25437f05ef45e0393de812d51261dc293240c17294dFred Shih.macro  TWO_ARG_REF_DOWNCALL name, entrypoint, return
25537f05ef45e0393de812d51261dc293240c17294dFred Shih    .extern \entrypoint
25637f05ef45e0393de812d51261dc293240c17294dFred ShihENTRY \name
2571d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME r2, r3  @ save callee saves in case of GC
2581d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr    r2, [sp, #FRAME_SIZE_REFS_ONLY_CALLEE_SAVE]  @ pass referrer
25937f05ef45e0393de812d51261dc293240c17294dFred Shih    mov    r3, r9                        @ pass Thread::Current
2601d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    bl     \entrypoint                   @ (field_idx, Object*, referrer, Thread*)
2611d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
26237f05ef45e0393de812d51261dc293240c17294dFred Shih    \return
26337f05ef45e0393de812d51261dc293240c17294dFred ShihEND \name
26437f05ef45e0393de812d51261dc293240c17294dFred Shih.endm
26537f05ef45e0393de812d51261dc293240c17294dFred Shih
2661cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe.macro THREE_ARG_REF_DOWNCALL name, entrypoint, return
26737f05ef45e0393de812d51261dc293240c17294dFred Shih    .extern \entrypoint
26837f05ef45e0393de812d51261dc293240c17294dFred ShihENTRY \name
2691d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME r3, r12  @ save callee saves in case of GC
2701d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr    r3, [sp, #FRAME_SIZE_REFS_ONLY_CALLEE_SAVE]  @ pass referrer
2711d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str    r9, [sp, #-16]!               @ expand the frame and pass Thread::Current
2721d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    .cfi_adjust_cfa_offset 16
2731d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    bl     \entrypoint                   @ (field_idx, Object*, new_val, referrer, Thread*)
27437f05ef45e0393de812d51261dc293240c17294dFred Shih    add    sp, #16                       @ release out args
27537f05ef45e0393de812d51261dc293240c17294dFred Shih    .cfi_adjust_cfa_offset -16
2761d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME   @ TODO: we can clearly save an add here
27737f05ef45e0393de812d51261dc293240c17294dFred Shih    \return
27837f05ef45e0393de812d51261dc293240c17294dFred ShihEND \name
27937f05ef45e0393de812d51261dc293240c17294dFred Shih.endm
28037f05ef45e0393de812d51261dc293240c17294dFred Shih
28144b412bb795fa6999129b2bc16f5eec1ea97e8f8buzbee    /*
28257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code, saves callee saves and then calls artThrowException
28357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception.
28444b412bb795fa6999129b2bc16f5eec1ea97e8f8buzbee     */
285468532ea115657709bc32ee498e701a4c71762d4Ian RogersONE_ARG_RUNTIME_EXCEPTION art_quick_deliver_exception, artDeliverExceptionFromCode
28644b412bb795fa6999129b2bc16f5eec1ea97e8f8buzbee
2876f495f2898a418f87e2a919e04fe23521bb0b9e9Brian Carlstrom    /*
28857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code to create and deliver a NullPointerException.
2896f495f2898a418f87e2a919e04fe23521bb0b9e9Brian Carlstrom     */
290468532ea115657709bc32ee498e701a4c71762d4Ian RogersNO_ARG_RUNTIME_EXCEPTION art_quick_throw_null_pointer_exception, artThrowNullPointerExceptionFromCode
2916f495f2898a418f87e2a919e04fe23521bb0b9e9Brian Carlstrom
292bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    /*
29357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code to create and deliver an ArithmeticException.
294bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers     */
295468532ea115657709bc32ee498e701a4c71762d4Ian RogersNO_ARG_RUNTIME_EXCEPTION art_quick_throw_div_zero, artThrowDivZeroFromCode
2969651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers
2979651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers    /*
29857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds
29957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * index, arg2 holds limit.
3009651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers     */
301468532ea115657709bc32ee498e701a4c71762d4Ian RogersTWO_ARG_RUNTIME_EXCEPTION art_quick_throw_array_bounds, artThrowArrayBoundsFromCode
3029651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers
3039651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers    /*
30457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code to create and deliver a StackOverflowError.
3059651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers     */
306468532ea115657709bc32ee498e701a4c71762d4Ian RogersNO_ARG_RUNTIME_EXCEPTION art_quick_throw_stack_overflow, artThrowStackOverflowFromCode
3079651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers
3089651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers    /*
30957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code to create and deliver a NoSuchMethodError.
3109651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers     */
311468532ea115657709bc32ee498e701a4c71762d4Ian RogersONE_ARG_RUNTIME_EXCEPTION art_quick_throw_no_such_method, artThrowNoSuchMethodFromCode
31257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
31357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    /*
314c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers     * All generated callsites for interface invokes and invocation slow paths will load arguments
315c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers     * as usual - except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain
316c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers     * the method_idx.  This wrapper will save arg1-arg3, load the caller's Method*, align the
317c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers     * stack and call the appropriate C helper.
318634eb2eb14f87753519d0ef2c5f256e55888f378Elliott Hughes     * NOTE: "this" is first visible argument of the target, and so can be found in arg1/r1.
3194a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee     *
320c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers     * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting
321c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers     * of the target Method* in r0 and method->code_ in r1.
3224a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee     *
3232cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier     * If unsuccessful, the helper will return null/null. There will bea pending exception in the
324c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers     * thread and we branch to another stub to deliver it.
3254a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee     *
326ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers     * On success this wrapper will restore arguments and *jump* to the target, leaving the lr
327ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers     * pointing back to the original caller.
3284a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee     */
329c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers.macro INVOKE_TRAMPOLINE c_name, cxx_name
330c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    .extern \cxx_name
3319329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersENTRY \c_name
3321d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME r2, r3  @ save callee saves in case allocation triggers GC
3331d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr    r2, [sp, #FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE]  @ pass caller Method*
334c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    mov    r3, r9                         @ pass Thread::Current
335865e6e01486e3d7d61b7d0d952b420e5912c8219buzbee    mov    r12, sp
336865e6e01486e3d7d61b7d0d952b420e5912c8219buzbee    str    r12, [sp, #-16]!               @ expand the frame and pass SP
3379329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset 16
338c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    bl     \cxx_name                      @ (method_idx, this, caller, Thread*, SP)
339865e6e01486e3d7d61b7d0d952b420e5912c8219buzbee    add    sp, #16                        @ strip the extra frame
3409329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset -16
341634eb2eb14f87753519d0ef2c5f256e55888f378Elliott Hughes    mov    r12, r1                        @ save Method*->code_
3421d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
343637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    cbz    r0, 1f                         @ did we find the target? if not go to exception delivery
344637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    bx     r12                            @ tail call to target
345637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers1:
346a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers    DELIVER_PENDING_EXCEPTION
3479329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND \c_name
348c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers.endm
349a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
3508dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline, artInvokeInterfaceTrampoline
3518dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
352a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
3538dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck
3548dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck
3558dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
3568dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
357ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers
35857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    /*
3595667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     * Quick invocation stub internal.
3606474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     * On entry:
3616474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     *   r0 = method pointer
3622cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier     *   r1 = argument array or null for no argument methods
3636474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     *   r2 = size of argument array in bytes
3646474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     *   r3 = (managed) thread pointer
3656474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     *   [sp] = JValue* result
3665667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *   [sp + 4] = result_in_float
3675667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *   [sp + 8] = core register argument array
3685667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *   [sp + 12] = fp register argument array
3695667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  +-------------------------+
3705667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  | uint32_t* fp_reg_args   |
3715667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  | uint32_t* core_reg_args |
3725667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  |   result_in_float       | <- Caller frame
3735667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  |   Jvalue* result        |
3745667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  +-------------------------+
3755667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  |          lr             |
3765667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  |          r11            |
3775667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  |          r9             |
3785667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  |          r4             | <- r11
3795667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  +-------------------------+
3805667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  | uint32_t out[n-1]       |
3815667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  |    :      :             |        Outs
3825667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  | uint32_t out[0]         |
3835667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  | StackRef<ArtMethod>     | <- SP  value=null
3845667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     *  +-------------------------+
3855d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao     */
3865667fdbb6e441dee7534ade18b628ed396daf593Zheng XuENTRY art_quick_invoke_stub_internal
3874808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    push   {r4, r5, r6, r7, r8, r9, r10, r11, lr}               @ spill regs
3885667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset 16
3895667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_rel_offset r4, 0
3904808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    .cfi_rel_offset r5, 4
3914808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    .cfi_rel_offset r6, 8
3924808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    .cfi_rel_offset r7, 12
3934808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    .cfi_rel_offset r8, 16
3944808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    .cfi_rel_offset r9, 20
3954808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    .cfi_rel_offset r10, 24
3964808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    .cfi_rel_offset r11, 28
3974808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    .cfi_rel_offset lr, 32
3985d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    mov    r11, sp                         @ save the stack pointer
3995d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_def_cfa_register r11
4005667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
4015d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    mov    r9, r3                          @ move managed thread pointer into r9
4026e498695b60f1532d2264ec6badb1cd6e10ecaa9Andreas Gampe
4035667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    add    r4, r2, #4                      @ create space for method pointer in frame
4045667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    sub    r4, sp, r4                      @ reserve & align *stack* to 16 bytes: native calling
4055667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    and    r4, #0xFFFFFFF0                 @ convention only aligns to 8B, so we have to ensure ART
4065667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    mov    sp, r4                          @ 16B alignment ourselves.
4076e498695b60f1532d2264ec6badb1cd6e10ecaa9Andreas Gampe
4085667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    mov    r4, r0                          @ save method*
4095d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    add    r0, sp, #4                      @ pass stack pointer + method ptr as dest for memcpy
4105d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    bl     memcpy                          @ memcpy (dest, src, bytes)
4115d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    mov    ip, #0                          @ set ip to 0
4122cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    str    ip, [sp]                        @ store null for method* at bottom of frame
4135667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
4144808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    ldr    ip, [r11, #48]                  @ load fp register argument array pointer
4155667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vldm   ip, {s0-s15}                    @ copy s0 - s15
4165667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
4174808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    ldr    ip, [r11, #44]                  @ load core register argument array pointer
4185667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    mov    r0, r4                          @ restore method*
4195667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    add    ip, ip, #4                      @ skip r0
4205667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    ldm    ip, {r1-r3}                     @ copy r1 - r3
4215667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
4225667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu#ifdef ARM_R4_SUSPEND_FLAG
4235667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    mov    r4, #SUSPEND_CHECK_INTERVAL     @ reset r4 to suspend check interval
4245667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu#endif
4255667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
4263d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    ldr    ip, [r0, #ART_METHOD_QUICK_CODE_OFFSET_32]  @ get pointer to the code
4275d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    blx    ip                              @ call the method
4285667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
4296474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao    mov    sp, r11                         @ restore the stack pointer
4305667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_def_cfa_register sp
4315667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
4324808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    ldr    r4, [sp, #40]                   @ load result_is_float
4334808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    ldr    r9, [sp, #36]                   @ load the result pointer
4345667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    cmp    r4, #0
4355667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    ite    eq
4365667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    strdeq r0, [r9]                        @ store r0/r1 into result pointer
4375667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vstrne d0, [r9]                        @ store s0-s1/d0 into result pointer
4385667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
4394808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray    pop    {r4, r5, r6, r7, r8, r9, r10, r11, pc}               @ restore spill regs
4405667fdbb6e441dee7534ade18b628ed396daf593Zheng XuEND art_quick_invoke_stub_internal
4416474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao
4425d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    /*
44357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * On entry r0 is uint32_t* gprs_ and r1 is uint32_t* fprs_
44457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     */
445637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan RogersARM_ENTRY art_quick_do_long_jump
44657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    vldm r1, {s0-s31}     @ load all fprs from argument fprs_
44757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    ldr  r2, [r0, #60]    @ r2 = r15 (PC from gprs_ 60=4*15)
448467f816c3c4483fb7766db3fc50e2fff10a92554Jeff Hao    ldr  r14, [r0, #56]   @ (LR from gprs_ 56=4*14)
44957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    add  r0, r0, #12      @ increment r0 to skip gprs_[0..2] 12=4*3
450467f816c3c4483fb7766db3fc50e2fff10a92554Jeff Hao    ldm  r0, {r3-r13}     @ load remaining gprs from argument gprs_
45157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    mov  r0, #0           @ clear result registers r0 and r1
45257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    mov  r1, #0
45357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    bx   r2               @ do long jump
4549329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND art_quick_do_long_jump
45557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
45660db5ab3a2e480db9236325a14cb5a867881d8bbIan Rogers    /*
457ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers     * Entry from managed code that calls artHandleFillArrayDataFromCode and delivers exception on
458ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers     * failure.
459ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers     */
460832336b3c9eb892045a8de1bb12c9361112ca3c5Ian RogersTWO_ARG_REF_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
4614f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
4624f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    /*
463d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers     * Entry from managed code that calls artLockObjectFromCode, may block for GC. r0 holds the
464d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers     * possibly null object to lock.
4654f0d07c783afef89703dce32c94440fc8621a29bIan Rogers     */
4669329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .extern artLockObjectFromCode
467468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_lock_object
4685d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    cbz    r0, .Lslow_lock
4695d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lretry_lock:
4704e6a31eb97f22f4480827474b30b9e64f396eaceMathieu Chartier    ldr    r2, [r9, #THREAD_ID_OFFSET]
4711d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldrex  r1, [r0, #MIRROR_OBJECT_LOCK_WORD_OFFSET]
472e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    mov    r3, r1
473e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    and    r3, #LOCK_WORD_READ_BARRIER_STATE_MASK_TOGGLED  @ zero the read barrier bits
474e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    cbnz   r3, .Lnot_unlocked         @ already thin locked
475e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    @ unlocked case - r1: original lock word that's zero except for the read barrier bits.
476e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    orr    r2, r1, r2                 @ r2 holds thread id with count of 0 with preserved read barrier bits
4771d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    strex  r3, r2, [r0, #MIRROR_OBJECT_LOCK_WORD_OFFSET]
478e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    cbnz   r3, .Llock_strex_fail      @ store failed, retry
479675967d981a3d17aaedf4ca6e07cc3a76e066921Andreas Gampe    dmb    ish                        @ full (LoadLoad|LoadStore) memory barrier
480d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    bx lr
481e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi.Lnot_unlocked:  @ r1: original lock word, r2: thread_id with count of 0 and zero read barrier bits
482e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    lsr    r3, r1, LOCK_WORD_STATE_SHIFT
4835d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    cbnz   r3, .Lslow_lock            @ if either of the top two bits are set, go slow path
484d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    eor    r2, r1, r2                 @ lock_word.ThreadId() ^ self->ThreadId()
485d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    uxth   r2, r2                     @ zero top 16 bits
4865d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    cbnz   r2, .Lslow_lock            @ lock word and self thread id's match -> recursive lock
487d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers                                      @ else contention, go to slow path
488e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    mov    r3, r1                     @ copy the lock word to check count overflow.
489e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    and    r3, #LOCK_WORD_READ_BARRIER_STATE_MASK_TOGGLED  @ zero the read barrier bits.
490e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    add    r2, r3, #LOCK_WORD_THIN_LOCK_COUNT_ONE  @ increment count in lock word placing in r2 to check overflow
491e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    lsr    r3, r2, LOCK_WORD_READ_BARRIER_STATE_SHIFT  @ if either of the upper two bits (28-29) are set, we overflowed.
492e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    cbnz   r3, .Lslow_lock            @ if we overflow the count go slow path
493e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    add    r2, r1, #LOCK_WORD_THIN_LOCK_COUNT_ONE  @ increment count for real
494e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    strex  r3, r2, [r0, #MIRROR_OBJECT_LOCK_WORD_OFFSET] @ strex necessary for read barrier bits
495e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    cbnz   r3, .Llock_strex_fail      @ strex failed, retry
496d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    bx lr
497e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi.Llock_strex_fail:
498e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    b      .Lretry_lock               @ retry
4995d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lslow_lock:
5001d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME r1, r2  @ save callee saves in case we block
5014f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    mov    r1, r9                     @ pass Thread::Current
5021d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    bl     artLockObjectFromCode      @ (Object* obj, Thread*)
5031d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
504d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    RETURN_IF_RESULT_IS_ZERO
505d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    DELIVER_PENDING_EXCEPTION
506468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_lock_object
507ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers
508ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    /*
509ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers     * Entry from managed code that calls artUnlockObjectFromCode and delivers exception on failure.
510d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers     * r0 holds the possibly null object to lock.
511ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers     */
5129329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .extern artUnlockObjectFromCode
513468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_unlock_object
5145d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    cbz    r0, .Lslow_unlock
515e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi.Lretry_unlock:
516e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#ifndef USE_READ_BARRIER
5171d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr    r1, [r0, #MIRROR_OBJECT_LOCK_WORD_OFFSET]
518e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#else
519e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    ldrex  r1, [r0, #MIRROR_OBJECT_LOCK_WORD_OFFSET]  @ Need to use atomic instructions for read barrier
520e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#endif
521e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    lsr    r2, r1, #LOCK_WORD_STATE_SHIFT
5225d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    cbnz   r2, .Lslow_unlock          @ if either of the top two bits are set, go slow path
523d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    ldr    r2, [r9, #THREAD_ID_OFFSET]
524e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    mov    r3, r1                     @ copy lock word to check thread id equality
525e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    and    r3, #LOCK_WORD_READ_BARRIER_STATE_MASK_TOGGLED  @ zero the read barrier bits
526e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    eor    r3, r3, r2                 @ lock_word.ThreadId() ^ self->ThreadId()
527d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    uxth   r3, r3                     @ zero top 16 bits
5285d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    cbnz   r3, .Lslow_unlock          @ do lock word and self thread id's match?
529e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    mov    r3, r1                     @ copy lock word to detect transition to unlocked
530e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    and    r3, #LOCK_WORD_READ_BARRIER_STATE_MASK_TOGGLED  @ zero the read barrier bits
531e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    cmp    r3, #LOCK_WORD_THIN_LOCK_COUNT_ONE
5325d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    bpl    .Lrecursive_thin_unlock
533e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    @ transition to unlocked
534e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    mov    r3, r1
535e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    and    r3, #LOCK_WORD_READ_BARRIER_STATE_MASK  @ r3: zero except for the preserved read barrier bits
536675967d981a3d17aaedf4ca6e07cc3a76e066921Andreas Gampe    dmb    ish                        @ full (LoadStore|StoreStore) memory barrier
537e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#ifndef USE_READ_BARRIER
5381d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str    r3, [r0, #MIRROR_OBJECT_LOCK_WORD_OFFSET]
539e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#else
540e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    strex  r2, r3, [r0, #MIRROR_OBJECT_LOCK_WORD_OFFSET]  @ strex necessary for read barrier bits
541e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    cbnz   r2, .Lunlock_strex_fail    @ store failed, retry
542e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#endif
543d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    bx     lr
544e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi.Lrecursive_thin_unlock:  @ r1: original lock word
545e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    sub    r1, r1, #LOCK_WORD_THIN_LOCK_COUNT_ONE  @ decrement count
546e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#ifndef USE_READ_BARRIER
5471d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str    r1, [r0, #MIRROR_OBJECT_LOCK_WORD_OFFSET]
548e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#else
549e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    strex  r2, r1, [r0, #MIRROR_OBJECT_LOCK_WORD_OFFSET]  @ strex necessary for read barrier bits
550e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    cbnz   r2, .Lunlock_strex_fail    @ store failed, retry
551e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#endif
552d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    bx     lr
553e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi.Lunlock_strex_fail:
554e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi    b      .Lretry_unlock             @ retry
5555d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lslow_unlock:
5561d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    @ save callee saves in case exception allocation triggers GC
5571d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME r1, r2
558637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    mov    r1, r9                     @ pass Thread::Current
5591d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    bl     artUnlockObjectFromCode    @ (Object* obj, Thread*)
5601d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
561637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    RETURN_IF_RESULT_IS_ZERO
562ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    DELIVER_PENDING_EXCEPTION
563468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_unlock_object
564ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers
565ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    /*
566a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers     * Entry from managed code that calls artIsAssignableFromCode and on failure calls
567a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers     * artThrowClassCastException.
568ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers     */
569a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    .extern artThrowClassCastException
570468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_check_cast
571a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    push {r0-r1, lr}                    @ save arguments, link register and pad
572a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    .cfi_adjust_cfa_offset 12
573a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    .cfi_rel_offset r0, 0
574a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    .cfi_rel_offset r1, 4
575a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    .cfi_rel_offset lr, 8
576a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    sub sp, #4
577a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    .cfi_adjust_cfa_offset 4
578a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    bl artIsAssignableFromCode
5795d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    cbz    r0, .Lthrow_class_cast_exception
580a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    add sp, #4
581a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    .cfi_adjust_cfa_offset -4
582a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    pop {r0-r1, pc}
583d0a0b3e189e6f46d410d61dab4d0cce113be41d5Christopher Ferris    .cfi_adjust_cfa_offset 4        @ Reset unwind info so following code unwinds.
5845d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lthrow_class_cast_exception:
585a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    add sp, #4
586a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    .cfi_adjust_cfa_offset -4
587a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    pop {r0-r1, lr}
588d0a0b3e189e6f46d410d61dab4d0cce113be41d5Christopher Ferris    .cfi_adjust_cfa_offset -12
589bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r0
590bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r1
591d0a0b3e189e6f46d410d61dab4d0cce113be41d5Christopher Ferris    .cfi_restore lr
5921d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_SAVE_ALL_CALLEE_SAVE_FRAME r2, r3  // save all registers as basis for long jump context
593a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    mov r2, r9                      @ pass Thread::Current
5941d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    b   artThrowClassCastException  @ (Class*, Class*, Thread*)
595a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    bkpt
596468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_check_cast
597e51a511ccee3f3c0120807321bcc160fcaa664beIan Rogers
598e51a511ccee3f3c0120807321bcc160fcaa664beIan Rogers    /*
599a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers     * Entry from managed code for array put operations of objects where the value being stored
600a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers     * needs to be checked for compatibility.
601a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers     * r0 = array, r1 = index, r2 = value
602e51a511ccee3f3c0120807321bcc160fcaa664beIan Rogers     */
603a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersENTRY art_quick_aput_obj_with_null_and_bound_check
604a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    tst r0, r0
605d842648ee0ae8df1a899c53e96a98ccc6cca9d4cDan Albert    bne art_quick_aput_obj_with_bound_check
606a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    b art_quick_throw_null_pointer_exception
607a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersEND art_quick_aput_obj_with_null_and_bound_check
608a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
60958bea4a6114b9ea4b00e36186357e5b431430123Dan Albert    .hidden art_quick_aput_obj_with_bound_check
610a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersENTRY art_quick_aput_obj_with_bound_check
6111d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET]
612a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    cmp r3, r1
613d842648ee0ae8df1a899c53e96a98ccc6cca9d4cDan Albert    bhi art_quick_aput_obj
614a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    mov r0, r1
615a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    mov r1, r3
616a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    b art_quick_throw_array_bounds
617a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersEND art_quick_aput_obj_with_bound_check
618a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
61958bea4a6114b9ea4b00e36186357e5b431430123Dan Albert    .hidden art_quick_aput_obj
620a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersENTRY art_quick_aput_obj
6215d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    cbz r2, .Ldo_aput_null
6221d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr r3, [r0, #MIRROR_OBJECT_CLASS_OFFSET]
6231d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr ip, [r2, #MIRROR_OBJECT_CLASS_OFFSET]
6241d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr r3, [r3, #MIRROR_CLASS_COMPONENT_TYPE_OFFSET]
625a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    cmp r3, ip  @ value's type == array's component type - trivial assignability
6265d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    bne .Lcheck_assignability
6275d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Ldo_aput:
6281d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    add r3, r0, #MIRROR_OBJECT_ARRAY_DATA_OFFSET
629a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    str r2, [r3, r1, lsl #2]
630a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    ldr r3, [r9, #THREAD_CARD_TABLE_OFFSET]
631a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    lsr r0, r0, #7
632a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    strb r3, [r3, r0]
633a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    blx lr
6345d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Ldo_aput_null:
6351d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    add r3, r0, #MIRROR_OBJECT_ARRAY_DATA_OFFSET
636a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    str r2, [r3, r1, lsl #2]
637a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    blx lr
6385d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lcheck_assignability:
6395d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    push {r0-r2, lr}             @ save arguments
640525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe    .cfi_adjust_cfa_offset 16
641525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe    .cfi_rel_offset r0, 0
642525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe    .cfi_rel_offset r1, 4
643525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe    .cfi_rel_offset r2, 8
644525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe    .cfi_rel_offset lr, 12
645a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    mov r1, ip
646a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    mov r0, r3
647a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    bl artIsAssignableFromCode
6485d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    cbz r0, .Lthrow_array_store_exception
649a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    pop {r0-r2, lr}
650525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe    .cfi_restore r0
651525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe    .cfi_restore r1
652525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe    .cfi_restore r2
653525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe    .cfi_restore lr
654525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe    .cfi_adjust_cfa_offset -16
6551d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    add r3, r0, #MIRROR_OBJECT_ARRAY_DATA_OFFSET
656a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    str r2, [r3, r1, lsl #2]
657a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    ldr r3, [r9, #THREAD_CARD_TABLE_OFFSET]
658a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    lsr r0, r0, #7
659a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    strb r3, [r3, r0]
660a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    blx lr
6615d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lthrow_array_store_exception:
662a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    pop {r0-r2, lr}
663d0a0b3e189e6f46d410d61dab4d0cce113be41d5Christopher Ferris    /* No need to repeat restore cfi directives, the ones above apply here. */
6641d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_SAVE_ALL_CALLEE_SAVE_FRAME r3, ip
665a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    mov r1, r2
6661d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    mov r2, r9                     @ pass Thread::Current
6671d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    b artThrowArrayStoreException  @ (Class*, Class*, Thread*)
6681d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    bkpt                           @ unreached
669a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersEND art_quick_aput_obj
670cbba6ac9bf9a6c630a7aafae6d8767b5ddbb6fd5Ian Rogers
6711cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe// Macro to facilitate adding new allocation entrypoints.
6725ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko.macro ONE_ARG_DOWNCALL name, entrypoint, return
6735ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko    .extern \entrypoint
6745ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir MarkoENTRY \name
6755ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME  r1, r2  @ save callee saves in case of GC
6765ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko    mov    r1, r9                     @ pass Thread::Current
6775ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko    bl     \entrypoint     @ (uint32_t type_idx, Method* method, Thread*)
6785ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
6795ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko    \return
6805ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir MarkoEND \name
6815ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko.endm
6825ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko
6835ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko// Macro to facilitate adding new allocation entrypoints.
6841cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe.macro TWO_ARG_DOWNCALL name, entrypoint, return
6851cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    .extern \entrypoint
6861cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas GampeENTRY \name
6871cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME  r2, r3  @ save callee saves in case of GC
6881cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    mov    r2, r9                     @ pass Thread::Current
6891cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    bl     \entrypoint     @ (uint32_t type_idx, Method* method, Thread*)
6901d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
6911cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    \return
6921cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas GampeEND \name
6931cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe.endm
694ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers
6951cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe// Macro to facilitate adding new array allocation entrypoints.
6961cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe.macro THREE_ARG_DOWNCALL name, entrypoint, return
6971cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    .extern \entrypoint
6981cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas GampeENTRY \name
6991cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME  r3, r12  @ save callee saves in case of GC
7001cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    mov    r3, r9                     @ pass Thread::Current
7011cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    @ (uint32_t type_idx, Method* method, int32_t component_count, Thread*)
7021cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    bl     \entrypoint
7031d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
7041cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    \return
7051cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas GampeEND \name
7061cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe.endm
707b093c6b27f8ea9bbe2d49c03ebe345203a121199Ian Rogers
708848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao// Macro to facilitate adding new allocation entrypoints.
709848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao.macro FOUR_ARG_DOWNCALL name, entrypoint, return
710848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    .extern \entrypoint
711848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff HaoENTRY \name
712848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME  r3, r12  @ save callee saves in case of GC
713848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    str    r9, [sp, #-16]!            @ expand the frame and pass Thread::Current
714848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    .pad #16
715848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    .cfi_adjust_cfa_offset 16
716848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    bl     \entrypoint
717848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    add    sp, #16                    @ strip the extra frame
718848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    .cfi_adjust_cfa_offset -16
719848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
720848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    \return
721848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff HaoEND \name
722848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao.endm
723848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao
7245ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir MarkoONE_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
7255ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir MarkoONE_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
7265ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir MarkoONE_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
72728ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers
728ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    /*
72937f05ef45e0393de812d51261dc293240c17294dFred Shih     * Called by managed code to resolve a static field and load a non-wide value.
730ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers     */
73137f05ef45e0393de812d51261dc293240c17294dFred ShihONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
73237f05ef45e0393de812d51261dc293240c17294dFred ShihONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
73337f05ef45e0393de812d51261dc293240c17294dFred ShihONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
73437f05ef45e0393de812d51261dc293240c17294dFred ShihONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
73537f05ef45e0393de812d51261dc293240c17294dFred ShihONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
73637f05ef45e0393de812d51261dc293240c17294dFred ShihONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
737ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    /*
73857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code to resolve a static field and load a 64-bit primitive value.
739ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers     */
7409329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .extern artGet64StaticFromCode
741468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_get64_static
7421d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME r2, r3  @ save callee saves in case of GC
7431d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr    r1, [sp, #FRAME_SIZE_REFS_ONLY_CALLEE_SAVE]  @ pass referrer
744ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    mov    r2, r9                        @ pass Thread::Current
7451d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    bl     artGet64StaticFromCode        @ (uint32_t field_idx, const Method* referrer, Thread*)
746637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    ldr    r2, [r9, #THREAD_EXCEPTION_OFFSET]  @ load Thread::Current()->exception_
7471d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
748637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    cbnz   r2, 1f                        @ success if no exception pending
749637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    bx     lr                            @ return on success
750637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers1:
751ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    DELIVER_PENDING_EXCEPTION
752468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_get64_static
753ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers
754ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    /*
75537f05ef45e0393de812d51261dc293240c17294dFred Shih     * Called by managed code to resolve an instance field and load a non-wide value.
756ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers     */
75737f05ef45e0393de812d51261dc293240c17294dFred ShihTWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
75837f05ef45e0393de812d51261dc293240c17294dFred ShihTWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
75937f05ef45e0393de812d51261dc293240c17294dFred ShihTWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
76037f05ef45e0393de812d51261dc293240c17294dFred ShihTWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
76137f05ef45e0393de812d51261dc293240c17294dFred ShihTWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
76237f05ef45e0393de812d51261dc293240c17294dFred ShihTWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
7631bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    /*
76457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code to resolve an instance field and load a 64-bit primitive value.
7651bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers     */
7669329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .extern artGet64InstanceFromCode
767468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_get64_instance
7681d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME  r2, r3  @ save callee saves in case of GC
7691d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr    r2, [sp, #FRAME_SIZE_REFS_ONLY_CALLEE_SAVE]  @ pass referrer
7701bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    mov    r3, r9                        @ pass Thread::Current
7711d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    bl     artGet64InstanceFromCode      @ (field_idx, Object*, referrer, Thread*)
772637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    ldr    r2, [r9, #THREAD_EXCEPTION_OFFSET]  @ load Thread::Current()->exception_
7731d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
774637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    cbnz   r2, 1f                        @ success if no exception pending
775637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    bx     lr                            @ return on success
776637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers1:
7771bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    DELIVER_PENDING_EXCEPTION
778468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_get64_instance
7791bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
7801bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    /*
78137f05ef45e0393de812d51261dc293240c17294dFred Shih     * Called by managed code to resolve a static field and store a non-wide value.
782ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers     */
78337f05ef45e0393de812d51261dc293240c17294dFred ShihTWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
78437f05ef45e0393de812d51261dc293240c17294dFred ShihTWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
78537f05ef45e0393de812d51261dc293240c17294dFred ShihTWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
78637f05ef45e0393de812d51261dc293240c17294dFred ShihTWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
787ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    /*
78857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code to resolve a static field and store a 64-bit primitive value.
78919abfb4f9af450e2ce3a801c5a0c34c4193e3e57Brian Carlstrom     * On entry r0 holds field index, r1:r2 hold new_val
790ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers     */
7919329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .extern artSet64StaticFromCode
792468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_set64_static
7931d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME r3, r12   @ save callee saves in case of GC
79419abfb4f9af450e2ce3a801c5a0c34c4193e3e57Brian Carlstrom    mov    r3, r2                        @ pass one half of wide argument
79519abfb4f9af450e2ce3a801c5a0c34c4193e3e57Brian Carlstrom    mov    r2, r1                        @ pass other half of wide argument
7961d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr    r1, [sp, #FRAME_SIZE_REFS_ONLY_CALLEE_SAVE]  @ pass referrer
7971d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str    r9, [sp, #-16]!               @ expand the frame and pass Thread::Current
7981d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    .cfi_adjust_cfa_offset 16
7991d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    bl     artSet64StaticFromCode        @ (field_idx, referrer, new_val, Thread*)
800ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    add    sp, #16                       @ release out args
801bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_adjust_cfa_offset -16
8021d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME  @ TODO: we can clearly save an add here
803637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    RETURN_IF_RESULT_IS_ZERO
804ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    DELIVER_PENDING_EXCEPTION
805468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_set64_static
806ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers
807ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    /*
80837f05ef45e0393de812d51261dc293240c17294dFred Shih     * Called by managed code to resolve an instance field and store a non-wide value.
8091bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers     */
81037f05ef45e0393de812d51261dc293240c17294dFred ShihTHREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
81137f05ef45e0393de812d51261dc293240c17294dFred ShihTHREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
81237f05ef45e0393de812d51261dc293240c17294dFred ShihTHREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
81337f05ef45e0393de812d51261dc293240c17294dFred ShihTHREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
8141bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    /*
81557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code to resolve an instance field and store a 64-bit primitive value.
8161bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers     */
81737f05ef45e0393de812d51261dc293240c17294dFred Shih    .extern artSet64InstanceFromCode
818468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_set64_instance
8191d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME r12, lr  @ save callee saves in case of GC
8201d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr    r12, [sp, #FRAME_SIZE_REFS_ONLY_CALLEE_SAVE]  @ pass referrer
8211d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str    r9, [sp, #-12]!               @ expand the frame and pass Thread::Current
8221d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    .cfi_adjust_cfa_offset 12
8231d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str    r12, [sp, #-4]!               @ expand the frame and pass the referrer
8241d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    .cfi_adjust_cfa_offset 4
8251d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    bl     artSet64InstanceFromCode      @ (field_idx, Object*, new_val, Method* referrer, Thread*)
8261bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    add    sp, #16                       @ release out args
8279329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset -16
8281d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME  @ TODO: we can clearly save an add here
829637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    RETURN_IF_RESULT_IS_ZERO
8301bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    DELIVER_PENDING_EXCEPTION
831468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_set64_instance
8321bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers
8331bddec3a6521f16df37499754000a3b1787a52e9Ian Rogers    /*
834caab8c4ef372db5c119bfac1911fa27b174a935cIan Rogers     * Entry from managed code to resolve a string, this stub will allocate a String and deliver an
8355ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko     * exception on error. On success the String is returned. R0 holds the string index. The fast
8365ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko     * path check for hit in strings cache has already been performed.
837aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom     */
8385ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir MarkoONE_ARG_DOWNCALL art_quick_resolve_string, artResolveStringFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
8390eb7d7e2a0c2767b5fd86bd52436c618fd4c3120Ian Rogers
8407410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier// Generate the allocation entrypoints for each allocator.
8417410f29b4dae223befac036ea567d7f33351dad1Mathieu ChartierGENERATE_ALL_ALLOC_ENTRYPOINTS
8423b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi
843dfcdf1a0d2d8d75b4c701317e4a092498a8d1e9eIan Rogers    /*
84457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code when the value in rSUSPEND has been decremented to 0.
845dfcdf1a0d2d8d75b4c701317e4a092498a8d1e9eIan Rogers     */
8469329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .extern artTestSuspendFromCode
8479329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersENTRY art_quick_test_suspend
84804f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin#ifdef ARM_R4_SUSPEND_FLAG
8491d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldrh   r0, [rSELF, #THREAD_FLAGS_OFFSET]
8504f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    mov    rSUSPEND, #SUSPEND_CHECK_INTERVAL  @ reset rSUSPEND to SUSPEND_CHECK_INTERVAL
851637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    cbnz   r0, 1f                             @ check Thread::Current()->suspend_count_ == 0
852637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    bx     lr                                 @ return if suspend_count_ == 0
853637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers1:
85404f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin#endif
8554f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    mov    r0, rSELF
8561d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME r1, r2   @ save callee saves for GC stack crawl
8571d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    @ TODO: save FPRs to enable access in the debugger?
8581d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    bl     artTestSuspendFromCode             @ (Thread*)
8591d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME_AND_RETURN
8609329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND art_quick_test_suspend
8614f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
8628325296769a77ecf3ab647b5ab516f439f5b3206Dave AllisonENTRY art_quick_implicit_suspend
8638325296769a77ecf3ab647b5ab516f439f5b3206Dave Allison    mov    r0, rSELF
8641d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME r1, r2   @ save callee saves for stack crawl
8651d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    bl     artTestSuspendFromCode             @ (Thread*)
8661d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME_AND_RETURN
8678325296769a77ecf3ab647b5ab516f439f5b3206Dave AllisonEND art_quick_implicit_suspend
8688325296769a77ecf3ab647b5ab516f439f5b3206Dave Allison
869dfcdf1a0d2d8d75b4c701317e4a092498a8d1e9eIan Rogers    /*
870dfcdf1a0d2d8d75b4c701317e4a092498a8d1e9eIan Rogers     * Called by managed code that is attempting to call a method on a proxy class. On entry
871af6e67a4816d2593586115b89faa659225363246Ian Rogers     * r0 holds the proxy method and r1 holds the receiver; r2 and r3 may contain arguments. The
872af6e67a4816d2593586115b89faa659225363246Ian Rogers     * frame size of the invoked proxy method agrees with a ref and args callee save frame.
873dfcdf1a0d2d8d75b4c701317e4a092498a8d1e9eIan Rogers     */
8745fa60c3db4208df407113b5a69d295a9c93d53b1Jeff Hao     .extern artQuickProxyInvokeHandler
8759329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersENTRY art_quick_proxy_invoke_handler
8761d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_R0
877dfcdf1a0d2d8d75b4c701317e4a092498a8d1e9eIan Rogers    mov     r2, r9                 @ pass Thread::Current
878af6e67a4816d2593586115b89faa659225363246Ian Rogers    mov     r3, sp                 @ pass SP
8795fa60c3db4208df407113b5a69d295a9c93d53b1Jeff Hao    blx     artQuickProxyInvokeHandler  @ (Method* proxy method, receiver, Thread*, SP)
880637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    ldr     r2, [r9, #THREAD_EXCEPTION_OFFSET]  @ load Thread::Current()->exception_
8815667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    // Tear down the callee-save frame. Skip arg registers.
8825667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    add     sp, #(FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE - FRAME_SIZE_REFS_ONLY_CALLEE_SAVE)
8835667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset -(FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE - FRAME_SIZE_REFS_ONLY_CALLEE_SAVE)
8841d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
8855667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    cbnz    r2, 1f                 @ success if no exception is pending
8865667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vmov    d0, r0, r1             @ store into fpr, for when it's a fpr return...
887637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    bx      lr                     @ return on success
888637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers1:
889dfcdf1a0d2d8d75b4c701317e4a092498a8d1e9eIan Rogers    DELIVER_PENDING_EXCEPTION
8909329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND art_quick_proxy_invoke_handler
891dfcdf1a0d2d8d75b4c701317e4a092498a8d1e9eIan Rogers
89288474b416eb257078e590bf9bc7957cee604a186Jeff Hao    /*
89388474b416eb257078e590bf9bc7957cee604a186Jeff Hao     * Called to resolve an imt conflict. r12 is a hidden argument that holds the target method's
89488474b416eb257078e590bf9bc7957cee604a186Jeff Hao     * dex method index.
89588474b416eb257078e590bf9bc7957cee604a186Jeff Hao     */
89688474b416eb257078e590bf9bc7957cee604a186Jeff HaoENTRY art_quick_imt_conflict_trampoline
89788474b416eb257078e590bf9bc7957cee604a186Jeff Hao    ldr    r0, [sp, #0]            @ load caller Method*
8983d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    ldr    r0, [r0, #ART_METHOD_DEX_CACHE_METHODS_OFFSET]  @ load dex_cache_resolved_methods
8991d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    add    r0, #MIRROR_OBJECT_ARRAY_DATA_OFFSET  @ get starting address of data
90088474b416eb257078e590bf9bc7957cee604a186Jeff Hao    ldr    r0, [r0, r12, lsl 2]    @ load the target method
90188474b416eb257078e590bf9bc7957cee604a186Jeff Hao    b art_quick_invoke_interface_trampoline
90288474b416eb257078e590bf9bc7957cee604a186Jeff HaoEND art_quick_imt_conflict_trampoline
90388474b416eb257078e590bf9bc7957cee604a186Jeff Hao
904468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    .extern artQuickResolutionTrampoline
905468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_resolution_trampoline
9061d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME r2, r3
907468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    mov     r2, r9                 @ pass Thread::Current
908468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    mov     r3, sp                 @ pass SP
909468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    blx     artQuickResolutionTrampoline  @ (Method* called, receiver, Thread*, SP)
910637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    cbz     r0, 1f                 @ is code pointer null? goto exception
911468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    mov     r12, r0
912468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    ldr  r0, [sp, #0]              @ load resolved method in r0
9131d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
914468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    bx      r12                    @ tail-call into actual code
915468532ea115657709bc32ee498e701a4c71762d4Ian Rogers1:
9161d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
917468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    DELIVER_PENDING_EXCEPTION
918468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_resolution_trampoline
919468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
920c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    /*
921c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe     * Called to do a generic JNI down-call
922c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe     */
9236f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian RogersENTRY art_quick_generic_jni_trampoline
9241d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_R0
925c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
926c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // Save rSELF
927c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    mov r11, rSELF
928c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // Save SP , so we can have static CFI info. r10 is saved in ref_and_args.
929c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    mov r10, sp
930c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    .cfi_def_cfa_register r10
931c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
932c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    sub sp, sp, #5120
933c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
934c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // prepare for artQuickGenericJniTrampoline call
935c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // (Thread*,  SP)
936c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    //    r0      r1   <= C calling convention
937c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    //  rSELF     r10  <= where they are
938c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
939c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    mov r0, rSELF   // Thread*
940c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    mov r1, r10
941c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    blx artQuickGenericJniTrampoline  // (Thread*, sp)
942c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
943c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // The C call will have registered the complete save-frame on success.
944c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // The result of the call is:
945c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // r0: pointer to native code, 0 on error.
946c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // r1: pointer to the bottom of the used area of the alloca, can restore stack till there.
947c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
948c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // Check for error = 0.
949126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray    cbz r0, .Lexception_in_native
950c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
951c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // Release part of the alloca.
952c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    mov sp, r1
953c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
954c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // Save the code pointer
955c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    mov r12, r0
956c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
957c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // Load parameters from frame into registers.
958c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    pop {r0-r3}
959c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
960c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // Softfloat.
961c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // TODO: Change to hardfloat when supported.
962c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
963c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    blx r12           // native call.
964c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
965c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // result sign extension is handled in C code
966c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // prepare for artQuickGenericJniEndTrampoline call
967c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // (Thread*, result, result_f)
96854accbca0b549b1b1ad3ef09655dad438bc1e104Nicolas Geoffray    //    r0      r2,r3    stack       <= C calling convention
969c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    //    r11     r0,r1    r0,r1          <= where they are
97054accbca0b549b1b1ad3ef09655dad438bc1e104Nicolas Geoffray    sub sp, sp, #8 // Stack alignment.
971c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
97254accbca0b549b1b1ad3ef09655dad438bc1e104Nicolas Geoffray    push {r0-r1}
97354accbca0b549b1b1ad3ef09655dad438bc1e104Nicolas Geoffray    mov r3, r1
97454accbca0b549b1b1ad3ef09655dad438bc1e104Nicolas Geoffray    mov r2, r0
975c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    mov r0, r11
976c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
977c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    blx artQuickGenericJniEndTrampoline
978c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
979c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // Restore self pointer.
980c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    mov r9, r11
981c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
982c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    // Pending exceptions possible.
983c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    ldr r2, [r9, #THREAD_EXCEPTION_OFFSET]  @ load Thread::Current()->exception_
984c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    cbnz r2, .Lexception_in_native
985c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
986126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray    // Tear down the alloca.
987126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray    mov sp, r10
988126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray    .cfi_def_cfa_register sp
989126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray
9905667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    // Tear down the callee-save frame. Skip arg registers.
9915667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    add     sp, #FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE-FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
9925667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset -(FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE-FRAME_SIZE_REFS_ONLY_CALLEE_SAVE)
9935667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
994c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
9955667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    // store into fpr, for when it's a fpr return...
9965667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vmov d0, r0, r1
997c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    bx lr      // ret
998d0a0b3e189e6f46d410d61dab4d0cce113be41d5Christopher Ferris    // Undo the unwinding information from above since it doesn't apply below.
999d0a0b3e189e6f46d410d61dab4d0cce113be41d5Christopher Ferris    .cfi_def_cfa_register r10
1000d0a0b3e189e6f46d410d61dab4d0cce113be41d5Christopher Ferris    .cfi_adjust_cfa_offset FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE-FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
1001c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe
1002c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe.Lexception_in_native:
1003126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray    ldr sp, [r9, #THREAD_TOP_QUICK_FRAME_OFFSET]
1004126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray    .cfi_def_cfa_register sp
1005126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray    # This will create a new save-all frame, required by the runtime.
1006c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe    DELIVER_PENDING_EXCEPTION
1007c200a4abeca91e19969f5b35543f17f812ba32b9Andreas GampeEND art_quick_generic_jni_trampoline
10082da882315a61072664f7ce3c212307342e907207Andreas Gampe
1009468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    .extern artQuickToInterpreterBridge
10106f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian RogersENTRY art_quick_to_interpreter_bridge
10111d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME r1, r2
10127db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers    mov     r1, r9                 @ pass Thread::Current
10137db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers    mov     r2, sp                 @ pass SP
1014468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    blx     artQuickToInterpreterBridge    @ (Method* method, Thread*, SP)
1015637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    ldr     r2, [r9, #THREAD_EXCEPTION_OFFSET]  @ load Thread::Current()->exception_
10165667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    // Tear down the callee-save frame. Skip arg registers.
10175667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    add     sp, #(FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE - FRAME_SIZE_REFS_ONLY_CALLEE_SAVE)
10185667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset -(FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE - FRAME_SIZE_REFS_ONLY_CALLEE_SAVE)
10191d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
1020590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    cbnz    r2, 1f                 @ success if no exception is pending
10215667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vmov    d0, r0, r1             @ store into fpr, for when it's a fpr return...
10225667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    bx      lr                     @ return on success
1023637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers1:
10247db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers    DELIVER_PENDING_EXCEPTION
1025468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_to_interpreter_bridge
10267db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers
1027e343b76af81a005ef64f5e75a555389fd9147dabjeffhao    /*
10280791adc2249366c50684935a4c42ba5e58bc3746jeffhao     * Routine that intercepts method calls and returns.
1029e343b76af81a005ef64f5e75a555389fd9147dabjeffhao     */
10309329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .extern artInstrumentationMethodEntryFromCode
10319329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .extern artInstrumentationMethodExitFromCode
1032468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_instrumentation_entry
10331d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    @ Make stack crawlable and clobber r2 and r3 (post saving)
10341d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME r2, r3
10351d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    @ preserve r0 (not normally an arg) knowing there is a spare slot in kRefsAndArgs.
10361d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    str   r0, [sp, #4]
103762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    mov   r2, r9         @ pass Thread::Current
10381d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    mov   r3, lr         @ pass LR
10391d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    blx   artInstrumentationMethodEntryFromCode  @ (Method*, Object*, Thread*, LR)
104062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    mov   r12, r0        @ r12 holds reference to code
104162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    ldr   r0, [sp, #4]   @ restore r0
10421d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
1043468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    blx   r12            @ call method with lr set to art_quick_instrumentation_exit
10441d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers@ Deliberate fall-through into art_quick_instrumentation_exit.
1045468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    .type art_quick_instrumentation_exit, #function
1046468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    .global art_quick_instrumentation_exit
1047468532ea115657709bc32ee498e701a4c71762d4Ian Rogersart_quick_instrumentation_exit:
104862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    mov   lr, #0         @ link register is to here, so clobber with 0 for later checks
10491d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_REFS_ONLY_CALLEE_SAVE_FRAME r2, r3  @ set up frame knowing r2 and r3 must be dead on exit
1050306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers    mov   r12, sp        @ remember bottom of caller's frame
1051e343b76af81a005ef64f5e75a555389fd9147dabjeffhao    push  {r0-r1}        @ save return value
10529329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset 8
10539329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r0, 0
10549329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r1, 4
1055844fb67a8b5638c4e195dbbe510dc1626824a16cAndreas Gampe    vpush {d0}           @ save fp return value
10569329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset 8
1057844fb67a8b5638c4e195dbbe510dc1626824a16cAndreas Gampe    sub   sp, #8         @ space for return value argument. Note: AAPCS stack alignment is 8B, no
1058844fb67a8b5638c4e195dbbe510dc1626824a16cAndreas Gampe                         @ need to align by 16.
1059844fb67a8b5638c4e195dbbe510dc1626824a16cAndreas Gampe    .cfi_adjust_cfa_offset 8
1060844fb67a8b5638c4e195dbbe510dc1626824a16cAndreas Gampe    vstr  d0, [sp]       @ d0 -> [sp] for fpr_res
106162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    mov   r2, r0         @ pass return value as gpr_res
106262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    mov   r3, r1
1063306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers    mov   r0, r9         @ pass Thread::Current
1064306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers    mov   r1, r12        @ pass SP
106562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    blx   artInstrumentationMethodExitFromCode  @ (Thread*, SP, gpr_res, fpr_res)
1066306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers    add   sp, #8
10679329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset -8
106862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
1069306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers    mov   r2, r0         @ link register saved by instrumentation
1070306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers    mov   lr, r1         @ r1 is holding link register if we're to bounce to deoptimize
1071844fb67a8b5638c4e195dbbe510dc1626824a16cAndreas Gampe    vpop  {d0}           @ restore fp return value
1072844fb67a8b5638c4e195dbbe510dc1626824a16cAndreas Gampe    .cfi_adjust_cfa_offset -8
1073e343b76af81a005ef64f5e75a555389fd9147dabjeffhao    pop   {r0, r1}       @ restore return value
1074d0a0b3e189e6f46d410d61dab4d0cce113be41d5Christopher Ferris    .cfi_adjust_cfa_offset -8
1075bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r0
1076bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r1
107762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    add sp, #32          @ remove callee save frame
107862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    .cfi_adjust_cfa_offset -32
1079306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers    bx    r2             @ return
10801d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersEND art_quick_instrumentation_entry
1081306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers
1082306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers    /*
108362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers     * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization
108462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers     * will long jump to the upcall with a special exception of -1.
1085306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers     */
10869329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .extern artDeoptimize
10879329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersENTRY art_quick_deoptimize
10881d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    SETUP_SAVE_ALL_CALLEE_SAVE_FRAME r0, r1
108962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    mov    r0, r9         @ Set up args.
10901d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    blx    artDeoptimize  @ artDeoptimize(Thread*)
10919329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND art_quick_deoptimize
1092e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
1093324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers    /*
1094324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     * Signed 64-bit integer multiply.
1095324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     *
1096324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
1097324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     *        WX
1098324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     *      x YZ
1099324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     *  --------
1100324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     *     ZW ZX
1101324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     *  YW YX
1102324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     *
1103324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     * The low word of the result holds ZX, the high word holds
1104324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
1105324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     * it doesn't fit in the low 64 bits.
1106324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     *
1107324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     * Unlike most ARM math operations, multiply instructions have
1108324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     * restrictions on using the same register more than once (Rd and Rm
1109324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     * cannot be the same).
1110324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers     */
1111324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers    /* mul-long vAA, vBB, vCC */
11129329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersENTRY art_quick_mul_long
1113324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers    push    {r9 - r10}
11149329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset 8
11159329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r9, 0
11169329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r10, 4
1117324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers    mul     ip, r2, r1                  @  ip<- ZxW
1118324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
1119324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
1120324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
1121324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers    mov     r0,r9
1122324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers    mov     r1,r10
1123324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers    pop     {r9 - r10}
11249329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset -8
1125bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r9
1126bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore r10
1127324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers    bx      lr
11289329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND art_quick_mul_long
1129324e190e9de0d81d39d88474e189acef9b10bcc8Ian Rogers
11305433072f589b61413e042eddf76e8190a048f71dbuzbee    /*
11315433072f589b61413e042eddf76e8190a048f71dbuzbee     * Long integer shift.  This is different from the generic 32/64-bit
11325433072f589b61413e042eddf76e8190a048f71dbuzbee     * binary operations because vAA/vBB are 64-bit but vCC (the shift
11335433072f589b61413e042eddf76e8190a048f71dbuzbee     * distance) is 32-bit.  Also, Dalvik requires us to ignore all but the low
11345433072f589b61413e042eddf76e8190a048f71dbuzbee     * 6 bits.
11355433072f589b61413e042eddf76e8190a048f71dbuzbee     * On entry:
11365433072f589b61413e042eddf76e8190a048f71dbuzbee     *   r0: low word
11375433072f589b61413e042eddf76e8190a048f71dbuzbee     *   r1: high word
11385433072f589b61413e042eddf76e8190a048f71dbuzbee     *   r2: shift count
11395433072f589b61413e042eddf76e8190a048f71dbuzbee     */
11405433072f589b61413e042eddf76e8190a048f71dbuzbee    /* shl-long vAA, vBB, vCC */
1141637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan RogersARM_ENTRY art_quick_shl_long            @ ARM code as thumb code requires spills
11425433072f589b61413e042eddf76e8190a048f71dbuzbee    and     r2, r2, #63                 @ r2<- r2 & 0x3f
11435433072f589b61413e042eddf76e8190a048f71dbuzbee    mov     r1, r1, asl r2              @  r1<- r1 << r2
11445433072f589b61413e042eddf76e8190a048f71dbuzbee    rsb     r3, r2, #32                 @  r3<- 32 - r2
11455433072f589b61413e042eddf76e8190a048f71dbuzbee    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
11465433072f589b61413e042eddf76e8190a048f71dbuzbee    subs    ip, r2, #32                 @  ip<- r2 - 32
11475433072f589b61413e042eddf76e8190a048f71dbuzbee    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
11485433072f589b61413e042eddf76e8190a048f71dbuzbee    mov     r0, r0, asl r2              @  r0<- r0 << r2
11495433072f589b61413e042eddf76e8190a048f71dbuzbee    bx      lr
11509329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND art_quick_shl_long
11515433072f589b61413e042eddf76e8190a048f71dbuzbee
11525433072f589b61413e042eddf76e8190a048f71dbuzbee    /*
11535433072f589b61413e042eddf76e8190a048f71dbuzbee     * Long integer shift.  This is different from the generic 32/64-bit
11545433072f589b61413e042eddf76e8190a048f71dbuzbee     * binary operations because vAA/vBB are 64-bit but vCC (the shift
11555433072f589b61413e042eddf76e8190a048f71dbuzbee     * distance) is 32-bit.  Also, Dalvik requires us to ignore all but the low
11565433072f589b61413e042eddf76e8190a048f71dbuzbee     * 6 bits.
11575433072f589b61413e042eddf76e8190a048f71dbuzbee     * On entry:
11585433072f589b61413e042eddf76e8190a048f71dbuzbee     *   r0: low word
11595433072f589b61413e042eddf76e8190a048f71dbuzbee     *   r1: high word
11605433072f589b61413e042eddf76e8190a048f71dbuzbee     *   r2: shift count
11615433072f589b61413e042eddf76e8190a048f71dbuzbee     */
11625433072f589b61413e042eddf76e8190a048f71dbuzbee    /* shr-long vAA, vBB, vCC */
1163637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan RogersARM_ENTRY art_quick_shr_long            @ ARM code as thumb code requires spills
11645433072f589b61413e042eddf76e8190a048f71dbuzbee    and     r2, r2, #63                 @ r0<- r0 & 0x3f
11655433072f589b61413e042eddf76e8190a048f71dbuzbee    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
11665433072f589b61413e042eddf76e8190a048f71dbuzbee    rsb     r3, r2, #32                 @  r3<- 32 - r2
11675433072f589b61413e042eddf76e8190a048f71dbuzbee    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
11685433072f589b61413e042eddf76e8190a048f71dbuzbee    subs    ip, r2, #32                 @  ip<- r2 - 32
11695433072f589b61413e042eddf76e8190a048f71dbuzbee    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
11705433072f589b61413e042eddf76e8190a048f71dbuzbee    mov     r1, r1, asr r2              @  r1<- r1 >> r2
11715433072f589b61413e042eddf76e8190a048f71dbuzbee    bx      lr
11729329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND art_quick_shr_long
11735433072f589b61413e042eddf76e8190a048f71dbuzbee
11745433072f589b61413e042eddf76e8190a048f71dbuzbee    /*
11755433072f589b61413e042eddf76e8190a048f71dbuzbee     * Long integer shift.  This is different from the generic 32/64-bit
11765433072f589b61413e042eddf76e8190a048f71dbuzbee     * binary operations because vAA/vBB are 64-bit but vCC (the shift
11775433072f589b61413e042eddf76e8190a048f71dbuzbee     * distance) is 32-bit.  Also, Dalvik requires us to ignore all but the low
11785433072f589b61413e042eddf76e8190a048f71dbuzbee     * 6 bits.
11795433072f589b61413e042eddf76e8190a048f71dbuzbee     * On entry:
11805433072f589b61413e042eddf76e8190a048f71dbuzbee     *   r0: low word
11815433072f589b61413e042eddf76e8190a048f71dbuzbee     *   r1: high word
11825433072f589b61413e042eddf76e8190a048f71dbuzbee     *   r2: shift count
11835433072f589b61413e042eddf76e8190a048f71dbuzbee     */
11845433072f589b61413e042eddf76e8190a048f71dbuzbee    /* ushr-long vAA, vBB, vCC */
1185637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan RogersARM_ENTRY art_quick_ushr_long           @ ARM code as thumb code requires spills
11865433072f589b61413e042eddf76e8190a048f71dbuzbee    and     r2, r2, #63                 @ r0<- r0 & 0x3f
11875433072f589b61413e042eddf76e8190a048f71dbuzbee    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
11885433072f589b61413e042eddf76e8190a048f71dbuzbee    rsb     r3, r2, #32                 @  r3<- 32 - r2
11895433072f589b61413e042eddf76e8190a048f71dbuzbee    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
11905433072f589b61413e042eddf76e8190a048f71dbuzbee    subs    ip, r2, #32                 @  ip<- r2 - 32
11915433072f589b61413e042eddf76e8190a048f71dbuzbee    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
11925433072f589b61413e042eddf76e8190a048f71dbuzbee    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
11935433072f589b61413e042eddf76e8190a048f71dbuzbee    bx      lr
11949329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND art_quick_ushr_long
1195fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1196fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    /*
1197fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     * String's indexOf.
1198fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *
1199fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     * On entry:
1200fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *    r0:   string object (known non-null)
120186e4671975752b112b2e8969ac6652c72c8e86c7jeffhao     *    r1:   char to match (known <= 0xFFFF)
1202fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *    r2:   Starting offset in string data
1203fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     */
12049329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersENTRY art_quick_indexof
1205fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    push {r4, r10-r11, lr} @ 4 words of callee saves
12069329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset 16
12079329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r4, 0
12089329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r10, 4
12099329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r11, 8
12109329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset lr, 12
12111d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr   r3, [r0, #MIRROR_STRING_COUNT_OFFSET]
1212848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    add   r0, #MIRROR_STRING_VALUE_OFFSET
1213fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1214fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    /* Clamp start to [0..count] */
1215fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    cmp   r2, #0
1216637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    it    lt
1217fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    movlt r2, #0
1218fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    cmp   r2, r3
1219637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    it    gt
1220fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    movgt r2, r3
1221fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1222fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    /* Save a copy in r12 to later compute result */
1223fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    mov   r12, r0
1224fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1225fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    /* Build pointer to start of data to compare and pre-bias */
1226fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    add   r0, r0, r2, lsl #1
1227fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    sub   r0, #2
1228fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1229fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    /* Compute iteration count */
1230fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    sub   r2, r3, r2
1231fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1232fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    /*
1233fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     * At this point we have:
1234fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *   r0: start of data to test
1235fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *   r1: char to compare
1236fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *   r2: iteration count
1237fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *   r12: original start of string data
1238fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *   r3, r4, r10, r11 available for loading string data
1239fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     */
1240fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1241fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    subs  r2, #4
12425d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    blt   .Lindexof_remainder
1243fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
12445d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lindexof_loop4:
1245fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r3, [r0, #2]!
1246fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r4, [r0, #2]!
1247fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r10, [r0, #2]!
1248fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r11, [r0, #2]!
1249fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    cmp   r3, r1
12505d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    beq   .Lmatch_0
1251fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    cmp   r4, r1
12525d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    beq   .Lmatch_1
1253fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    cmp   r10, r1
12545d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    beq   .Lmatch_2
1255fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    cmp   r11, r1
12565d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    beq   .Lmatch_3
1257fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    subs  r2, #4
12585d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    bge   .Lindexof_loop4
1259fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
12605d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lindexof_remainder:
12615d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    adds  r2, #4
12625d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    beq   .Lindexof_nomatch
1263fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
12645d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lindexof_loop1:
1265fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r3, [r0, #2]!
1266fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    cmp   r3, r1
12675d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    beq   .Lmatch_3
1268fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    subs  r2, #1
12695d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    bne   .Lindexof_loop1
1270fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
12715d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lindexof_nomatch:
1272fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    mov   r0, #-1
1273fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    pop {r4, r10-r11, pc}
1274fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
12755d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lmatch_0:
1276fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    sub   r0, #6
1277fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    sub   r0, r12
1278fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    asr   r0, r0, #1
1279fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    pop {r4, r10-r11, pc}
12805d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lmatch_1:
1281fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    sub   r0, #4
1282fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    sub   r0, r12
1283fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    asr   r0, r0, #1
1284fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    pop {r4, r10-r11, pc}
12855d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lmatch_2:
1286fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    sub   r0, #2
1287fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    sub   r0, r12
1288fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    asr   r0, r0, #1
1289fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    pop {r4, r10-r11, pc}
12905d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lmatch_3:
1291fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    sub   r0, r12
1292fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    asr   r0, r0, #1
1293fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    pop {r4, r10-r11, pc}
12949329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND art_quick_indexof
1295fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1296fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee   /*
1297fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     * String's compareTo.
1298fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *
1299fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     * Requires rARG0/rARG1 to have been previously checked for null.  Will
1300fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     * return negative if this's string is < comp, 0 if they are the
1301fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     * same and positive if >.
1302fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *
1303fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     * On entry:
1304fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *    r0:   this object pointer
1305fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *    r1:   comp object pointer
1306fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *
1307fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     */
1308fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    .extern __memcmp16
13099329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersENTRY art_quick_string_compareto
1310fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    mov    r2, r0         @ this to r2, opening up r0 for return value
1311637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    sub    r0, r2, r1     @ Same?
1312637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    cbnz   r0,1f
1313637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    bx     lr
1314637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers1:                        @ Same strings, return.
1315fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1316fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    push {r4, r7-r12, lr} @ 8 words - keep alignment
13179329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_adjust_cfa_offset 32
13189329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r4, 0
13199329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r7, 4
13209329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r8, 8
13219329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r9, 12
13229329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r10, 16
13239329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r11, 20
13249329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset r12, 24
13259329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    .cfi_rel_offset lr, 28
1326fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
13271d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr    r7, [r2, #MIRROR_STRING_COUNT_OFFSET]
13281d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    ldr    r10, [r1, #MIRROR_STRING_COUNT_OFFSET]
1329848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    add    r2, #MIRROR_STRING_VALUE_OFFSET
1330848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    add    r1, #MIRROR_STRING_VALUE_OFFSET
1331fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1332fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    /*
1333fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     * At this point, we have:
1334fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *    value:  r2/r1
1335fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *    offset: r4/r9
1336fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *    count:  r7/r10
1337fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     * We're going to compute
1338fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *    r11 <- countDiff
1339fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     *    r10 <- minCount
1340fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     */
1341fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     subs  r11, r7, r10
1342637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers     it    ls
1343fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     movls r10, r7
1344fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1345fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     /*
1346fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee      * Note: data pointers point to previous element so we can use pre-index
1347fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee      * mode with base writeback.
1348fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee      */
1349848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao     subs  r2, #2   @ offset to contents[-1]
1350848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao     subs  r1, #2   @ offset to contents[-1]
1351fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1352fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee     /*
1353fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee      * At this point we have:
1354fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee      *   r2: *this string data
1355fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee      *   r1: *comp string data
1356fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee      *   r10: iteration count for comparison
1357fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee      *   r11: value to return if the first part of the string is equal
1358fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee      *   r0: reserved for result
1359fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee      *   r3, r4, r7, r8, r9, r12 available for loading string data
1360fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee      */
1361fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1362fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    subs  r10, #2
13635d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    blt   .Ldo_remainder2
1364fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1365fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee      /*
1366fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee       * Unroll the first two checks so we can quickly catch early mismatch
1367fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee       * on long strings (but preserve incoming alignment)
1368fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee       */
1369fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1370fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r3, [r2, #2]!
1371fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r4, [r1, #2]!
1372fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r7, [r2, #2]!
1373fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r8, [r1, #2]!
1374fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    subs  r0, r3, r4
1375637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    it    eq
1376637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    subseq  r0, r7, r8
13775d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    bne   .Ldone
1378fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    cmp   r10, #28
13795d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    bgt   .Ldo_memcmp16
1380fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    subs  r10, #3
13815d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    blt   .Ldo_remainder
1382fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
13835d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lloopback_triple:
1384fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r3, [r2, #2]!
1385fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r4, [r1, #2]!
1386fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r7, [r2, #2]!
1387fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r8, [r1, #2]!
1388fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r9, [r2, #2]!
1389fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r12,[r1, #2]!
1390fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    subs  r0, r3, r4
1391637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    it    eq
1392637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    subseq  r0, r7, r8
1393637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    it    eq
1394637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    subseq  r0, r9, r12
13955d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    bne   .Ldone
1396fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    subs  r10, #3
13975d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    bge   .Lloopback_triple
1398fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
13995d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Ldo_remainder:
1400fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    adds  r10, #3
14015d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    beq   .Lreturn_diff
1402fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
14035d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lloopback_single:
1404fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r3, [r2, #2]!
1405fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    ldrh  r4, [r1, #2]!
1406fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    subs  r0, r3, r4
14075d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    bne   .Ldone
1408fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    subs  r10, #1
14095d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    bne   .Lloopback_single
1410fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
14115d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Lreturn_diff:
1412fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    mov   r0, r11
1413fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    pop   {r4, r7-r12, pc}
1414fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
14155d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Ldo_remainder2:
1416fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    adds  r10, #2
14175d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    bne   .Lloopback_single
1418fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    mov   r0, r11
1419fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    pop   {r4, r7-r12, pc}
1420fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1421fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    /* Long string case */
14225d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Ldo_memcmp16:
1423fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    mov   r7, r11
1424fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    add   r0, r2, #2
1425fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    add   r1, r1, #2
1426fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    mov   r2, r10
1427fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    bl    __memcmp16
1428fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    cmp   r0, #0
1429637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    it    eq
1430fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    moveq r0, r7
14315d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers.Ldone:
1432fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee    pop   {r4, r7-r12, pc}
14339329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian RogersEND art_quick_string_compareto
14345667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
14355667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    /* Assembly routines used to handle ABI differences. */
14365667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
14375667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    /* double fmod(double a, double b) */
14385667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .extern fmod
14395667fdbb6e441dee7534ade18b628ed396daf593Zheng XuENTRY art_quick_fmod
14405667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    push  {lr}
14415667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset 4
14425667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_rel_offset lr, 0
14435667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    sub   sp, #4
14445667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset 4
14455667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vmov  r0, r1, d0
14465667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vmov  r2, r3, d1
14475667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    bl    fmod
14485667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vmov  d0, r0, r1
14495667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    add   sp, #4
14505667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset -4
14515667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    pop   {pc}
14525667fdbb6e441dee7534ade18b628ed396daf593Zheng XuEND art_quick_fmod
14535667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
14545667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    /* float fmodf(float a, float b) */
14555667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu     .extern fmodf
14565667fdbb6e441dee7534ade18b628ed396daf593Zheng XuENTRY art_quick_fmodf
14575667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    push  {lr}
14585667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset 4
14595667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_rel_offset lr, 0
14605667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    sub   sp, #4
14615667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset 4
14625667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vmov  r0, r1, d0
14635667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    bl    fmodf
14645667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vmov  s0, r0
14655667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    add   sp, #4
14665667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .cfi_adjust_cfa_offset -4
14675667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    pop   {pc}
14685667fdbb6e441dee7534ade18b628ed396daf593Zheng XuEND art_quick_fmod
14695667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
14705667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    /* int64_t art_d2l(double d) */
14715667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .extern art_d2l
14725667fdbb6e441dee7534ade18b628ed396daf593Zheng XuENTRY art_quick_d2l
14735667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vmov  r0, r1, d0
14745667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    b     art_d2l
14755667fdbb6e441dee7534ade18b628ed396daf593Zheng XuEND art_quick_d2l
14765667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu
14775667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    /* int64_t art_f2l(float f) */
14785667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    .extern art_f2l
14795667fdbb6e441dee7534ade18b628ed396daf593Zheng XuENTRY art_quick_f2l
14805667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    vmov  r0, s0
14815667fdbb6e441dee7534ade18b628ed396daf593Zheng Xu    b     art_f2l
14825667fdbb6e441dee7534ade18b628ed396daf593Zheng XuEND art_quick_f2l
1483