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