1b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith/* 2b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Copyright (C) 2014 The Android Open Source Project 3b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * 4b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Licensed under the Apache License, Version 2.0 (the "License"); 5b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * you may not use this file except in compliance with the License. 6b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * You may obtain a copy of the License at 7b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * 8b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * http://www.apache.org/licenses/LICENSE-2.0 9b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * 10b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Unless required by applicable law or agreed to in writing, software 11b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * distributed under the License is distributed on an "AS IS" BASIS, 12b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * See the License for the specific language governing permissions and 14b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * limitations under the License. 15b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 16b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 17b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith#include "asm_support_arm64.S" 18b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 19b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith#include "arch/quick_alloc_entrypoints.S" 20b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 21b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 22b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith /* 23b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Macro that sets up the callee save frame to conform with 24b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Runtime::CreateCalleeSaveMethod(kSaveAll) 25b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 26b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro SETUP_SAVE_ALL_CALLEE_SAVE_FRAME 27b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu adrp xIP0, :got:_ZN3art7Runtime9instance_E 28b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr xIP0, [xIP0, #:got_lo12:_ZN3art7Runtime9instance_E] 29b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 30b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Our registers aren't intermixed - just spill in order. 31b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr xIP0, [xIP0] // xIP0 = & (art::Runtime * art::Runtime.instance_) . 32b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 33b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // xIP0 = (ArtMethod*) Runtime.instance_.callee_save_methods[kRefAndArgs] . 34ab088118d33caafb00815ab72ac0fd7374169f64Hiroshi Yamauchi THIS_LOAD_REQUIRES_READ_BARRIER 35b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr xIP0, [xIP0, RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET ] 36b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 37b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu sub sp, sp, #176 38b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_adjust_cfa_offset 176 39b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 405c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Ugly compile-time check, but we only have the preprocessor. 41b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 176) 425c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#error "SAVE_ALL_CALLEE_SAVE_FRAME(ARM64) size not as expected." 435c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif 445c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 45b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // FP callee-saves 46b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp d8, d9, [sp, #8] 47b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp d10, d11, [sp, #24] 48b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp d12, d13, [sp, #40] 49b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp d14, d15, [sp, #56] 50b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 51b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // Reserved registers 52b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp xSELF, xSUSPEND, [sp, #72] 53b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x18, 72 54b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x19, 80 5503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 56b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // callee-saves 57b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x20, x21, [sp, #88] 58b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x20, 88 59b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x21, 96 6003906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 61b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x22, x23, [sp, #104] 62b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x22, 104 63b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x23, 112 6403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 65b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x24, x25, [sp, #120] 66b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x24, 120 67b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x25, 128 6803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 69b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x26, x27, [sp, #136] 70b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x26, 136 71b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x27, 144 7203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 73b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x28, x29, [sp, #152] 74b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x28, 152 75b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x29, 160 76b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 77b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu str xLR, [sp, #168] 78b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x30, 168 79b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 80b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Loads appropriate callee-save-method 81b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu str xIP0, [sp] // Store ArtMethod* Runtime::callee_save_methods_[kRefsAndArgs] 82b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 83b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 84b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith /* 85b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Macro that sets up the callee save frame to conform with 86b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Runtime::CreateCalleeSaveMethod(kRefsOnly). 87b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 88b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro SETUP_REF_ONLY_CALLEE_SAVE_FRAME 89b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu adrp xIP0, :got:_ZN3art7Runtime9instance_E 90b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr xIP0, [xIP0, #:got_lo12:_ZN3art7Runtime9instance_E] 915c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 925c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Our registers aren't intermixed - just spill in order. 93b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr xIP0, [xIP0] // xIP0 = & (art::Runtime * art::Runtime.instance_) . 945c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 95b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // xIP0 = (ArtMethod*) Runtime.instance_.callee_save_methods[kRefAndArgs] . 96ab088118d33caafb00815ab72ac0fd7374169f64Hiroshi Yamauchi THIS_LOAD_REQUIRES_READ_BARRIER 97b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr xIP0, [xIP0, RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET ] 985c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 99b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu sub sp, sp, #96 100b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_adjust_cfa_offset 96 1015c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 1025c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Ugly compile-time check, but we only have the preprocessor. 103b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 96) 1045c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#error "REFS_ONLY_CALLEE_SAVE_FRAME(ARM64) size not as expected." 1055c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif 1065c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 107b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // Callee-saves 108b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x20, x21, [sp, #8] 109b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x20, 8 110b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x21, 16 1115c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 112b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x22, x23, [sp, #24] 113b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x22, 24 114b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x23, 32 1155c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 116b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x24, x25, [sp, #40] 117b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x24, 40 118b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x25, 48 1195c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 120b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x26, x27, [sp, #56] 121b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x26, 56 122b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x27, 64 1235c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 124b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x28, x29, [sp, #72] 125b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x28, 72 126b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x29, 80 1275c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 128b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // LR 129b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu str xLR, [sp, #88] 130b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x30, 88 1315c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 132b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // Save xSELF to xETR. 133b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov xETR, xSELF 1345c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 1355c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Loads appropriate callee-save-method 136b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu str xIP0, [sp] // Store ArtMethod* Runtime::callee_save_methods_[kRefsAndArgs] 137b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 138b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 139b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu// TODO: Probably no need to restore registers preserved by aapcs64. 140b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro RESTORE_REF_ONLY_CALLEE_SAVE_FRAME 141b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // Restore xSELF. 142b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov xSELF, xETR 14300c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe 144b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // Callee-saves 145b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x20, x21, [sp, #8] 14600c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe .cfi_restore x20 14700c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe .cfi_restore x21 14800c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe 149b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x22, x23, [sp, #24] 15000c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe .cfi_restore x22 15100c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe .cfi_restore x23 15200c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe 153b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x24, x25, [sp, #40] 15400c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe .cfi_restore x24 15500c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe .cfi_restore x25 15600c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe 157b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x26, x27, [sp, #56] 15800c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe .cfi_restore x26 15900c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe .cfi_restore x27 16000c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe 161b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x28, x29, [sp, #72] 16200c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe .cfi_restore x28 16300c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe .cfi_restore x29 16400c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe 165b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // LR 166b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr xLR, [sp, #88] 16700c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe .cfi_restore x30 16800c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe 169b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu add sp, sp, #96 170b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_adjust_cfa_offset -96 171b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 172b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 173d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe.macro POP_REF_ONLY_CALLEE_SAVE_FRAME 174b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // Restore xSELF as it might be scratched. 175b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov xSELF, xETR 176b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // ETR 177b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr xETR, [sp, #16] 178b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_restore x21 179b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu 180b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu add sp, sp, #96 181b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_adjust_cfa_offset -96 182d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe.endm 183d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 184b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro RESTORE_REF_ONLY_CALLEE_SAVE_FRAME_AND_RETURN 18548241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu RESTORE_REF_ONLY_CALLEE_SAVE_FRAME 18648241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu ret 187b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 188b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 189b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 190b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME_INTERNAL 191b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu sub sp, sp, #224 192b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_adjust_cfa_offset 224 193b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1945c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Ugly compile-time check, but we only have the preprocessor. 195b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu#if (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE != 224) 1965c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#error "REFS_AND_ARGS_CALLEE_SAVE_FRAME(ARM64) size not as expected." 1975c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif 1985c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 199b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // FP args 200b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp d0, d1, [sp, #16] 201b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp d2, d3, [sp, #32] 202b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp d4, d5, [sp, #48] 203b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp d6, d7, [sp, #64] 204b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu 205b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // args and x20(callee-save) 206b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x1, x2, [sp, #80] 207b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x1, 80 208b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x2, 88 209b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu 210b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x3, x4, [sp, #96] 211b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x3, 96 212b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x4, 104 213b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu 214b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x5, x6, [sp, #112] 215b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x5, 112 216b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x6, 120 217b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu 218b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x7, x20, [sp, #128] 219b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x7, 128 220b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x20, 136 221b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu 222b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // Callee-saves. 223b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x21, x22, [sp, #144] 224b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x21, 144 225b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x22, 152 226b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu 227b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x23, x24, [sp, #160] 228b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x23, 160 229b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x24, 168 230b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu 231b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x25, x26, [sp, #176] 232b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x25, 176 233b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x26, 184 234b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu 235b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x27, x28, [sp, #192] 236b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x27, 192 237b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x28, 200 238b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu 239b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // x29(callee-save) and LR 240b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x29, xLR, [sp, #208] 241b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x29, 208 242b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_rel_offset x30, 216 243b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu 244b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // Save xSELF to xETR. 245b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov xETR, xSELF 246b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 247b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 248b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith /* 249b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Macro that sets up the callee save frame to conform with 250b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Runtime::CreateCalleeSaveMethod(kRefsAndArgs). 251b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * 252b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * TODO This is probably too conservative - saving FP & LR. 253b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 254b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME 255b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu adrp xIP0, :got:_ZN3art7Runtime9instance_E 256b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr xIP0, [xIP0, #:got_lo12:_ZN3art7Runtime9instance_E] 257b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 258b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Our registers aren't intermixed - just spill in order. 259b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr xIP0, [xIP0] // xIP0 = & (art::Runtime * art::Runtime.instance_) . 260b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 261b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // xIP0 = (ArtMethod*) Runtime.instance_.callee_save_methods[kRefAndArgs] . 262ab088118d33caafb00815ab72ac0fd7374169f64Hiroshi Yamauchi THIS_LOAD_REQUIRES_READ_BARRIER 263b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr xIP0, [xIP0, RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET ] 264b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 265b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME_INTERNAL 266b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 267b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu str xIP0, [sp] // Store ArtMethod* Runtime::callee_save_methods_[kRefsAndArgs] 268b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 269b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 270b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu// TODO: Probably no need to restore registers preserved by aapcs64. 271b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME 272b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // Restore xSELF. 273b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov xSELF, xETR 274b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 275b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // FP args 276b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp d0, d1, [sp, #16] 277b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp d2, d3, [sp, #32] 278b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp d4, d5, [sp, #48] 279b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp d6, d7, [sp, #64] 280b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu 281b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // args and x20(callee-save) 282b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x1, x2, [sp, #80] 28303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x1 28403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x2 28503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 286b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x3, x4, [sp, #96] 28703906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x3 28803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x4 28903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 290b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x5, x6, [sp, #112] 29103906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x5 29203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x6 29303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 294b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x7, x20, [sp, #128] 29503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x7 29603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x20 29703906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 298b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // Callee-saves. 299b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x21, x22, [sp, #144] 30003906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x21 30103906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x22 30203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 303b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x23, x24, [sp, #160] 30403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x23 30503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x24 30603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 307b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x25, x26, [sp, #176] 30803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x25 30903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x26 31003906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 311b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x27, x28, [sp, #192] 31203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x27 31303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x28 31403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 315b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // x29(callee-save) and LR 316b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x29, xLR, [sp, #208] 31703906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x29 31803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x30 319b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 320b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu add sp, sp, #224 321b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu .cfi_adjust_cfa_offset -224 322b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 323b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 324b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro RETURN_IF_RESULT_IS_ZERO 32500c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe cbnz x0, 1f // result non-zero branch over 32600c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe ret // return 32700c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe1: 328b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 329b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 330b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro RETURN_IF_RESULT_IS_NON_ZERO 33100c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe cbz x0, 1f // result zero branch over 33200c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe ret // return 33300c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe1: 334b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 335b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 336b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith /* 337b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending 338b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * exception is Thread::Current()->exception_ 339b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 340b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro DELIVER_PENDING_EXCEPTION 341b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith SETUP_SAVE_ALL_CALLEE_SAVE_FRAME 342b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x0, xSELF 343b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x1, sp 344b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 345b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Point of no return. 346b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith b artDeliverPendingExceptionFromCode // artDeliverPendingExceptionFromCode(Thread*, SP) 347b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith brk 0 // Unreached 348b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 349b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 3506e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe.macro RETURN_OR_DELIVER_PENDING_EXCEPTION_REG reg 3516e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe ldr \reg, [xSELF, # THREAD_EXCEPTION_OFFSET] // Get exception field. 3526e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe cbnz \reg, 1f 353b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ret 354b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith1: 355b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith DELIVER_PENDING_EXCEPTION 356b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 357b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 3586e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe.macro RETURN_OR_DELIVER_PENDING_EXCEPTION 359b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu RETURN_OR_DELIVER_PENDING_EXCEPTION_REG xIP0 3606e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe.endm 3616e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe 3626e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe// Same as above with x1. This is helpful in stubs that want to avoid clobbering another register. 3636e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe.macro RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 3646e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe RETURN_OR_DELIVER_PENDING_EXCEPTION_REG x1 3656e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe.endm 3666e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe 3676e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe.macro RETURN_IF_W0_IS_ZERO_OR_DELIVER 3686e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe cbnz w0, 1f // result non-zero branch over 3696e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe ret // return 3706e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe1: 3716e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe DELIVER_PENDING_EXCEPTION 3726e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe.endm 3736e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe 374b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro NO_ARG_RUNTIME_EXCEPTION c_name, cxx_name 375b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith .extern \cxx_name 376b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithENTRY \c_name 3775c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context 378b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov x0, xSELF // pass Thread::Current 3795c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe mov x1, sp // pass SP 3805c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe b \cxx_name // \cxx_name(Thread*, SP) 381b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithEND \c_name 382b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 383b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 384b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro ONE_ARG_RUNTIME_EXCEPTION c_name, cxx_name 385b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith .extern \cxx_name 386b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithENTRY \c_name 38775b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context. 388b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov x1, xSELF // pass Thread::Current. 38975b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu mov x2, sp // pass SP. 3905c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe b \cxx_name // \cxx_name(arg, Thread*, SP). 391b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith brk 0 392b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithEND \c_name 393b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 394b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 395b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro TWO_ARG_RUNTIME_EXCEPTION c_name, cxx_name 396b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith .extern \cxx_name 397b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithENTRY \c_name 398b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context 399b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov x2, xSELF // pass Thread::Current 4005c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe mov x3, sp // pass SP 4015c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe b \cxx_name // \cxx_name(arg1, arg2, Thread*, SP) 402b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith brk 0 403b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithEND \c_name 404b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 405b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 406b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith /* 407b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Called by managed code, saves callee saves and then calls artThrowException 408b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception. 409b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 410b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithONE_ARG_RUNTIME_EXCEPTION art_quick_deliver_exception, artDeliverExceptionFromCode 411b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 412b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith /* 413b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Called by managed code to create and deliver a NullPointerException. 414b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 415b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithNO_ARG_RUNTIME_EXCEPTION art_quick_throw_null_pointer_exception, artThrowNullPointerExceptionFromCode 416b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 417b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith /* 418b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Called by managed code to create and deliver an ArithmeticException. 419b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 420b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithNO_ARG_RUNTIME_EXCEPTION art_quick_throw_div_zero, artThrowDivZeroFromCode 421b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 422b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith /* 423b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds 424b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * index, arg2 holds limit. 425b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 426b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithTWO_ARG_RUNTIME_EXCEPTION art_quick_throw_array_bounds, artThrowArrayBoundsFromCode 427b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 428b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith /* 429b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Called by managed code to create and deliver a StackOverflowError. 430b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 431b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithNO_ARG_RUNTIME_EXCEPTION art_quick_throw_stack_overflow, artThrowStackOverflowFromCode 432b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 433b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith /* 434b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Called by managed code to create and deliver a NoSuchMethodError. 435b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 436b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithONE_ARG_RUNTIME_EXCEPTION art_quick_throw_no_such_method, artThrowNoSuchMethodFromCode 437b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 438b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith /* 439b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * All generated callsites for interface invokes and invocation slow paths will load arguments 44051f763506c7bb34420242e88e1631550f94d6417Andreas Gampe * as usual - except instead of loading arg0/x0 with the target Method*, arg0/x0 will contain 44151f763506c7bb34420242e88e1631550f94d6417Andreas Gampe * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the 442b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * stack and call the appropriate C helper. 44351f763506c7bb34420242e88e1631550f94d6417Andreas Gampe * NOTE: "this" is first visible argument of the target, and so can be found in arg1/x1. 444b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * 44551f763506c7bb34420242e88e1631550f94d6417Andreas Gampe * The helper will attempt to locate the target and return a 128-bit result in x0/x1 consisting 446b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * of the target Method* in x0 and method->code_ in x1. 447b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * 44851f763506c7bb34420242e88e1631550f94d6417Andreas Gampe * If unsuccessful, the helper will return NULL/????. There will be a pending exception in the 449b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * thread and we branch to another stub to deliver it. 450b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * 451b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * On success this wrapper will restore arguments and *jump* to the target, leaving the lr 452b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * pointing back to the original caller. 45351f763506c7bb34420242e88e1631550f94d6417Andreas Gampe * 45451f763506c7bb34420242e88e1631550f94d6417Andreas Gampe * Adapted from ARM32 code. 45551f763506c7bb34420242e88e1631550f94d6417Andreas Gampe * 456b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu * Clobbers xIP0. 457b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 458b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro INVOKE_TRAMPOLINE c_name, cxx_name 459b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith .extern \cxx_name 460b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithENTRY \c_name 46151f763506c7bb34420242e88e1631550f94d6417Andreas Gampe SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save callee saves in case allocation triggers GC 46251f763506c7bb34420242e88e1631550f94d6417Andreas Gampe // Helper signature is always 46351f763506c7bb34420242e88e1631550f94d6417Andreas Gampe // (method_idx, *this_object, *caller_method, *self, sp) 46451f763506c7bb34420242e88e1631550f94d6417Andreas Gampe 46541c507a9dae44b8329a857da3d9810fab2e9ddc6Alexei Zavjalov ldr w2, [sp, #FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE] // pass caller Method* 46651f763506c7bb34420242e88e1631550f94d6417Andreas Gampe mov x3, xSELF // pass Thread::Current 46751f763506c7bb34420242e88e1631550f94d6417Andreas Gampe mov x4, sp 46851f763506c7bb34420242e88e1631550f94d6417Andreas Gampe bl \cxx_name // (method_idx, this, caller, Thread*, SP) 469b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov xIP0, x1 // save Method*->code_ 47051f763506c7bb34420242e88e1631550f94d6417Andreas Gampe RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME 47151f763506c7bb34420242e88e1631550f94d6417Andreas Gampe cbz x0, 1f // did we find the target? if not go to exception delivery 472b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu br xIP0 // tail call to target 47351f763506c7bb34420242e88e1631550f94d6417Andreas Gampe1: 47451f763506c7bb34420242e88e1631550f94d6417Andreas Gampe DELIVER_PENDING_EXCEPTION 475b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithEND \c_name 476b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 477b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 478b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithINVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline, artInvokeInterfaceTrampoline 479b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithINVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck 480b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 481b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithINVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck 482b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithINVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck 483b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithINVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck 484b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithINVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck 485b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 48603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 48703906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe.macro INVOKE_STUB_CREATE_FRAME 48803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 489b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng XuSAVE_SIZE=6*8 // x4, x5, xSUSPEND, SP, LR & FP saved. 490cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas GampeSAVE_SIZE_AND_METHOD=SAVE_SIZE+STACK_REFERENCE_SIZE 491cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe 49203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 49348241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu mov x9, sp // Save stack pointer. 49403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_register sp,x9 49503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 49648241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu add x10, x2, # SAVE_SIZE_AND_METHOD // calculate size of frame. 49748241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu sub x10, sp, x10 // Calculate SP position - saves + ArtMethod* + args 49848241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu and x10, x10, # ~0xf // Enforce 16 byte stack alignment. 49948241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu mov sp, x10 // Set new SP. 50003906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 50148241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu sub x10, x9, #SAVE_SIZE // Calculate new FP (later). Done here as we must move SP 50248241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu .cfi_def_cfa_register x10 // before this. 50303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_adjust_cfa_offset SAVE_SIZE 50403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 505b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu stp x9, xSUSPEND, [x10, #32] // Save old stack pointer and xSUSPEND 50603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_rel_offset sp, 32 507cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe .cfi_rel_offset x19, 40 50803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 50948241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu stp x4, x5, [x10, #16] // Save result and shorty addresses. 51003906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_rel_offset x4, 16 51103906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_rel_offset x5, 24 51203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 51348241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu stp xFP, xLR, [x10] // Store LR & FP. 51403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_rel_offset x29, 0 51503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_rel_offset x30, 8 51603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 51748241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu mov xFP, x10 // Use xFP now, as it's callee-saved. 51803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_def_cfa_register x29 51948241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu mov xSELF, x3 // Move thread pointer into SELF register. 52048241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu mov wSUSPEND, #SUSPEND_CHECK_INTERVAL // reset wSUSPEND to suspend check interval 52103906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 52203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // Copy arguments into stack frame. 52303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // Use simple copy routine for now. 52403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // 4 bytes per slot. 52503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // X1 - source address 52603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // W2 - args length 52703906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // X9 - destination address. 52803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // W10 - temporary 529cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe add x9, sp, #4 // Destination address is bottom of stack + NULL. 53003906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 53103906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // Use \@ to differentiate between macro invocations. 53203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe.LcopyParams\@: 53303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe cmp w2, #0 53403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe beq .LendCopyParams\@ 53503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe sub w2, w2, #4 // Need 65536 bytes of range. 53603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe ldr w10, [x1, x2] 53703906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe str w10, [x9, x2] 53803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 53903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe b .LcopyParams\@ 54003906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 54103906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe.LendCopyParams\@: 54203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 543cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe // Store NULL into StackReference<Method>* at bottom of frame. 544cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe str wzr, [sp] 54503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 546cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe#if (STACK_REFERENCE_SIZE != 4) 547cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe#error "STACK_REFERENCE_SIZE(ARM64) size not as expected." 548cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe#endif 54903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe.endm 55003906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 55103906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe.macro INVOKE_STUB_CALL_AND_RETURN 55203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 55303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // load method-> METHOD_QUICK_CODE_OFFSET 554e832e64a7e82d7f72aedbd7d798fb929d458ee8fMathieu Chartier ldr x9, [x0 , #METHOD_QUICK_CODE_OFFSET_64] 55503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // Branch to method. 55603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe blr x9 55703906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 55803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // Restore return value address and shorty address. 55903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe ldp x4,x5, [xFP, #16] 56003906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x4 56103906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x5 56203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 56303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // Store result (w0/x0/s0/d0) appropriately, depending on resultType. 56403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe ldrb w10, [x5] 56503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 56603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // Don't set anything for a void type. 56703906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe cmp w10, #'V' 56803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe beq .Lexit_art_quick_invoke_stub\@ 56903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 57003906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe cmp w10, #'D' 57103906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe bne .Lreturn_is_float\@ 57203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe str d0, [x4] 57303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe b .Lexit_art_quick_invoke_stub\@ 57403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 57503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe.Lreturn_is_float\@: 57603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe cmp w10, #'F' 57703906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe bne .Lreturn_is_int\@ 57803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe str s0, [x4] 57903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe b .Lexit_art_quick_invoke_stub\@ 58003906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 58103906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe // Just store x0. Doesn't matter if it is 64 or 32 bits. 58203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe.Lreturn_is_int\@: 58303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe str x0, [x4] 58403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 58503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe.Lexit_art_quick_invoke_stub\@: 586b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldp x2, xSUSPEND, [xFP, #32] // Restore stack pointer and xSUSPEND. 587cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe .cfi_restore x19 58803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe mov sp, x2 58903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore sp 59003906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 591d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe ldp xFP, xLR, [xFP] // Restore old frame pointer and link register. 59203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x29 59303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe .cfi_restore x30 59403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 59503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe ret 59603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 59703906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe.endm 59803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 59903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 600b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith/* 601b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * extern"C" void art_quick_invoke_stub(ArtMethod *method, x0 602b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * uint32_t *args, x1 603b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * uint32_t argsize, w2 604b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Thread *self, x3 605b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * JValue *result, x4 606b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * char *shorty); x5 607b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * +----------------------+ 608b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | | 609b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | C/C++ frame | 610b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | LR'' | 611b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | FP'' | <- SP' 612b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * +----------------------+ 613b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * +----------------------+ 614b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu * | x19 | <- Used as wSUSPEND, won't be restored by managed code. 615b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | SP' | 616b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X5 | 617b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X4 | Saved registers 618b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | LR' | 619b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | FP' | <- FP 620b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * +----------------------+ 621b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | uint32_t out[n-1] | 622b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | : : | Outs 623b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | uint32_t out[0] | 624cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe * | StackRef<ArtMethod> | <- SP value=null 625b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * +----------------------+ 626b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * 627b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Outgoing registers: 628b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * x0 - Method* 629b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * x1-x7 - integer parameters. 630b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * d0-d7 - Floating point parameters. 631b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * xSELF = self 63248241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu * wSUSPEND = suspend count 633b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * SP = & of ArtMethod* 634b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * x1 = "this" pointer. 635b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * 636b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 637b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithENTRY art_quick_invoke_stub 638b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Spill registers as per AACPS64 calling convention. 63903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe INVOKE_STUB_CREATE_FRAME 640b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 641b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Fill registers x/w1 to x/w7 and s/d0 to s/d7 with parameters. 642b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Parse the passed shorty to determine which register to load. 643b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Load addresses for routines that load WXSD registers. 644b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith adr x11, .LstoreW2 645b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith adr x12, .LstoreX2 646b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith adr x13, .LstoreS0 647b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith adr x14, .LstoreD0 648b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 649b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Initialize routine offsets to 0 for integers and floats. 650b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // x8 for integers, x15 for floating point. 651b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x8, #0 652b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x15, #0 653b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 654b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith add x10, x5, #1 // Load shorty address, plus one to skip return value. 655b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldr w1, [x9],#4 // Load "this" parameter, and increment arg pointer. 656b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 657b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Loop to fill registers. 658b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LfillRegisters: 659b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldrb w17, [x10], #1 // Load next character in signature, and increment. 660b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cbz w17, .LcallFunction // Exit at end of signature. Shorty 0 terminated. 661b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 662b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cmp w17, #'F' // is this a float? 663b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith bne .LisDouble 664b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 665b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cmp x15, # 8*12 // Skip this load if all registers full. 66603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe beq .Ladvance4 667b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 668b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith add x17, x13, x15 // Calculate subroutine to jump to. 669b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith br x17 670b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 671b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LisDouble: 672b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cmp w17, #'D' // is this a double? 673b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith bne .LisLong 674b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 675b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cmp x15, # 8*12 // Skip this load if all registers full. 67603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe beq .Ladvance8 677b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 678b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith add x17, x14, x15 // Calculate subroutine to jump to. 679b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith br x17 680b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 681b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LisLong: 682b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cmp w17, #'J' // is this a long? 683b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith bne .LisOther 684b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 6859de65ff3a9c49b91d80be292020f012f3d0a24efAndreas Gampe cmp x8, # 6*12 // Skip this load if all registers full. 68603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe beq .Ladvance8 687b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 688b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith add x17, x12, x8 // Calculate subroutine to jump to. 689b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith br x17 690b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 691b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LisOther: // Everything else takes one vReg. 6929de65ff3a9c49b91d80be292020f012f3d0a24efAndreas Gampe cmp x8, # 6*12 // Skip this load if all registers full. 69303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe beq .Ladvance4 69403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 695b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith add x17, x11, x8 // Calculate subroutine to jump to. 696b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith br x17 697b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 69803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe.Ladvance4: 69903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe add x9, x9, #4 70003906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe b .LfillRegisters 70103906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 70203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe.Ladvance8: 70303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe add x9, x9, #8 70403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe b .LfillRegisters 70503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 706b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// Macro for loading a parameter into a register. 707b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// counter - the register with offset into these tables 708b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// size - the size of the register - 4 or 8 bytes. 709b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// register - the name of the register to be loaded. 710b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro LOADREG counter size register return 711b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldr \register , [x9], #\size 712b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith add \counter, \counter, 12 713b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith b \return 714b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 715b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 716b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// Store ints. 717b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LstoreW2: 718b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 4 w2 .LfillRegisters 719b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 4 w3 .LfillRegisters 720b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 4 w4 .LfillRegisters 721b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 4 w5 .LfillRegisters 722b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 4 w6 .LfillRegisters 723b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 4 w7 .LfillRegisters 724b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 725b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// Store longs. 726b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LstoreX2: 727b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 8 x2 .LfillRegisters 728b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 8 x3 .LfillRegisters 729b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 8 x4 .LfillRegisters 730b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 8 x5 .LfillRegisters 731b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 8 x6 .LfillRegisters 732b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 8 x7 .LfillRegisters 733b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 734b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// Store singles. 735b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LstoreS0: 736b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s0 .LfillRegisters 737b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s1 .LfillRegisters 738b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s2 .LfillRegisters 739b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s3 .LfillRegisters 740b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s4 .LfillRegisters 741b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s5 .LfillRegisters 742b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s6 .LfillRegisters 743b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s7 .LfillRegisters 744b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 745b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// Store doubles. 746b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LstoreD0: 747b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d0 .LfillRegisters 748b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d1 .LfillRegisters 749b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d2 .LfillRegisters 750b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d3 .LfillRegisters 751b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d4 .LfillRegisters 752b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d5 .LfillRegisters 753b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d6 .LfillRegisters 754b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d7 .LfillRegisters 755b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 756b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 757b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LcallFunction: 758b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 75903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe INVOKE_STUB_CALL_AND_RETURN 760b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 761b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithEND art_quick_invoke_stub 762b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 763b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith/* extern"C" 764b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * void art_quick_invoke_static_stub(ArtMethod *method, x0 765b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * uint32_t *args, x1 766b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * uint32_t argsize, w2 767b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Thread *self, x3 768b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * JValue *result, x4 769b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * char *shorty); x5 770b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 771b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithENTRY art_quick_invoke_static_stub 772b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Spill registers as per AACPS64 calling convention. 77303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe INVOKE_STUB_CREATE_FRAME 774b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 775b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Fill registers x/w1 to x/w7 and s/d0 to s/d7 with parameters. 776b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Parse the passed shorty to determine which register to load. 777b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Load addresses for routines that load WXSD registers. 778b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith adr x11, .LstoreW1_2 779b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith adr x12, .LstoreX1_2 780b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith adr x13, .LstoreS0_2 781b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith adr x14, .LstoreD0_2 782b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 783b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Initialize routine offsets to 0 for integers and floats. 784b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // x8 for integers, x15 for floating point. 785b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x8, #0 786b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x15, #0 787b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 788b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith add x10, x5, #1 // Load shorty address, plus one to skip return value. 789b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 790b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Loop to fill registers. 791b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LfillRegisters2: 792b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldrb w17, [x10], #1 // Load next character in signature, and increment. 793b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cbz w17, .LcallFunction2 // Exit at end of signature. Shorty 0 terminated. 794b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 795b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cmp w17, #'F' // is this a float? 796b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith bne .LisDouble2 797b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 798b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cmp x15, # 8*12 // Skip this load if all registers full. 79903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe beq .Ladvance4_2 800b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 801b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith add x17, x13, x15 // Calculate subroutine to jump to. 802b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith br x17 803b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 804b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LisDouble2: 805b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cmp w17, #'D' // is this a double? 806b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith bne .LisLong2 807b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 808b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cmp x15, # 8*12 // Skip this load if all registers full. 80903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe beq .Ladvance8_2 810b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 811b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith add x17, x14, x15 // Calculate subroutine to jump to. 812b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith br x17 813b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 814b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LisLong2: 815b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cmp w17, #'J' // is this a long? 816b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith bne .LisOther2 817b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 818b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cmp x8, # 7*12 // Skip this load if all registers full. 81903906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe beq .Ladvance8_2 820b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 821b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith add x17, x12, x8 // Calculate subroutine to jump to. 822b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith br x17 823b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 824b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LisOther2: // Everything else takes one vReg. 825b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cmp x8, # 7*12 // Skip this load if all registers full. 82603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe beq .Ladvance4_2 82703906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 828b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith add x17, x11, x8 // Calculate subroutine to jump to. 829b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith br x17 830b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 83103906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe.Ladvance4_2: 83203906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe add x9, x9, #4 83303906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe b .LfillRegisters2 83403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 83503906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe.Ladvance8_2: 83603906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe add x9, x9, #8 83703906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe b .LfillRegisters2 83803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 839b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// Store ints. 840b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LstoreW1_2: 841b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 4 w1 .LfillRegisters2 842b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 4 w2 .LfillRegisters2 843b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 4 w3 .LfillRegisters2 844b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 4 w4 .LfillRegisters2 845b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 4 w5 .LfillRegisters2 846b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 4 w6 .LfillRegisters2 847b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 4 w7 .LfillRegisters2 848b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 849b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// Store longs. 850b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LstoreX1_2: 851b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 8 x1 .LfillRegisters2 852b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 8 x2 .LfillRegisters2 853b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 8 x3 .LfillRegisters2 854b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 8 x4 .LfillRegisters2 855b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 8 x5 .LfillRegisters2 856b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 8 x6 .LfillRegisters2 857b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x8 8 x7 .LfillRegisters2 858b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 859b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// Store singles. 860b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LstoreS0_2: 861b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s0 .LfillRegisters2 862b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s1 .LfillRegisters2 863b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s2 .LfillRegisters2 864b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s3 .LfillRegisters2 865b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s4 .LfillRegisters2 866b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s5 .LfillRegisters2 867b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s6 .LfillRegisters2 868b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 4 s7 .LfillRegisters2 869b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 870b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// Store doubles. 871b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LstoreD0_2: 872b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d0 .LfillRegisters2 873b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d1 .LfillRegisters2 874b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d2 .LfillRegisters2 875b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d3 .LfillRegisters2 876b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d4 .LfillRegisters2 877b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d5 .LfillRegisters2 878b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d6 .LfillRegisters2 879b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith LOADREG x15 8 d7 .LfillRegisters2 880b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 881b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 882b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.LcallFunction2: 883b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 88403906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe INVOKE_STUB_CALL_AND_RETURN 885b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 886b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithEND art_quick_invoke_static_stub 887b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 88803906cffb1a59931c1c871ac3a0ffb1c4476bbb4Andreas Gampe 889b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 890b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith /* 891b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * On entry x0 is uintptr_t* gprs_ and x1 is uint64_t* fprs_ 892b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 893b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 894b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithENTRY art_quick_do_long_jump 895b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Load FPRs 896b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d0, d1, [x1], #16 897b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d2, d3, [x1], #16 898b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d4, d5, [x1], #16 899b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d6, d7, [x1], #16 900b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d8, d9, [x1], #16 901b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d10, d11, [x1], #16 902b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d12, d13, [x1], #16 903b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d14, d15, [x1], #16 904b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d16, d17, [x1], #16 905b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d18, d19, [x1], #16 906b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d20, d21, [x1], #16 907b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d22, d23, [x1], #16 908b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d24, d25, [x1], #16 909b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d26, d27, [x1], #16 910b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d28, d29, [x1], #16 911b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp d30, d31, [x1] 912b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 913b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Load GPRs 914b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // TODO: lots of those are smashed, could optimize. 915b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith add x0, x0, #30*8 916b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x30, x1, [x0], #-16 917b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x28, x29, [x0], #-16 918b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x26, x27, [x0], #-16 919b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x24, x25, [x0], #-16 920b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x22, x23, [x0], #-16 921b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x20, x21, [x0], #-16 922b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x18, x19, [x0], #-16 923b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x16, x17, [x0], #-16 924b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x14, x15, [x0], #-16 925b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x12, x13, [x0], #-16 926b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x10, x11, [x0], #-16 927b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x8, x9, [x0], #-16 928b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x6, x7, [x0], #-16 929b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x4, x5, [x0], #-16 930b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ldp x2, x3, [x0], #-16 931b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov sp, x1 932b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 933b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // TODO: Is it really OK to use LR for the target PC? 934b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x0, #0 935b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x1, #0 936b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith br xLR 937b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithEND art_quick_do_long_jump 938b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 939f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe /* 940f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe * Entry from managed code that calls artHandleFillArrayDataFromCode and delivers exception on 941f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe * failure. 942f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe */ 943f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .extern artHandleFillArrayDataFromCode 944f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas GampeENTRY art_quick_handle_fill_data 945f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe SETUP_REF_ONLY_CALLEE_SAVE_FRAME // Save callee saves in case exception allocation triggers GC. 946f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe mov x2, xSELF // Pass Thread::Current. 947f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe mov x3, sp // Pass SP. 948f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe bl artHandleFillArrayDataFromCode // (Array*, const DexFile::Payload*, Thread*, SP) 949f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe RESTORE_REF_ONLY_CALLEE_SAVE_FRAME 950f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe RETURN_IF_RESULT_IS_ZERO 951f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe DELIVER_PENDING_EXCEPTION 952f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas GampeEND art_quick_handle_fill_data 953b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 9544fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe /* 9554fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe * Entry from managed code that calls artLockObjectFromCode, may block for GC. x0 holds the 9564fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe * possibly null object to lock. 9574fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe * 9584fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe * Derived from arm32 code. 9594fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe */ 9604fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe .extern artLockObjectFromCode 9614fc046e78efbc98541388cdda986b5d8a2b951adAndreas GampeENTRY art_quick_lock_object 9624fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe cbz w0, .Lslow_lock 9634fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe add x4, x0, #LOCK_WORD_OFFSET // exclusive load/store had no immediate anymore 9644fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe.Lretry_lock: 9654fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe ldr w2, [xSELF, #THREAD_ID_OFFSET] // TODO: Can the thread ID really change during the loop? 9664fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe ldxr w1, [x4] 9674fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe cbnz w1, .Lnot_unlocked // already thin locked 9684fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe stxr w3, w2, [x4] 9694fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe cbnz w3, .Lstrex_fail // store failed, retry 970675967d981a3d17aaedf4ca6e07cc3a76e066921Andreas Gampe dmb ishld // full (LoadLoad|LoadStore) memory barrier 9714fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe ret 9724fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe.Lstrex_fail: 9734fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe b .Lretry_lock // unlikely forward branch, need to reload and recheck r1/r2 9744fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe.Lnot_unlocked: 9754fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe lsr w3, w1, 30 9764fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe cbnz w3, .Lslow_lock // if either of the top two bits are set, go slow path 9774fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe eor w2, w1, w2 // lock_word.ThreadId() ^ self->ThreadId() 9784fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe uxth w2, w2 // zero top 16 bits 9794fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe cbnz w2, .Lslow_lock // lock word and self thread id's match -> recursive lock 9804fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe // else contention, go to slow path 9814fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe add w2, w1, #65536 // increment count in lock word placing in w2 for storing 9824fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe lsr w1, w2, 30 // if either of the top two bits are set, we overflowed. 9834fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe cbnz w1, .Lslow_lock // if we overflow the count go slow path 9844fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe str w2, [x0, #LOCK_WORD_OFFSET]// no need for stxr as we hold the lock 9854fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe ret 9864fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe.Lslow_lock: 9874fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save callee saves in case we block 9884fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe mov x1, xSELF // pass Thread::Current 9894fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe mov x2, sp // pass SP 9904fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe bl artLockObjectFromCode // (Object* obj, Thread*, SP) 9914fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe RESTORE_REF_ONLY_CALLEE_SAVE_FRAME 9924fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe RETURN_IF_W0_IS_ZERO_OR_DELIVER 9934fc046e78efbc98541388cdda986b5d8a2b951adAndreas GampeEND art_quick_lock_object 9944fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe 9954fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe /* 9964fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe * Entry from managed code that calls artUnlockObjectFromCode and delivers exception on failure. 9974fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe * x0 holds the possibly null object to lock. 9984fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe * 9994fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe * Derived from arm32 code. 10004fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe */ 10014fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe .extern artUnlockObjectFromCode 10024fc046e78efbc98541388cdda986b5d8a2b951adAndreas GampeENTRY art_quick_unlock_object 10034fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe cbz x0, .Lslow_unlock 10044fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe ldr w1, [x0, #LOCK_WORD_OFFSET] 10054fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe lsr w2, w1, 30 10064fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe cbnz w2, .Lslow_unlock // if either of the top two bits are set, go slow path 10074fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe ldr w2, [xSELF, #THREAD_ID_OFFSET] 10084fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe eor w3, w1, w2 // lock_word.ThreadId() ^ self->ThreadId() 10094fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe uxth w3, w3 // zero top 16 bits 10104fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe cbnz w3, .Lslow_unlock // do lock word and self thread id's match? 10114fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe cmp w1, #65536 10124fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe bpl .Lrecursive_thin_unlock 10134fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe // transition to unlocked, w3 holds 0 1014675967d981a3d17aaedf4ca6e07cc3a76e066921Andreas Gampe dmb ish // full (LoadStore|StoreStore) memory barrier 10154fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe str w3, [x0, #LOCK_WORD_OFFSET] 10164fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe ret 10174fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe.Lrecursive_thin_unlock: 10184fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe sub w1, w1, #65536 10194fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe str w1, [x0, #LOCK_WORD_OFFSET] 10204fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe ret 10214fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe.Lslow_unlock: 10224fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save callee saves in case exception allocation triggers GC 10234fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe mov x1, xSELF // pass Thread::Current 10244fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe mov x2, sp // pass SP 10254fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe bl artUnlockObjectFromCode // (Object* obj, Thread*, SP) 10264fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe RESTORE_REF_ONLY_CALLEE_SAVE_FRAME 10274fc046e78efbc98541388cdda986b5d8a2b951adAndreas Gampe RETURN_IF_W0_IS_ZERO_OR_DELIVER 10284fc046e78efbc98541388cdda986b5d8a2b951adAndreas GampeEND art_quick_unlock_object 1029525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe 1030525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe /* 1031525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe * Entry from managed code that calls artIsAssignableFromCode and on failure calls 1032525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe * artThrowClassCastException. 1033525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe */ 1034525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .extern artThrowClassCastException 1035525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas GampeENTRY art_quick_check_cast 1036525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe // Store arguments and link register 1037525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe sub sp, sp, #32 // Stack needs to be 16b aligned on calls 1038525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_adjust_cfa_offset 32 1039525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe stp x0, x1, [sp] 1040525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_rel_offset x0, 0 1041525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_rel_offset x1, 8 1042525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe stp xSELF, xLR, [sp, #16] 1043525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_rel_offset x18, 16 1044525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_rel_offset x30, 24 1045525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe 1046525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe // Call runtime code 1047525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe bl artIsAssignableFromCode 1048525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe 1049525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe // Check for exception 1050525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe cbz x0, .Lthrow_class_cast_exception 1051525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe 1052525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe // Restore and return 1053525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe ldp x0, x1, [sp] 1054525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_restore x0 1055525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_restore x1 1056525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe ldp xSELF, xLR, [sp, #16] 1057525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_restore x18 1058525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_restore x30 1059525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe add sp, sp, #32 1060525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_adjust_cfa_offset -32 1061525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe ret 1062525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe 1063525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe.Lthrow_class_cast_exception: 1064525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe // Restore 1065525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe ldp x0, x1, [sp] 1066525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_restore x0 1067525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_restore x1 1068525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe ldp xSELF, xLR, [sp, #16] 1069525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_restore x18 1070525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_restore x30 1071525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe add sp, sp, #32 1072525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe .cfi_adjust_cfa_offset -32 1073525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe 1074525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context 1075525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe mov x2, xSELF // pass Thread::Current 1076525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe mov x3, sp // pass SP 1077525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe b artThrowClassCastException // (Class*, Class*, Thread*, SP) 1078525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe brk 0 // We should not return here... 1079525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas GampeEND art_quick_check_cast 1080525cde2dd7cc7ad4212765ad3975cf260a934d3eAndreas Gampe 1081f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe /* 1082f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe * Entry from managed code for array put operations of objects where the value being stored 1083f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe * needs to be checked for compatibility. 1084f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe * x0 = array, x1 = index, x2 = value 1085f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe * 1086f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe * Currently all values should fit into w0/w1/w2, and w1 always will as indices are 32b. We 1087f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe * assume, though, that the upper 32b are zeroed out. At least for x1/w1 we can do better by 1088f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe * using index-zero-extension in load/stores. 1089f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe * 1090f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe * Temporaries: x3, x4 1091f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe * TODO: x4 OK? ip seems wrong here. 1092f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe */ 1093f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas GampeENTRY art_quick_aput_obj_with_null_and_bound_check 1094f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe tst x0, x0 1095f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe bne art_quick_aput_obj_with_bound_check 1096f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe b art_quick_throw_null_pointer_exception 1097f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas GampeEND art_quick_aput_obj_with_null_and_bound_check 1098f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe 1099f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas GampeENTRY art_quick_aput_obj_with_bound_check 1100f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ldr w3, [x0, #ARRAY_LENGTH_OFFSET] 1101f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe cmp w3, w1 1102f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe bhi art_quick_aput_obj 1103f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe mov x0, x1 1104f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe mov x1, x3 1105f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe b art_quick_throw_array_bounds 1106f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas GampeEND art_quick_aput_obj_with_bound_check 1107f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe 1108f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas GampeENTRY art_quick_aput_obj 1109f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe cbz x2, .Ldo_aput_null 1110f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ldr w3, [x0, #CLASS_OFFSET] // Heap reference = 32b 1111f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe // This also zero-extends to x3 1112f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ldr w4, [x2, #CLASS_OFFSET] // Heap reference = 32b 1113f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe // This also zero-extends to x4 1114f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ldr w3, [x3, #CLASS_COMPONENT_TYPE_OFFSET] // Heap reference = 32b 1115f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe // This also zero-extends to x3 1116f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe cmp w3, w4 // value's type == array's component type - trivial assignability 1117f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe bne .Lcheck_assignability 1118f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe.Ldo_aput: 1119f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe add x3, x0, #OBJECT_ARRAY_DATA_OFFSET 1120f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe // "Compress" = do nothing 1121f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe str w2, [x3, x1, lsl #2] // Heap reference = 32b 1122f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ldr x3, [xSELF, #THREAD_CARD_TABLE_OFFSET] 1123f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe lsr x0, x0, #7 1124f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe strb w3, [x3, x0] 1125f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ret 1126f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe.Ldo_aput_null: 1127f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe add x3, x0, #OBJECT_ARRAY_DATA_OFFSET 1128f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe // "Compress" = do nothing 1129f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe str w2, [x3, x1, lsl #2] // Heap reference = 32b 1130f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ret 1131f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe.Lcheck_assignability: 1132f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe // Store arguments and link register 1133f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe sub sp, sp, #48 // Stack needs to be 16b aligned on calls 1134f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_adjust_cfa_offset 48 1135f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe stp x0, x1, [sp] 1136f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_rel_offset x0, 0 1137f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_rel_offset x1, 8 1138f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe stp x2, xSELF, [sp, #16] 1139f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_rel_offset x2, 16 1140f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_rel_offset x18, 24 1141f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe str xLR, [sp, #32] 1142f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_rel_offset x30, 32 1143f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe 1144f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe // Call runtime code 1145f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe mov x0, x3 // Heap reference, 32b, "uncompress" = do nothing, already zero-extended 1146f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe mov x1, x4 // Heap reference, 32b, "uncompress" = do nothing, already zero-extended 1147f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe bl artIsAssignableFromCode 1148f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe 1149f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe // Check for exception 1150f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe cbz x0, .Lthrow_array_store_exception 1151f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe 1152f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe // Restore 1153f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ldp x0, x1, [sp] 1154f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_restore x0 1155f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_restore x1 1156f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ldp x2, xSELF, [sp, #16] 1157f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_restore x2 1158f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_restore x18 1159f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ldr xLR, [sp, #32] 1160f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_restore x30 1161f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe add sp, sp, #48 1162f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_adjust_cfa_offset -48 1163f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe 1164f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe add x3, x0, #OBJECT_ARRAY_DATA_OFFSET 1165f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe // "Compress" = do nothing 1166f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe str w2, [x3, x1, lsl #2] // Heap reference = 32b 1167f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ldr x3, [xSELF, #THREAD_CARD_TABLE_OFFSET] 1168f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe lsr x0, x0, #7 1169f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe strb w3, [x3, x0] 1170f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ret 1171f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe.Lthrow_array_store_exception: 1172f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ldp x0, x1, [sp] 1173f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_restore x0 1174f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_restore x1 1175f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ldp x2, xSELF, [sp, #16] 1176f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_restore x2 1177f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_restore x18 1178f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe ldr xLR, [sp, #32] 1179f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_restore x30 1180f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe add sp, sp, #48 1181f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe .cfi_adjust_cfa_offset -48 1182f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe 1183f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe SETUP_SAVE_ALL_CALLEE_SAVE_FRAME 1184f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe mov x1, x2 // Pass value. 1185f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe mov x2, xSELF // Pass Thread::Current. 1186f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe mov x3, sp // Pass SP. 1187f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe b artThrowArrayStoreException // (Object*, Object*, Thread*, SP). 1188f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe brk 0 // Unreached. 1189f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas GampeEND art_quick_aput_obj 1190f4e910badbaa5aa48efbf697715f4815f0ebc7e4Andreas Gampe 1191b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// Macro to facilitate adding new allocation entrypoints. 1192b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro TWO_ARG_DOWNCALL name, entrypoint, return 1193b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith .extern \entrypoint 1194b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithENTRY \name 119500c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save callee saves in case of GC 119600c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe mov x2, xSELF // pass Thread::Current 119700c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe mov x3, sp // pass SP 119800c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe bl \entrypoint // (uint32_t type_idx, Method* method, Thread*, SP) 119900c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe RESTORE_REF_ONLY_CALLEE_SAVE_FRAME 120000c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe \return 120100c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe DELIVER_PENDING_EXCEPTION 1202b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithEND \name 1203b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 1204b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1205b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// Macro to facilitate adding new array allocation entrypoints. 1206b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.macro THREE_ARG_DOWNCALL name, entrypoint, return 1207b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith .extern \entrypoint 1208b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithENTRY \name 120900c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save callee saves in case of GC 121000c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe mov x3, xSELF // pass Thread::Current 121100c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe mov x4, sp // pass SP 121200c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe bl \entrypoint 121300c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe RESTORE_REF_ONLY_CALLEE_SAVE_FRAME 121400c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe \return 121500c1e6d5fa6c2c20f25c38591b9780114bf7ddbfAndreas Gampe DELIVER_PENDING_EXCEPTION 1216b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithEND \name 1217b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.endm 1218b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 12196e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe// Macros taking opportunity of code similarities for downcalls with referrer. 12206e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe.macro ONE_ARG_REF_DOWNCALL name, entrypoint, return 12216e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe .extern \entrypoint 12226e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeENTRY \name 12236e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save callee saves in case of GC 1224cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe ldr w1, [sp, #FRAME_SIZE_REFS_ONLY_CALLEE_SAVE] // Load referrer 12256e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe mov x2, xSELF // pass Thread::Current 12266e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe mov x3, sp // pass SP 12276e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe bl \entrypoint // (uint32_t type_idx, Method* method, Thread*, SP) 12286e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe RESTORE_REF_ONLY_CALLEE_SAVE_FRAME 12296e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe \return 12306e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeEND \name 12316e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe.endm 12326e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe 12336e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe.macro TWO_ARG_REF_DOWNCALL name, entrypoint, return 12346e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe .extern \entrypoint 12356e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeENTRY \name 12366e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save callee saves in case of GC 1237cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe ldr w2, [sp, #FRAME_SIZE_REFS_ONLY_CALLEE_SAVE] // Load referrer 12386e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe mov x3, xSELF // pass Thread::Current 12396e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe mov x4, sp // pass SP 12406e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe bl \entrypoint 12416e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe RESTORE_REF_ONLY_CALLEE_SAVE_FRAME 12426e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe \return 12436e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeEND \name 12446e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe.endm 12456e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe 12466e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe.macro THREE_ARG_REF_DOWNCALL name, entrypoint, return 12476e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe .extern \entrypoint 12486e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeENTRY \name 12496e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save callee saves in case of GC 1250cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe ldr w3, [sp, #FRAME_SIZE_REFS_ONLY_CALLEE_SAVE] // Load referrer 12516e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe mov x4, xSELF // pass Thread::Current 12526e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe mov x5, sp // pass SP 12536e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe bl \entrypoint 12546e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe RESTORE_REF_ONLY_CALLEE_SAVE_FRAME 12556e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe \return 12566e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeEND \name 12576e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe.endm 12586e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe 1259dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin /* 1260dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin * Entry from managed code when uninitialized static storage, this stub will run the class 1261dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin * initializer and deliver the exception on error. On success the static storage base is 1262dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin * returned. 1263dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin */ 1264dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo FranchinTWO_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode, RETURN_IF_RESULT_IS_NON_ZERO 1265dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin 12666aac355810d83babbd834df07cf1a38f44ad11c2Andreas GampeTWO_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_RESULT_IS_NON_ZERO 12676aac355810d83babbd834df07cf1a38f44ad11c2Andreas GampeTWO_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_RESULT_IS_NON_ZERO 1268dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin 12696e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 12706e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 12716e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 12726e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe 12736e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeTWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 12746e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeTWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 12756e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeTWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 12766e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe 12776e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeTWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER 12786e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeTWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER 12796e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe 12806e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeTHREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER 12816e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeTHREE_ARG_DOWNCALL art_quick_set64_instance, artSet64InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER 12826e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeTHREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER 12836e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe 12846e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe// This is separated out as the argument order is different. 12856e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe .extern artSet64StaticFromCode 12866e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeENTRY art_quick_set64_static 12876e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save callee saves in case of GC 12886e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe mov x3, x1 // Store value 1289cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe ldr w1, [sp, #FRAME_SIZE_REFS_ONLY_CALLEE_SAVE] // Load referrer 12906e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe mov x2, x3 // Put value param 12916e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe mov x3, xSELF // pass Thread::Current 12926e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe mov x4, sp // pass SP 12936e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe bl artSet64StaticFromCode 12946e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe RESTORE_REF_ONLY_CALLEE_SAVE_FRAME 12956e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe RETURN_IF_W0_IS_ZERO_OR_DELIVER 12966e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas GampeEND art_quick_set64_static 12976e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe 1298dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin /* 1299dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin * Entry from managed code to resolve a string, this stub will allocate a String and deliver an 1300dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin * exception on error. On success the String is returned. x0 holds the referring method, 1301dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin * w1 holds the string index. The fast path check for hit in strings cache has already been 1302dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin * performed. 1303dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin */ 1304dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo FranchinTWO_ARG_DOWNCALL art_quick_resolve_string, artResolveStringFromCode, RETURN_IF_RESULT_IS_NON_ZERO 13056e4e59c674f4d58421512dbcfc57a99e27b6b5c8Andreas Gampe 1306b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith// Generate the allocation entrypoints for each allocator. 1307b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithGENERATE_ALL_ALLOC_ENTRYPOINTS 1308b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 130948241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu /* 131048241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu * Called by managed code when the value in wSUSPEND has been decremented to 0. 131148241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu */ 131248241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu .extern artTestSuspendFromCode 131348241e786121e1c4c050d9cfad3d22de270a3e75Zheng XuENTRY art_quick_test_suspend 131448241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu ldrh w0, [xSELF, #THREAD_FLAGS_OFFSET] // get xSELF->state_and_flags.as_struct.flags 131548241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu mov wSUSPEND, #SUSPEND_CHECK_INTERVAL // reset wSUSPEND to SUSPEND_CHECK_INTERVAL 131648241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu cbnz w0, .Lneed_suspend // check flags == 0 131748241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu ret // return if flags == 0 131848241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu.Lneed_suspend: 131948241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu mov x0, xSELF 132048241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save callee saves for stack crawl 132148241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu mov x1, sp 132248241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu bl artTestSuspendFromCode // (Thread*, SP) 132348241e786121e1c4c050d9cfad3d22de270a3e75Zheng Xu RESTORE_REF_ONLY_CALLEE_SAVE_FRAME_AND_RETURN 132448241e786121e1c4c050d9cfad3d22de270a3e75Zheng XuEND art_quick_test_suspend 1325b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 13267204c04dd86ae8ce05690e38737b2abf017a0a69Stuart MonteithENTRY art_quick_implicit_suspend 13277204c04dd86ae8ce05690e38737b2abf017a0a69Stuart Monteith mov x0, xSELF 13287204c04dd86ae8ce05690e38737b2abf017a0a69Stuart Monteith SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save callee saves for stack crawl 13297204c04dd86ae8ce05690e38737b2abf017a0a69Stuart Monteith mov x1, sp 13307204c04dd86ae8ce05690e38737b2abf017a0a69Stuart Monteith bl artTestSuspendFromCode // (Thread*, SP) 13317204c04dd86ae8ce05690e38737b2abf017a0a69Stuart Monteith RESTORE_REF_ONLY_CALLEE_SAVE_FRAME_AND_RETURN 13327204c04dd86ae8ce05690e38737b2abf017a0a69Stuart MonteithEND art_quick_implicit_suspend 13337204c04dd86ae8ce05690e38737b2abf017a0a69Stuart Monteith 1334e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe /* 1335e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe * Called by managed code that is attempting to call a method on a proxy class. On entry 1336e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe * x0 holds the proxy method and x1 holds the receiver; The frame size of the invoked proxy 1337e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe * method agrees with a ref and args callee save frame. 1338e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe */ 1339e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe .extern artQuickProxyInvokeHandler 1340e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas GampeENTRY art_quick_proxy_invoke_handler 1341e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME 1342e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe str x0, [sp, #0] // place proxy method at bottom of frame 1343e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe mov x2, xSELF // pass Thread::Current 1344e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe mov x3, sp // pass SP 1345e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe bl artQuickProxyInvokeHandler // (Method* proxy method, receiver, Thread*, SP) 1346b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // Use xETR as xSELF might be scratched by native function above. 1347b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr x2, [xETR, THREAD_EXCEPTION_OFFSET] 1348e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe cbnz x2, .Lexception_in_proxy // success if no exception is pending 1349d1e9167713e485d9264e856b68ffb568f22f1dc9Andreas Gampe RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME // Restore frame 1350d1e9167713e485d9264e856b68ffb568f22f1dc9Andreas Gampe fmov d0, x0 // Store result in d0 in case it was float or double 1351e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe ret // return on success 1352e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe.Lexception_in_proxy: 1353e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME 1354e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas Gampe DELIVER_PENDING_EXCEPTION 1355e62a07eac9ba2bef01f373832dd810a2cee9f348Andreas GampeEND art_quick_proxy_invoke_handler 1356b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 135751f763506c7bb34420242e88e1631550f94d6417Andreas Gampe /* 1358b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu * Called to resolve an imt conflict. xIP1 is a hidden argument that holds the target method's 135951f763506c7bb34420242e88e1631550f94d6417Andreas Gampe * dex method index. 136051f763506c7bb34420242e88e1631550f94d6417Andreas Gampe */ 136151f763506c7bb34420242e88e1631550f94d6417Andreas GampeENTRY art_quick_imt_conflict_trampoline 1362cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe ldr w0, [sp, #0] // load caller Method* 136351f763506c7bb34420242e88e1631550f94d6417Andreas Gampe ldr w0, [x0, #METHOD_DEX_CACHE_METHODS_OFFSET] // load dex_cache_resolved_methods 136451f763506c7bb34420242e88e1631550f94d6417Andreas Gampe add x0, x0, #OBJECT_ARRAY_DATA_OFFSET // get starting address of data 1365b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr w0, [x0, xIP1, lsl 2] // load the target method 136651f763506c7bb34420242e88e1631550f94d6417Andreas Gampe b art_quick_invoke_interface_trampoline 136751f763506c7bb34420242e88e1631550f94d6417Andreas GampeEND art_quick_imt_conflict_trampoline 1368b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1369b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithENTRY art_quick_resolution_trampoline 1370b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME 1371b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x2, xSELF 1372b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x3, sp 1373b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith bl artQuickResolutionTrampoline // (called, receiver, Thread*, SP) 1374dfd891a61a1642b3c0d532e0cec73255cf4b9afbMatteo Franchin cbz x0, 1f 1375b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov xIP0, x0 // Remember returned code pointer in xIP0. 1376cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe ldr w0, [sp, #0] // artQuickResolutionTrampoline puts called method in *SP. 1377b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME 1378b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu br xIP0 1379b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith1: 1380b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME 1381b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith DELIVER_PENDING_EXCEPTION 1382b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithEND art_quick_resolution_trampoline 1383b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1384b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith/* 1385b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Generic JNI frame layout: 1386b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * 1387b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * #-------------------# 1388b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | | 1389b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | caller method... | 1390b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * #-------------------# <--- SP on entry 1391b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | Return X30/LR | 1392b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X29/FP | callee save 1393b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X28 | callee save 1394b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X27 | callee save 1395b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X26 | callee save 1396b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X25 | callee save 1397b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X24 | callee save 1398b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X23 | callee save 1399b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X22 | callee save 1400b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X21 | callee save 1401b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X20 | callee save 1402b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X7 | arg7 1403b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X6 | arg6 1404b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X5 | arg5 1405b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X4 | arg4 1406b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X3 | arg3 1407b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X2 | arg2 1408b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | X1 | arg1 1409b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | D7 | float arg 8 1410b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | D6 | float arg 7 1411b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | D5 | float arg 6 1412b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | D4 | float arg 5 1413b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | D3 | float arg 4 1414b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | D2 | float arg 3 1415b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | D1 | float arg 2 1416b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | D0 | float arg 1 1417cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe * | Method* | <- X0 1418b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * #-------------------# 1419b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | local ref cookie | // 4B 1420421c53742610c053543f8c84e04d5e0c5185d68cMathieu Chartier * | handle scope size | // 4B 1421b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * #-------------------# 1422b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | JNI Call Stack | 1423b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * #-------------------# <--- SP on native call 1424b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | | 1425b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | Stack for Regs | The trampoline assembly will pop these values 1426b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | | into registers for native call 1427b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * #-------------------# 1428b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | Native code ptr | 1429b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * #-------------------# 1430b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | Free scratch | 1431b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * #-------------------# 1432b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * | Ptr to (1) | <--- SP 1433b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * #-------------------# 1434b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 1435b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith /* 1436b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Called to do a generic JNI down-call 1437b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 1438235e77bd9f19e4faefda109be40f8744f3a66f40Andreas GampeENTRY_NO_HIDE art_quick_generic_jni_trampoline 1439b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME_INTERNAL 1440b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith str x0, [sp, #0] // Store native ArtMethod* to bottom of stack. 1441b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1442b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Save SP , so we can have static CFI info. 1443b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x28, sp 1444b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith .cfi_def_cfa_register x28 1445b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1446b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // This looks the same, but is different: this will be updated to point to the bottom 1447eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // of the frame when the handle scope is inserted. 1448b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov xFP, sp 1449b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1450b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov xIP0, #5120 1451b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu sub sp, sp, xIP0 1452b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1453b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // prepare for artQuickGenericJniTrampoline call 1454b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // (Thread*, SP) 1455b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // x0 x1 <= C calling convention 1456b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // xSELF xFP <= where they are 1457b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1458b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x0, xSELF // Thread* 1459b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x1, xFP 1460b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith bl artQuickGenericJniTrampoline // (Thread*, sp) 1461b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1462c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // The C call will have registered the complete save-frame on success. 1463c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // The result of the call is: 1464c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // x0: pointer to native code, 0 on error. 1465c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // x1: pointer to the bottom of the used area of the alloca, can restore stack till there. 1466b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1467c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // Check for error = 0. 1468c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe cbz x0, .Lentry_error 1469b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1470c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // Release part of the alloca. 1471c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe mov sp, x1 1472b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1473c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // Save the code pointer 1474c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe mov xIP0, x0 1475b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1476b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Load parameters from frame into registers. 1477b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // TODO Check with artQuickGenericJniTrampoline. 1478b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Also, check again APPCS64 - the stack arguments are interleaved. 1479c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe ldp x0, x1, [sp] 1480c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe ldp x2, x3, [sp, #16] 1481c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe ldp x4, x5, [sp, #32] 1482c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe ldp x6, x7, [sp, #48] 1483b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1484c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe ldp d0, d1, [sp, #64] 1485c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe ldp d2, d3, [sp, #80] 1486c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe ldp d4, d5, [sp, #96] 1487c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe ldp d6, d7, [sp, #112] 1488b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1489c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe add sp, sp, #128 1490b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1491b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu blr xIP0 // native call. 1492b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1493b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // result sign extension is handled in C code 1494b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // prepare for artQuickGenericJniEndTrampoline call 1495c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // (Thread*, result, result_f) 1496c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // x0 x1 x2 <= C calling convention 1497c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe mov x1, x0 // Result (from saved) 1498b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov x0, xETR // Thread register, original xSELF might be scratched by native code. 1499c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe fmov x2, d0 // d0 will contain floating point result, but needs to go into x2 1500b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1501b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith bl artQuickGenericJniEndTrampoline 1502b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1503b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Tear down the alloca. 1504b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov sp, x28 1505b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith .cfi_def_cfa_register sp 1506b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1507b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Pending exceptions possible. 1508b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu // Use xETR as xSELF might be scratched by native code 1509b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldr x1, [xETR, THREAD_EXCEPTION_OFFSET] 1510b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith cbnz x1, .Lexception_in_native 1511b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1512b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // Tear down the callee-save frame. 1513b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME 1514b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1515b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // store into fpr, for when it's a fpr return... 1516b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith fmov d0, x0 1517b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith ret 1518b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1519b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.Lentry_error: 1520b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov sp, x28 1521b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith .cfi_def_cfa_register sp 1522b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith.Lexception_in_native: 1523b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME 1524b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith DELIVER_PENDING_EXCEPTION 1525b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1526b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithEND art_quick_generic_jni_trampoline 1527b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1528b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith/* 1529b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * Called to bridge from the quick to interpreter ABI. On entry the arguments match those 1530b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * of a quick call: 1531b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * x0 = method being called/to bridge to. 1532b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith * x1..x7, d0..d7 = arguments to that method. 1533b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith */ 1534235e77bd9f19e4faefda109be40f8744f3a66f40Andreas GampeENTRY_NO_HIDE art_quick_to_interpreter_bridge 1535b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // Set up frame and save arguments. 1536b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1537b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // x0 will contain mirror::ArtMethod* method. 1538b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x1, xSELF // How to get Thread::Current() ??? 1539b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith mov x2, sp 1540b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1541b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // uint64_t artQuickToInterpreterBridge(mirror::ArtMethod* method, Thread* self, 1542b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith // mirror::ArtMethod** sp) 1543b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith bl artQuickToInterpreterBridge 1544b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1545b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME // TODO: no need to restore arguments in this case. 1546b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1547b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith fmov d0, x0 1548b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1549b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith RETURN_OR_DELIVER_PENDING_EXCEPTION 1550b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart MonteithEND art_quick_to_interpreter_bridge 1551b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith 1552d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1553d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe// 1554d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe// Instrumentation-related stubs 1555d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe// 1556d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe .extern artInstrumentationMethodEntryFromCode 1557d58342caa97108ba413bad467c285c0377f138f5Andreas GampeENTRY art_quick_instrumentation_entry 1558d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME 1559d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1560b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov x20, x0 // Preserve method reference in a callee-save. 1561d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1562d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe mov x2, xSELF 1563d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe mov x3, sp 1564d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe mov x4, xLR 1565d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe bl artInstrumentationMethodEntryFromCode // (Method*, Object*, Thread*, SP, LR) 1566d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1567b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov xIP0, x0 // x0 = result of call. 1568b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov x0, x20 // Reload method reference. 1569d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1570d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME // Note: will restore xSELF 1571d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe adr xLR, art_quick_instrumentation_exit 1572b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu br xIP0 // Tail-call method with lr set to art_quick_instrumentation_exit. 1573d58342caa97108ba413bad467c285c0377f138f5Andreas GampeEND art_quick_instrumentation_entry 1574d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1575d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe .extern artInstrumentationMethodExitFromCode 1576d58342caa97108ba413bad467c285c0377f138f5Andreas GampeENTRY art_quick_instrumentation_exit 1577d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe mov xLR, #0 // Clobber LR for later checks. 1578d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1579d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe SETUP_REF_ONLY_CALLEE_SAVE_FRAME 1580d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1581d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe // We need to save x0 and d0. We could use a callee-save from SETUP_REF_ONLY, but then 1582d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe // we would need to fully restore it. As there are a lot of callee-save registers, it seems 1583d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe // easier to have an extra small stack area. 1584d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 158570f8d4b107e1f87c23df51efa360b3f4e90bce91Sebastien Hertz str x0, [sp, #-16]! // Save integer result. 1586d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe .cfi_adjust_cfa_offset 16 1587d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe str d0, [sp, #8] // Save floating-point result. 1588d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1589d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe add x1, sp, #16 // Pass SP. 1590d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe mov x2, x0 // Pass integer result. 1591d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe fmov x3, d0 // Pass floating-point result. 159270f8d4b107e1f87c23df51efa360b3f4e90bce91Sebastien Hertz mov x0, xSELF // Pass Thread. 1593d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe bl artInstrumentationMethodExitFromCode // (Thread*, SP, gpr_res, fpr_res) 1594d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1595b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu mov xIP0, x0 // Return address from instrumentation call. 1596d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe mov xLR, x1 // r1 is holding link register if we're to bounce to deoptimize 1597d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1598d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe ldr d0, [sp, #8] // Restore floating-point result. 1599d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe ldr x0, [sp], 16 // Restore integer result, and drop stack area. 1600d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe .cfi_adjust_cfa_offset 16 1601d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1602d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe POP_REF_ONLY_CALLEE_SAVE_FRAME 1603d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1604b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu br xIP0 // Tail-call out. 1605d58342caa97108ba413bad467c285c0377f138f5Andreas GampeEND art_quick_instrumentation_exit 1606d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1607d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe /* 1608d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization 1609d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe * will long jump to the upcall with a special exception of -1. 1610d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe */ 1611d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe .extern artDeoptimize 1612d58342caa97108ba413bad467c285c0377f138f5Andreas GampeENTRY art_quick_deoptimize 1613d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe SETUP_SAVE_ALL_CALLEE_SAVE_FRAME 1614d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe mov x0, xSELF // Pass thread. 1615d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe mov x1, sp // Pass SP. 1616d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe bl artDeoptimize // artDeoptimize(Thread*, SP) 161786797a791d692f81def5c1b5f0918992c49ed122Serban Constantinescu brk 0 1618d58342caa97108ba413bad467c285c0377f138f5Andreas GampeEND art_quick_deoptimize 1619d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1620d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe 1621169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu /* 1622169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu * String's indexOf. 1623169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu * 1624169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu * TODO: Not very optimized. 1625169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu * On entry: 1626169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu * x0: string object (known non-null) 1627169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu * w1: char to match (known <= 0xFFFF) 1628169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu * w2: Starting offset in string data 1629169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu */ 1630169489b4f4be8c5dd880ba6f152948324d22ff79Serban ConstantinescuENTRY art_quick_indexof 1631169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu ldr w3, [x0, #STRING_COUNT_OFFSET] 1632169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu ldr w4, [x0, #STRING_OFFSET_OFFSET] 1633169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu ldr w0, [x0, #STRING_VALUE_OFFSET] // x0 ? 1634169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu 1635169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu /* Clamp start to [0..count] */ 1636169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu cmp w2, #0 1637169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu csel w2, wzr, w2, lt 1638169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu cmp w2, w3 1639169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu csel w2, w3, w2, gt 1640169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu 1641169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu /* Build a pointer to the start of the string data */ 1642169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu add x0, x0, #STRING_DATA_OFFSET 1643169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu add x0, x0, x4, lsl #1 1644169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu 1645169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu /* Save a copy to compute result */ 1646169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu mov x5, x0 1647169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu 1648169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu /* Build pointer to start of data to compare and pre-bias */ 1649169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu add x0, x0, x2, lsl #1 1650169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu sub x0, x0, #2 1651169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu 1652169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu /* Compute iteration count */ 1653169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu sub w2, w3, w2 1654169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu 1655169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu /* 1656169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu * At this point we have: 1657169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu * x0: start of the data to test 1658169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu * w1: char to compare 1659169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu * w2: iteration count 1660169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu * x5: original start of string data 1661169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu */ 1662169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu 1663169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu subs w2, w2, #4 1664169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu b.lt .Lindexof_remainder 1665169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu 1666169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu.Lindexof_loop4: 1667169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu ldrh w6, [x0, #2]! 1668169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu ldrh w7, [x0, #2]! 1669b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldrh wIP0, [x0, #2]! 1670b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu ldrh wIP1, [x0, #2]! 1671169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu cmp w6, w1 1672169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu b.eq .Lmatch_0 1673169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu cmp w7, w1 1674169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu b.eq .Lmatch_1 1675b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu cmp wIP0, w1 1676169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu b.eq .Lmatch_2 1677b551fdcda9eb128c80de37c4fb978968bec6d4b3Zheng Xu cmp wIP1, w1 1678169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu b.eq .Lmatch_3 1679169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu subs w2, w2, #4 1680169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu b.ge .Lindexof_loop4 1681169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu 1682169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu.Lindexof_remainder: 1683169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu adds w2, w2, #4 1684169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu b.eq .Lindexof_nomatch 1685169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu 1686169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu.Lindexof_loop1: 1687169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu ldrh w6, [x0, #2]! 1688169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu cmp w6, w1 1689169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu b.eq .Lmatch_3 1690169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu subs w2, w2, #1 1691169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu b.ne .Lindexof_loop1 1692169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu 1693169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu.Lindexof_nomatch: 1694169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu mov x0, #-1 1695169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu ret 1696169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu 1697169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu.Lmatch_0: 1698169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu sub x0, x0, #6 1699169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu sub x0, x0, x5 1700169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu asr x0, x0, #1 1701169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu ret 1702169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu.Lmatch_1: 1703169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu sub x0, x0, #4 1704169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu sub x0, x0, x5 1705169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu asr x0, x0, #1 1706169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu ret 1707169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu.Lmatch_2: 1708169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu sub x0, x0, #2 1709169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu sub x0, x0, x5 1710169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu asr x0, x0, #1 1711169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu ret 1712169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu.Lmatch_3: 1713169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu sub x0, x0, x5 1714169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu asr x0, x0, #1 1715169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu ret 1716169489b4f4be8c5dd880ba6f152948324d22ff79Serban ConstantinescuEND art_quick_indexof 1717266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1718266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe /* 1719266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * String's compareTo. 1720266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * 1721266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * TODO: Not very optimized. 1722266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * 1723266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * On entry: 1724266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * x0: this object pointer 1725266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * x1: comp object pointer 1726266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * 1727266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe */ 172886797a791d692f81def5c1b5f0918992c49ed122Serban Constantinescu .extern __memcmp16 1729266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas GampeENTRY art_quick_string_compareto 1730266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe mov x2, x0 // x0 is return, use x2 for first input. 1731266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe sub x0, x2, x1 // Same string object? 1732266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe cbnz x0,1f 1733266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ret 1734266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe1: // Different string objects. 1735266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1736266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ldr w6, [x2, #STRING_OFFSET_OFFSET] 1737266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ldr w5, [x1, #STRING_OFFSET_OFFSET] 1738266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ldr w4, [x2, #STRING_COUNT_OFFSET] 1739266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ldr w3, [x1, #STRING_COUNT_OFFSET] 1740266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ldr w2, [x2, #STRING_VALUE_OFFSET] 1741266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ldr w1, [x1, #STRING_VALUE_OFFSET] 1742266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1743266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe /* 1744266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * Now: CharArray* Offset Count 1745266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * first arg x2 w6 w4 1746266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * second arg x1 w5 w3 1747266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe */ 1748266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1749266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe // x0 := str1.length(w4) - str2.length(w3). ldr zero-extended w3/w4 into x3/x4. 1750266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe subs x0, x4, x3 1751266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe // Min(count1, count2) into w3. 1752266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe csel x3, x3, x4, ge 1753266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1754266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe // Build pointer into string data. 1755266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1756266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe // Add offset in array (substr etc.) (sign extend and << 1). 1757266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe add x2, x2, w6, sxtw #1 1758266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe add x1, x1, w5, sxtw #1 1759266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1760266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe // Add offset in CharArray to array. 1761266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe add x2, x2, #STRING_DATA_OFFSET 1762266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe add x1, x1, #STRING_DATA_OFFSET 1763266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1764169489b4f4be8c5dd880ba6f152948324d22ff79Serban Constantinescu // TODO: Tune this value. 1765266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe // Check for long string, do memcmp16 for them. 1766266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe cmp w3, #28 // Constant from arm32. 1767266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe bgt .Ldo_memcmp16 1768266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1769266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe /* 1770266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * Now: 1771266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * x2: *first string data 1772266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * x1: *second string data 1773266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * w3: iteration count 1774266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * x0: return value if comparison equal 1775266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe * x4, x5, x6, x7: free 1776266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe */ 1777266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1778266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe // Do a simple unrolled loop. 1779266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe.Lloop: 1780266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe // At least two more elements? 1781266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe subs w3, w3, #2 1782266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe b.lt .Lremainder_or_done 1783266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1784266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ldrh w4, [x2], #2 1785266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ldrh w5, [x1], #2 1786266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1787266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ldrh w6, [x2], #2 1788266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ldrh w7, [x1], #2 1789266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1790266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe subs w4, w4, w5 1791266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe b.ne .Lw4_result 1792266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1793266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe subs w6, w6, w7 1794266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe b.ne .Lw6_result 1795266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1796266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe b .Lloop 1797266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1798266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe.Lremainder_or_done: 1799266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe adds w3, w3, #1 1800266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe b.eq .Lremainder 1801266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ret 1802266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1803266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe.Lremainder: 1804266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ldrh w4, [x2], #2 1805266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ldrh w5, [x1], #2 1806266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe subs w4, w4, w5 1807266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe b.ne .Lw4_result 1808266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ret 1809266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1810266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe// Result is in w4 1811266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe.Lw4_result: 1812266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe sxtw x0, w4 1813266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ret 1814266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1815266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe// Result is in w6 1816266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe.Lw6_result: 1817266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe sxtw x0, w6 1818266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ret 1819266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1820266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe.Ldo_memcmp16: 1821d74824bdd01b2a76b310e1275a1114d39833a708Zheng Xu mov x14, x0 // Save x0 and LR. __memcmp16 does not use these temps. 1822d74824bdd01b2a76b310e1275a1114d39833a708Zheng Xu mov x15, xLR // TODO: Codify and check that? 1823266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1824266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe mov x0, x2 1825266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe uxtw x2, w3 182686797a791d692f81def5c1b5f0918992c49ed122Serban Constantinescu bl __memcmp16 1827266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 1828d74824bdd01b2a76b310e1275a1114d39833a708Zheng Xu mov xLR, x15 // Restore LR. 1829266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe 183086797a791d692f81def5c1b5f0918992c49ed122Serban Constantinescu cmp x0, #0 // Check the memcmp difference. 1831d74824bdd01b2a76b310e1275a1114d39833a708Zheng Xu csel x0, x0, x14, ne // x0 := x0 != 0 ? x14(prev x0=length diff) : x1. 1832266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas Gampe ret 1833266340d30a2ed52a4ea0ff64492d6aac857a3e24Andreas GampeEND art_quick_string_compareto 18340210d11658becc2bf02fe79788c87276a857d0e9Zheng Xu 18350210d11658becc2bf02fe79788c87276a857d0e9Zheng Xu// Macro to facilitate adding new entrypoints which call to native function directly. 18360210d11658becc2bf02fe79788c87276a857d0e9Zheng Xu// Currently, xSELF is the only thing we need to take care of between managed code and AAPCS. 18370210d11658becc2bf02fe79788c87276a857d0e9Zheng Xu// But we might introduce more differences. 18380210d11658becc2bf02fe79788c87276a857d0e9Zheng Xu.macro NATIVE_DOWNCALL name, entrypoint 18390210d11658becc2bf02fe79788c87276a857d0e9Zheng Xu .extern \entrypoint 18400210d11658becc2bf02fe79788c87276a857d0e9Zheng XuENTRY \name 184186797a791d692f81def5c1b5f0918992c49ed122Serban Constantinescu stp xSELF, xLR, [sp, #-16]! 18420210d11658becc2bf02fe79788c87276a857d0e9Zheng Xu bl \entrypoint 184386797a791d692f81def5c1b5f0918992c49ed122Serban Constantinescu ldp xSELF, xLR, [sp], #16 18440210d11658becc2bf02fe79788c87276a857d0e9Zheng Xu ret 18450210d11658becc2bf02fe79788c87276a857d0e9Zheng XuEND \name 18460210d11658becc2bf02fe79788c87276a857d0e9Zheng Xu.endm 18470210d11658becc2bf02fe79788c87276a857d0e9Zheng Xu 18480210d11658becc2bf02fe79788c87276a857d0e9Zheng XuNATIVE_DOWNCALL art_quick_fmod fmod 18490210d11658becc2bf02fe79788c87276a857d0e9Zheng XuNATIVE_DOWNCALL art_quick_fmodf fmodf 18500210d11658becc2bf02fe79788c87276a857d0e9Zheng XuNATIVE_DOWNCALL art_quick_memcpy memcpy 185186797a791d692f81def5c1b5f0918992c49ed122Serban ConstantinescuNATIVE_DOWNCALL art_quick_assignable_from_code artIsAssignableFromCode 1852