quick_entrypoints_mips.S revision 4147fcc43c2ee019a06e55384985e3eaf82dcb8c
10f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes/* 20f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Copyright (C) 2012 The Android Open Source Project 30f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * 40f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 50f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * you may not use this file except in compliance with the License. 60f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * You may obtain a copy of the License at 70f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * 80f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 90f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * 100f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Unless required by applicable law or agreed to in writing, software 110f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 120f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * See the License for the specific language governing permissions and 140f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * limitations under the License. 150f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes */ 160f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes 177655f29fabc0a12765de828914a18314382e5a35Ian Rogers#include "asm_support_mips.S" 185bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 197410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier#include "arch/quick_alloc_entrypoints.S" 207410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier 210703060875166106af3d490c6c264611aea67ec8jeffhao .set noreorder 225bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee .balign 4 235bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 245bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* Deliver the given exception */ 255bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee .extern artDeliverExceptionFromCode 265bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* Deliver an exception pending on a thread */ 278161c0336b97e11e02c000af357f8f40de2e23e4jeffhao .extern artDeliverPendingExceptionFromCode 285bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 29735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung#define ARG_SLOT_SIZE 32 // space for a0-a3 plus 4 more words 30735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung 315bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 325bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Macro that sets up the callee save frame to conform with 33fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko * Runtime::CreateCalleeSaveMethod(kSaveAllCalleeSaves) 34735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung * Callee-save: $s0-$s8 + $gp + $ra, 11 total + 1 word for Method* 35735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung * Clobbers $t0 and $sp 36735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots. 37fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko * Reserves FRAME_SIZE_SAVE_ALL_CALLEE_SAVES + ARG_SLOT_SIZE bytes on the stack 385bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 39fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko.macro SETUP_SAVE_ALL_CALLEE_SAVES_FRAME 40a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe addiu $sp, $sp, -96 41a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe .cfi_adjust_cfa_offset 96 425c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 435c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Ugly compile-time check, but we only have the preprocessor. 44fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVES != 96) 45fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko#error "FRAME_SIZE_SAVE_ALL_CALLEE_SAVES(MIPS) size not as expected." 465c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif 475c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 48a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe sw $ra, 92($sp) 49a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe .cfi_rel_offset 31, 92 50a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe sw $s8, 88($sp) 51a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe .cfi_rel_offset 30, 88 52a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe sw $gp, 84($sp) 53a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe .cfi_rel_offset 28, 84 54a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe sw $s7, 80($sp) 55a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe .cfi_rel_offset 23, 80 56a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe sw $s6, 76($sp) 57a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe .cfi_rel_offset 22, 76 58a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe sw $s5, 72($sp) 59a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe .cfi_rel_offset 21, 72 60a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe sw $s4, 68($sp) 61a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe .cfi_rel_offset 20, 68 62a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe sw $s3, 64($sp) 63a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe .cfi_rel_offset 19, 64 64a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe sw $s2, 60($sp) 65a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe .cfi_rel_offset 18, 60 66a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe sw $s1, 56($sp) 67a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe .cfi_rel_offset 17, 56 68a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe sw $s0, 52($sp) 69a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe .cfi_rel_offset 16, 52 70a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe 71a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe SDu $f30, $f31, 44, $sp, $t1 72a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe SDu $f28, $f29, 36, $sp, $t1 73a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe SDu $f26, $f27, 28, $sp, $t1 74a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe SDu $f24, $f25, 20, $sp, $t1 75a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe SDu $f22, $f23, 12, $sp, $t1 76a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe SDu $f20, $f21, 4, $sp, $t1 77a4e0e67611f54180694e0807d6599c1132269b6cAndreas Gampe 78735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung # 1 word for holding Method* 791d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers 804af77b7636fe98aae443b46a241fd9a29f16e291Douglas Leung lw $t0, %got(_ZN3art7Runtime9instance_E)($gp) 814af77b7636fe98aae443b46a241fd9a29f16e291Douglas Leung lw $t0, 0($t0) 82fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko lw $t0, RUNTIME_SAVE_ALL_CALLEE_SAVES_METHOD_OFFSET($t0) 831d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers sw $t0, 0($sp) # Place Method* at bottom of stack. 841d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame. 85735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, -ARG_SLOT_SIZE # reserve argument slots on the stack 86735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_adjust_cfa_offset ARG_SLOT_SIZE 875bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm 885bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 895bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 905bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Macro that sets up the callee save frame to conform with 91fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko * Runtime::CreateCalleeSaveMethod(kSaveRefsOnly). Restoration assumes non-moving GC. 925bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Does not include rSUSPEND or rSELF 93735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung * callee-save: $s2-$s8 + $gp + $ra, 9 total + 2 words padding + 1 word to hold Method* 94735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung * Clobbers $t0 and $sp 95735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots. 96fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko * Reserves FRAME_SIZE_SAVE_REFS_ONLY + ARG_SLOT_SIZE bytes on the stack 975bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 98fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko.macro SETUP_SAVE_REFS_ONLY_FRAME 99735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, -48 100735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_adjust_cfa_offset 48 1015c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 1025c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Ugly compile-time check, but we only have the preprocessor. 103fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko#if (FRAME_SIZE_SAVE_REFS_ONLY != 48) 104fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko#error "FRAME_SIZE_SAVE_REFS_ONLY(MIPS) size not as expected." 1055c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif 1065c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 107735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung sw $ra, 44($sp) 108735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_rel_offset 31, 44 109735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung sw $s8, 40($sp) 110735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_rel_offset 30, 40 111735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung sw $gp, 36($sp) 112735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_rel_offset 28, 36 113735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung sw $s7, 32($sp) 114735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_rel_offset 23, 32 115735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung sw $s6, 28($sp) 116735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_rel_offset 22, 28 117735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung sw $s5, 24($sp) 118735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_rel_offset 21, 24 119735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung sw $s4, 20($sp) 120735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_rel_offset 20, 20 121735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung sw $s3, 16($sp) 122735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_rel_offset 19, 16 123735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung sw $s2, 12($sp) 124735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_rel_offset 18, 12 125735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung # 2 words for alignment and bottom word will hold Method* 1261d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers 1274af77b7636fe98aae443b46a241fd9a29f16e291Douglas Leung lw $t0, %got(_ZN3art7Runtime9instance_E)($gp) 1284af77b7636fe98aae443b46a241fd9a29f16e291Douglas Leung lw $t0, 0($t0) 129fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko lw $t0, RUNTIME_SAVE_REFS_ONLY_METHOD_OFFSET($t0) 1301d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers sw $t0, 0($sp) # Place Method* at bottom of stack. 1311d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame. 132735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, -ARG_SLOT_SIZE # reserve argument slots on the stack 133735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_adjust_cfa_offset ARG_SLOT_SIZE 1345bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm 1355bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 136fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko.macro RESTORE_SAVE_REFS_ONLY_FRAME 137735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, ARG_SLOT_SIZE # remove argument slots on the stack 138735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_adjust_cfa_offset -ARG_SLOT_SIZE 139735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $ra, 44($sp) 140bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 31 141735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $s8, 40($sp) 142bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 30 143735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $gp, 36($sp) 144bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 28 145735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $s7, 32($sp) 146bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 23 147735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $s6, 28($sp) 148bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 22 149735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $s5, 24($sp) 150bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 21 151735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $s4, 20($sp) 152bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 20 153735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $s3, 16($sp) 154bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 19 155735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $s2, 12($sp) 156bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 18 157735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, 48 158735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_adjust_cfa_offset -48 1595bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm 1605bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 161fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko.macro RESTORE_SAVE_REFS_ONLY_FRAME_AND_RETURN 162fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko RESTORE_SAVE_REFS_ONLY_FRAME 1638d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $ra 164735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung nop 1655bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm 1665bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 1675bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 1685bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Macro that sets up the callee save frame to conform with 169fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko * Runtime::CreateCalleeSaveMethod(kSaveRefsAndArgs). 1701b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze * callee-save: $a1-$a3, $t0-$t1, $s2-$s8, $gp, $ra, $f8-$f19 1711b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze * (26 total + 1 word padding + method*) 1725bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 173fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko.macro SETUP_SAVE_REFS_AND_ARGS_FRAME_REGISTERS_ONLY 1741b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $sp, $sp, -112 1751b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_adjust_cfa_offset 112 1765c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 1775c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Ugly compile-time check, but we only have the preprocessor. 1781b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#if (FRAME_SIZE_SAVE_REFS_AND_ARGS != 112) 179fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko#error "FRAME_SIZE_SAVE_REFS_AND_ARGS(MIPS) size not as expected." 1805c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif 1815c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 1821b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $ra, 108($sp) 1831b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 31, 108 1841b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $s8, 104($sp) 1851b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 30, 104 1861b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $gp, 100($sp) 1871b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 28, 100 1881b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $s7, 96($sp) 1891b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 23, 96 1901b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $s6, 92($sp) 1911b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 22, 92 1921b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $s5, 88($sp) 1931b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 21, 88 1941b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $s4, 84($sp) 1951b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 20, 84 1961b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $s3, 80($sp) 1971b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 19, 80 1981b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $s2, 76($sp) 1991b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 18, 76 2001b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $t1, 72($sp) 2011b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 9, 72 2021b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $t0, 68($sp) 2031b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 8, 68 2041b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $a3, 64($sp) 2051b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 7, 64 2061b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $a2, 60($sp) 2071b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 6, 60 2081b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sw $a1, 56($sp) 2091b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_rel_offset 5, 56 2101b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze SDu $f18, $f19, 48, $sp, $t8 2111b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze SDu $f16, $f17, 40, $sp, $t8 2121b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze SDu $f14, $f15, 32, $sp, $t8 2131b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze SDu $f12, $f13, 24, $sp, $t8 2141b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze SDu $f10, $f11, 16, $sp, $t8 2151b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze SDu $f8, $f9, 8, $sp, $t8 216fa147e22a73c6df166b08a2f71f9c9b52b09d17cjeffhao # bottom will hold Method* 217735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung.endm 2181d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers 219735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung /* 220735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung * Macro that sets up the callee save frame to conform with 221fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko * Runtime::CreateCalleeSaveMethod(kSaveRefsAndArgs). Restoration assumes non-moving GC. 2221b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze * callee-save: $a1-$a3, $t0-$t1, $s2-$s8, $gp, $ra, $f8-$f19 2231b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze * (26 total + 1 word padding + method*) 224735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung * Clobbers $t0 and $sp 225735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots. 226fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko * Reserves FRAME_SIZE_SAVE_REFS_AND_ARGS + ARG_SLOT_SIZE bytes on the stack 227735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung */ 228fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko.macro SETUP_SAVE_REFS_AND_ARGS_FRAME 229fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_AND_ARGS_FRAME_REGISTERS_ONLY 2304af77b7636fe98aae443b46a241fd9a29f16e291Douglas Leung lw $t0, %got(_ZN3art7Runtime9instance_E)($gp) 2314af77b7636fe98aae443b46a241fd9a29f16e291Douglas Leung lw $t0, 0($t0) 232fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko lw $t0, RUNTIME_SAVE_REFS_AND_ARGS_METHOD_OFFSET($t0) 2331d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers sw $t0, 0($sp) # Place Method* at bottom of stack. 2341d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame. 235735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, -ARG_SLOT_SIZE # reserve argument slots on the stack 236735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_adjust_cfa_offset ARG_SLOT_SIZE 237735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung.endm 238735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung 239735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung /* 240735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung * Macro that sets up the callee save frame to conform with 241fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko * Runtime::CreateCalleeSaveMethod(kSaveRefsAndArgs). Restoration assumes non-moving GC. 2421b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze * callee-save: $a1-$a3, $t0-$t1, $s2-$s8, $gp, $ra, $f8-$f19 2431b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze * (26 total + 1 word padding + method*) 244735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung * Clobbers $sp 245735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung * Use $a0 as the Method* and loads it into bottom of stack. 246735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots. 247fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko * Reserves FRAME_SIZE_SAVE_REFS_AND_ARGS + ARG_SLOT_SIZE bytes on the stack 248735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung */ 249fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko.macro SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_A0 250fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_AND_ARGS_FRAME_REGISTERS_ONLY 251735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung sw $a0, 0($sp) # Place Method* at bottom of stack. 252735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame. 253735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, -ARG_SLOT_SIZE # reserve argument slots on the stack 254735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_adjust_cfa_offset ARG_SLOT_SIZE 2555bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm 2565bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 257fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko.macro RESTORE_SAVE_REFS_AND_ARGS_FRAME 258735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, ARG_SLOT_SIZE # remove argument slots on the stack 259735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_adjust_cfa_offset -ARG_SLOT_SIZE 2601b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $ra, 108($sp) 261bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 31 2621b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $s8, 104($sp) 263bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 30 2641b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $gp, 100($sp) 265bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 28 2661b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $s7, 96($sp) 267bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 23 2681b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $s6, 92($sp) 269bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 22 2701b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $s5, 88($sp) 271bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 21 2721b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $s4, 84($sp) 273bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 20 2741b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $s3, 80($sp) 275bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 19 2761b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $s2, 76($sp) 277bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 18 2781b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $t1, 72($sp) 2791b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_restore 9 2801b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $t0, 68($sp) 2811b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_restore 8 2821b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $a3, 64($sp) 283bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 7 2841b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $a2, 60($sp) 285bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 6 2861b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $a1, 56($sp) 287bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 5 2881b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LDu $f18, $f19, 48, $sp, $t8 2891b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LDu $f16, $f17, 40, $sp, $t8 2901b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LDu $f14, $f15, 32, $sp, $t8 2911b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LDu $f12, $f13, 24, $sp, $t8 2921b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LDu $f10, $f11, 16, $sp, $t8 2931b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LDu $f8, $f9, 8, $sp, $t8 2941b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $sp, $sp, 112 # pop frame 2951b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .cfi_adjust_cfa_offset -112 2965bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm 2975bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 2985bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 299952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko * Macro that sets up the callee save frame to conform with 300952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko * Runtime::CreateCalleeSaveMethod(kSaveEverything). 3013b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko * when the $sp has already been decremented by FRAME_SIZE_SAVE_EVERYTHING. 302952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko * Callee-save: $at, $v0-$v1, $a0-$a3, $t0-$t7, $s0-$s7, $t8-$t9, $gp, $fp $ra, $f0-$f31; 303952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko * 28(GPR)+ 32(FPR) + 3 words for padding and 1 word for Method* 304952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko * Clobbers $t0 and $t1. 305952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots. 306fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko * Reserves FRAME_SIZE_SAVE_EVERYTHING + ARG_SLOT_SIZE bytes on the stack. 307952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko * This macro sets up $gp; entrypoints using it should start with ENTRY_NO_GP. 308952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko */ 3093b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko.macro SETUP_SAVE_EVERYTHING_FRAME_DECREMENTED_SP 310952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko // Ugly compile-time check, but we only have the preprocessor. 311fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko#if (FRAME_SIZE_SAVE_EVERYTHING != 256) 312fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko#error "FRAME_SIZE_SAVE_EVERYTHING(MIPS) size not as expected." 313952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko#endif 314952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko 315952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $ra, 252($sp) 316952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 31, 252 317952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $fp, 248($sp) 318952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 30, 248 319952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $gp, 244($sp) 320952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 28, 244 321952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $t9, 240($sp) 322952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 25, 240 323952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $t8, 236($sp) 324952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 24, 236 325952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $s7, 232($sp) 326952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 23, 232 327952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $s6, 228($sp) 328952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 22, 228 329952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $s5, 224($sp) 330952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 21, 224 331952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $s4, 220($sp) 332952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 20, 220 333952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $s3, 216($sp) 334952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 19, 216 335952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $s2, 212($sp) 336952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 18, 212 337952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $s1, 208($sp) 338952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 17, 208 339952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $s0, 204($sp) 340952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 16, 204 341952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $t7, 200($sp) 342952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 15, 200 343952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $t6, 196($sp) 344952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 14, 196 345952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $t5, 192($sp) 346952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 13, 192 347952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $t4, 188($sp) 348952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 12, 188 349952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $t3, 184($sp) 350952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 11, 184 351952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $t2, 180($sp) 352952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 10, 180 353952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $t1, 176($sp) 354952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 9, 176 355952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $t0, 172($sp) 356952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 8, 172 357952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $a3, 168($sp) 358952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 7, 168 359952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $a2, 164($sp) 360952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 6, 164 361952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $a1, 160($sp) 362952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 5, 160 363952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $a0, 156($sp) 364952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 4, 156 365952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $v1, 152($sp) 366952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 3, 152 367952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $v0, 148($sp) 368952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 2, 148 369952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko 370952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko // Set up $gp, clobbering $ra and using the branch delay slot for a useful instruction. 371952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko bal 1f 3722e42cf12e7bd62c5455a9c5ac0fc072de0f31884Goran Jakovljevic .set push 3732e42cf12e7bd62c5455a9c5ac0fc072de0f31884Goran Jakovljevic .set noat 374952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $at, 144($sp) 375952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_rel_offset 1, 144 3762e42cf12e7bd62c5455a9c5ac0fc072de0f31884Goran Jakovljevic .set pop 377952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko1: 378952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cpload $ra 379952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko 380952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f30, $f31, 136, $sp, $t1 381952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f28, $f29, 128, $sp, $t1 382952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f26, $f27, 120, $sp, $t1 383952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f24, $f25, 112, $sp, $t1 384952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f22, $f23, 104, $sp, $t1 385952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f20, $f21, 96, $sp, $t1 386952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f18, $f19, 88, $sp, $t1 387952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f16, $f17, 80, $sp, $t1 388952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f14, $f15, 72, $sp, $t1 389952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f12, $f13, 64, $sp, $t1 390952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f10, $f11, 56, $sp, $t1 391952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f8, $f9, 48, $sp, $t1 392952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f6, $f7, 40, $sp, $t1 393952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f4, $f5, 32, $sp, $t1 394952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f2, $f3, 24, $sp, $t1 395952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko SDu $f0, $f1, 16, $sp, $t1 396952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko 397952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko # 3 words padding and 1 word for holding Method* 398952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko 399952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $t0, %got(_ZN3art7Runtime9instance_E)($gp) 400952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $t0, 0($t0) 401fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko lw $t0, RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET($t0) 402952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $t0, 0($sp) # Place Method* at bottom of stack. 403952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame. 404952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko addiu $sp, $sp, -ARG_SLOT_SIZE # reserve argument slots on the stack 405952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_adjust_cfa_offset ARG_SLOT_SIZE 406952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko.endm 407952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko 4083b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko /* 4093b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko * Macro that sets up the callee save frame to conform with 4103b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko * Runtime::CreateCalleeSaveMethod(kSaveEverything). 4113b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko * Callee-save: $at, $v0-$v1, $a0-$a3, $t0-$t7, $s0-$s7, $t8-$t9, $gp, $fp $ra, $f0-$f31; 4123b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko * 28(GPR)+ 32(FPR) + 3 words for padding and 1 word for Method* 4133b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko * Clobbers $t0 and $t1. 4143b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots. 4153b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko * Reserves FRAME_SIZE_SAVE_EVERYTHING + ARG_SLOT_SIZE bytes on the stack. 4163b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko * This macro sets up $gp; entrypoints using it should start with ENTRY_NO_GP. 4173b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko */ 4183b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko.macro SETUP_SAVE_EVERYTHING_FRAME 4193b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko addiu $sp, $sp, -(FRAME_SIZE_SAVE_EVERYTHING) 4203b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko .cfi_adjust_cfa_offset (FRAME_SIZE_SAVE_EVERYTHING) 4213b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko SETUP_SAVE_EVERYTHING_FRAME_DECREMENTED_SP 4223b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko.endm 4233b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko 424c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze.macro RESTORE_SAVE_EVERYTHING_FRAME restore_a0=1 425952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko addiu $sp, $sp, ARG_SLOT_SIZE # remove argument slots on the stack 426952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_adjust_cfa_offset -ARG_SLOT_SIZE 427952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko 428952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f30, $f31, 136, $sp, $t1 429952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f28, $f29, 128, $sp, $t1 430952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f26, $f27, 120, $sp, $t1 431952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f24, $f25, 112, $sp, $t1 432952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f22, $f23, 104, $sp, $t1 433952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f20, $f21, 96, $sp, $t1 434952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f18, $f19, 88, $sp, $t1 435952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f16, $f17, 80, $sp, $t1 436952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f14, $f15, 72, $sp, $t1 437952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f12, $f13, 64, $sp, $t1 438952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f10, $f11, 56, $sp, $t1 439952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f8, $f9, 48, $sp, $t1 440952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f6, $f7, 40, $sp, $t1 441952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f4, $f5, 32, $sp, $t1 442952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f2, $f3, 24, $sp, $t1 443952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko LDu $f0, $f1, 16, $sp, $t1 444952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko 445952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $ra, 252($sp) 446952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 31 447952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $fp, 248($sp) 448952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 30 449952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $gp, 244($sp) 450952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 28 451952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $t9, 240($sp) 452952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 25 453952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $t8, 236($sp) 454952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 24 455952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $s7, 232($sp) 456952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 23 457952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $s6, 228($sp) 458952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 22 459952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $s5, 224($sp) 460952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 21 461952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $s4, 220($sp) 462952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 20 463952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $s3, 216($sp) 464952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 19 465952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $s2, 212($sp) 466952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 18 467952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $s1, 208($sp) 468952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 17 469952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $s0, 204($sp) 470952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 16 471952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $t7, 200($sp) 472952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 15 473952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $t6, 196($sp) 474952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 14 475952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $t5, 192($sp) 476952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 13 477952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $t4, 188($sp) 478952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 12 479952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $t3, 184($sp) 480952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 11 481952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $t2, 180($sp) 482952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 10 483952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $t1, 176($sp) 484952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 9 485952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $t0, 172($sp) 486952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 8 487952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $a3, 168($sp) 488952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 7 489952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $a2, 164($sp) 490952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 6 491952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $a1, 160($sp) 492952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 5 493c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze .if \restore_a0 494952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $a0, 156($sp) 495952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 4 496c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze .endif 497952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $v1, 152($sp) 498952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 3 499952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $v0, 148($sp) 500952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 2 5012e42cf12e7bd62c5455a9c5ac0fc072de0f31884Goran Jakovljevic .set push 5022e42cf12e7bd62c5455a9c5ac0fc072de0f31884Goran Jakovljevic .set noat 503952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lw $at, 144($sp) 504952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_restore 1 5052e42cf12e7bd62c5455a9c5ac0fc072de0f31884Goran Jakovljevic .set pop 506952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko 507952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko addiu $sp, $sp, 256 # pop frame 508952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko .cfi_adjust_cfa_offset -256 509952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko.endm 510952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko 511952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko /* 512c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze * Macro that calls through to artDeliverPendingExceptionFromCode, where the pending 513c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze * exception is Thread::Current()->exception_ when the runtime method frame is ready. 514c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze * Requires $gp properly set up. 5155bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 516c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze.macro DELIVER_PENDING_EXCEPTION_FRAME_READY 5178161c0336b97e11e02c000af357f8f40de2e23e4jeffhao la $t9, artDeliverPendingExceptionFromCode 5188d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $t9 # artDeliverPendingExceptionFromCode(Thread*) 5191d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers move $a0, rSELF # pass Thread::Current 5205bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm 5215bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 522c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze /* 523c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze * Macro that calls through to artDeliverPendingExceptionFromCode, where the pending 524c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze * exception is Thread::Current()->exception_. 525c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze * Requires $gp properly set up. 526c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze */ 527c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze.macro DELIVER_PENDING_EXCEPTION 528c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze SETUP_SAVE_ALL_CALLEE_SAVES_FRAME # save callee saves for throw 529c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze DELIVER_PENDING_EXCEPTION_FRAME_READY 530c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze.endm 531c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze 5325bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.macro RETURN_IF_NO_EXCEPTION 5337fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_ 534fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko RESTORE_SAVE_REFS_ONLY_FRAME 5358161c0336b97e11e02c000af357f8f40de2e23e4jeffhao bnez $t0, 1f # success if no exception is pending 5365bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee nop 5378d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $ra 5385bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee nop 5395bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee1: 5405bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee DELIVER_PENDING_EXCEPTION 5415bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm 5425bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 5435bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.macro RETURN_IF_ZERO 544fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko RESTORE_SAVE_REFS_ONLY_FRAME 5457fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao bnez $v0, 1f # success? 5465bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee nop 5478d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $ra # return on success 5485bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee nop 5495bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee1: 5505bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee DELIVER_PENDING_EXCEPTION 5515bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm 5525bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 5531cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe.macro RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER 554fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko RESTORE_SAVE_REFS_ONLY_FRAME 5557fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao beqz $v0, 1f # success? 5565bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee nop 5578d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $ra # return on success 5585bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee nop 5595bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee1: 5605bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee DELIVER_PENDING_EXCEPTION 5615bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm 5625bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 5635bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 5643bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic * On stack replacement stub. 5653bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic * On entry: 5663bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic * a0 = stack to copy 5673bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic * a1 = size of stack 5683bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic * a2 = pc to call 5693bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic * a3 = JValue* result 5703bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic * [sp + 16] = shorty 5713bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic * [sp + 20] = thread 5723bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic */ 5733bc13817a19e36f3833bb44624ef86800892eaadGoran JakovljevicENTRY art_quick_osr_stub 5743bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic // Save callee general purpose registers, RA and GP. 5753bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic addiu $sp, $sp, -48 5763bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_adjust_cfa_offset 48 5773bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $ra, 44($sp) 5783bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_rel_offset 31, 44 5793bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $s8, 40($sp) 5803bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_rel_offset 30, 40 5813bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $gp, 36($sp) 5823bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_rel_offset 28, 36 5833bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $s7, 32($sp) 5843bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_rel_offset 23, 32 5853bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $s6, 28($sp) 5863bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_rel_offset 22, 28 5873bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $s5, 24($sp) 5883bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_rel_offset 21, 24 5893bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $s4, 20($sp) 5903bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_rel_offset 20, 20 5913bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $s3, 16($sp) 5923bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_rel_offset 19, 16 5933bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $s2, 12($sp) 5943bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_rel_offset 18, 12 5953bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $s1, 8($sp) 5963bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_rel_offset 17, 8 5973bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $s0, 4($sp) 5983bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_rel_offset 16, 4 5993bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic 6003bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic move $s8, $sp # Save the stack pointer 6013bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic move $s7, $a1 # Save size of stack 6023bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic move $s6, $a2 # Save the pc to call 6033bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw rSELF, 48+20($sp) # Save managed thread pointer into rSELF 6043bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic addiu $t0, $sp, -12 # Reserve space for stack pointer, 6053bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic # JValue* result, and ArtMethod* slot. 6063bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic srl $t0, $t0, 4 # Align stack pointer to 16 bytes 6073bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sll $sp, $t0, 4 # Update stack pointer 6083bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $s8, 4($sp) # Save old stack pointer 6093bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $a3, 8($sp) # Save JValue* result 6103bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $zero, 0($sp) # Store null for ArtMethod* at bottom of frame 6113bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic subu $sp, $a1 # Reserve space for callee stack 6123bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic move $a2, $a1 6133bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic move $a1, $a0 6143bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic move $a0, $sp 6153bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic la $t9, memcpy 6163bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic jalr $t9 # memcpy (dest a0, src a1, bytes a2) 6173bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic addiu $sp, $sp, -16 # make space for argument slots for memcpy 6183bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic bal .Losr_entry # Call the method 6193bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic addiu $sp, $sp, 16 # restore stack after memcpy 6203bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $a2, 8($sp) # Restore JValue* result 6213bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $sp, 4($sp) # Restore saved stack pointer 6223bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $a0, 48+16($sp) # load shorty 6233bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lbu $a0, 0($a0) # load return type 6243bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic li $a1, 'D' # put char 'D' into a1 6253bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic beq $a0, $a1, .Losr_fp_result # Test if result type char == 'D' 6263bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic li $a1, 'F' # put char 'F' into a1 6273bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic beq $a0, $a1, .Losr_fp_result # Test if result type char == 'F' 6283bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic nop 6293bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $v0, 0($a2) 6303bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic b .Losr_exit 6313bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $v1, 4($a2) # store v0/v1 into result 6323bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic.Losr_fp_result: 6333bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic SDu $f0, $f1, 0, $a2, $t0 # store f0/f1 into result 6343bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic.Losr_exit: 6353bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $ra, 44($sp) 6363bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_restore 31 6373bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $s8, 40($sp) 6383bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_restore 30 6393bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $gp, 36($sp) 6403bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_restore 28 6413bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $s7, 32($sp) 6423bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_restore 23 6433bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $s6, 28($sp) 6443bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_restore 22 6453bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $s5, 24($sp) 6463bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_restore 21 6473bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $s4, 20($sp) 6483bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_restore 20 6493bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $s3, 16($sp) 6503bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_restore 19 6513bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $s2, 12($sp) 6523bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_restore 18 6533bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $s1, 8($sp) 6543bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_restore 17 6553bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic lw $s0, 4($sp) 6563bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_restore 16 6573bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic jalr $zero, $ra 6583bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic addiu $sp, $sp, 48 6593bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic .cfi_adjust_cfa_offset -48 6603bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic.Losr_entry: 6613bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic addiu $s7, $s7, -4 6623bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic addu $t0, $s7, $sp 6633bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic move $t9, $s6 6643bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic jalr $zero, $t9 6653bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic sw $ra, 0($t0) # Store RA per the compiler ABI 6663bc13817a19e36f3833bb44624ef86800892eaadGoran JakovljevicEND art_quick_osr_stub 6673bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic 6683bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic /* 6697fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * On entry $a0 is uint32_t* gprs_ and $a1 is uint32_t* fprs_ 6705bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * FIXME: just guessing about the shape of the jmpbuf. Where will pc be? 6715bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 672d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoENTRY art_quick_do_long_jump 673e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f0, $f1, 0*8, $a1, $t1 674e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f2, $f3, 1*8, $a1, $t1 675e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f4, $f5, 2*8, $a1, $t1 676e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f6, $f7, 3*8, $a1, $t1 677e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f8, $f9, 4*8, $a1, $t1 678e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f10, $f11, 5*8, $a1, $t1 679e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f12, $f13, 6*8, $a1, $t1 680e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f14, $f15, 7*8, $a1, $t1 681e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f16, $f17, 8*8, $a1, $t1 682e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f18, $f19, 9*8, $a1, $t1 683e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f20, $f21, 10*8, $a1, $t1 684e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f22, $f23, 11*8, $a1, $t1 685e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f24, $f25, 12*8, $a1, $t1 686e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f26, $f27, 13*8, $a1, $t1 687e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f28, $f29, 14*8, $a1, $t1 688e34652f15f32666323052a6718a63248244f1e66Duane Sand LDu $f30, $f31, 15*8, $a1, $t1 689e34652f15f32666323052a6718a63248244f1e66Duane Sand 690748dd957eecbce2f379a3182ce95c19be308a54eChris Dearman .set push 691748dd957eecbce2f379a3182ce95c19be308a54eChris Dearman .set nomacro 692748dd957eecbce2f379a3182ce95c19be308a54eChris Dearman .set noat 6937fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $at, 4($a0) 694748dd957eecbce2f379a3182ce95c19be308a54eChris Dearman .set pop 6957fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $v0, 8($a0) 6967fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $v1, 12($a0) 6977fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $a1, 20($a0) 6987fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $a2, 24($a0) 6997fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $a3, 28($a0) 7007fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $t0, 32($a0) 7017fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $t1, 36($a0) 7027fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $t2, 40($a0) 7037fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $t3, 44($a0) 7047fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $t4, 48($a0) 7057fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $t5, 52($a0) 7067fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $t6, 56($a0) 7077fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $t7, 60($a0) 7087fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $s0, 64($a0) 7097fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $s1, 68($a0) 7107fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $s2, 72($a0) 7117fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $s3, 76($a0) 7127fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $s4, 80($a0) 7137fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $s5, 84($a0) 7147fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $s6, 88($a0) 7157fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $s7, 92($a0) 7167fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $t8, 96($a0) 7177fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $t9, 100($a0) 7187fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $gp, 112($a0) 7197fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $sp, 116($a0) 7207fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $fp, 120($a0) 7217fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $ra, 124($a0) 7227fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao lw $a0, 16($a0) 723590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic move $v0, $zero # clear result registers v0 and v1 (in branch delay slot) 72475969963213c39a029e01c3b9440fb388d793afbGoran Jakovljevic jalr $zero, $t9 # do long jump 7257fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao move $v1, $zero 726d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_do_long_jump 7275bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 7285bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 7295bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Called by managed code, saves most registers (forms basis of long jump context) and passes 7305bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * the bottom of the stack. artDeliverExceptionFromCode will place the callee save Method* at 73184bc06e30ba12c3ff07e577c52b63b9df162af7eLazar Trsic * the bottom of the thread. On entry a0 holds Throwable* 7325bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 733468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_deliver_exception 734fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_ALL_CALLEE_SAVES_FRAME 7358161c0336b97e11e02c000af357f8f40de2e23e4jeffhao la $t9, artDeliverExceptionFromCode 7368d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $t9 # artDeliverExceptionFromCode(Throwable*, Thread*) 7371d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers move $a1, rSELF # pass Thread::Current 738468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_deliver_exception 7395bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 7405bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 7415bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Called by managed code to create and deliver a NullPointerException 7425bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 743d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao .extern artThrowNullPointerExceptionFromCode 744804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir MarkoENTRY_NO_GP art_quick_throw_null_pointer_exception 745804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko // Note that setting up $gp does not rely on $t9 here, so branching here directly is OK, 746804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko // even after clobbering any registers we don't need to preserve, such as $gp or $t0. 747804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko SETUP_SAVE_EVERYTHING_FRAME 7488161c0336b97e11e02c000af357f8f40de2e23e4jeffhao la $t9, artThrowNullPointerExceptionFromCode 7498d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $t9 # artThrowNullPointerExceptionFromCode(Thread*) 7501d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers move $a0, rSELF # pass Thread::Current 751468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_throw_null_pointer_exception 7525bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 753e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray 754e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray /* 755e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray * Call installed by a signal handler to create and deliver a NullPointerException. 756e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray */ 757e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray .extern artThrowNullPointerExceptionFromSignal 7583b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir MarkoENTRY_NO_GP_CUSTOM_CFA art_quick_throw_null_pointer_exception_from_signal, FRAME_SIZE_SAVE_EVERYTHING 7593b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko SETUP_SAVE_EVERYTHING_FRAME_DECREMENTED_SP 7603b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko # Retrieve the fault address from the padding where the signal handler stores it. 7613b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko lw $a0, (ARG_SLOT_SIZE + __SIZEOF_POINTER__)($sp) 762e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray la $t9, artThrowNullPointerExceptionFromSignal 763e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray jalr $zero, $t9 # artThrowNullPointerExceptionFromSignal(uintptr_t, Thread*) 764e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray move $a1, rSELF # pass Thread::Current 765e8e1127da3f154fae8d2eb16a94203544a182159Nicolas GeoffrayEND art_quick_throw_null_pointer_exception_from_signal 766e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray 7675bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 7685bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Called by managed code to create and deliver an ArithmeticException 7695bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 770d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao .extern artThrowDivZeroFromCode 771804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir MarkoENTRY_NO_GP art_quick_throw_div_zero 772804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko SETUP_SAVE_EVERYTHING_FRAME 7738161c0336b97e11e02c000af357f8f40de2e23e4jeffhao la $t9, artThrowDivZeroFromCode 7748d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $t9 # artThrowDivZeroFromCode(Thread*) 7751d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers move $a0, rSELF # pass Thread::Current 776468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_throw_div_zero 7775bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 7785bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 7795bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException 7805bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 781d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao .extern artThrowArrayBoundsFromCode 782804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir MarkoENTRY_NO_GP art_quick_throw_array_bounds 783804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko // Note that setting up $gp does not rely on $t9 here, so branching here directly is OK, 784804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko // even after clobbering any registers we don't need to preserve, such as $gp or $t0. 785804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko SETUP_SAVE_EVERYTHING_FRAME 7868161c0336b97e11e02c000af357f8f40de2e23e4jeffhao la $t9, artThrowArrayBoundsFromCode 7878d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $t9 # artThrowArrayBoundsFromCode(index, limit, Thread*) 7881d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers move $a2, rSELF # pass Thread::Current 789468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_throw_array_bounds 7905bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 79157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers /* 79287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko * Called by managed code to create and deliver a StringIndexOutOfBoundsException 79387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko * as if thrown from a call to String.charAt(). 79487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko */ 79587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko .extern artThrowStringBoundsFromCode 796804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir MarkoENTRY_NO_GP art_quick_throw_string_bounds 797804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko SETUP_SAVE_EVERYTHING_FRAME 79887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko la $t9, artThrowStringBoundsFromCode 79987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko jalr $zero, $t9 # artThrowStringBoundsFromCode(index, limit, Thread*) 80087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko move $a2, rSELF # pass Thread::Current 80187f3fcbd0db352157fc59148e94647ef21b73bceVladimir MarkoEND art_quick_throw_string_bounds 80287f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko 80387f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko /* 80457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * Called by managed code to create and deliver a StackOverflowError. 80557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers */ 806d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao .extern artThrowStackOverflowFromCode 807468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_throw_stack_overflow 808fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_ALL_CALLEE_SAVES_FRAME 8098161c0336b97e11e02c000af357f8f40de2e23e4jeffhao la $t9, artThrowStackOverflowFromCode 8108d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $t9 # artThrowStackOverflowFromCode(Thread*) 8111d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers move $a0, rSELF # pass Thread::Current 812468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_throw_stack_overflow 8135bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 81457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers /* 8155bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * All generated callsites for interface invokes and invocation slow paths will load arguments 8167fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * as usual - except instead of loading arg0/$a0 with the target Method*, arg0/$a0 will contain 8177ea6a170486d81b127e69673cd1020c4db628c93Nicolas Geoffray * the method_idx. This wrapper will save arg1-arg3, and call the appropriate C helper. 8187fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * NOTE: "this" is first visable argument of the target, and so can be found in arg1/$a1. 8195bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * 8207fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * The helper will attempt to locate the target and return a 64-bit result in $v0/$v1 consisting 8217fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * of the target Method* in $v0 and method->code_ in $v1. 8225bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * 8232cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier * If unsuccessful, the helper will return null/null. There will be a pending exception in the 8245bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * thread and we branch to another stub to deliver it. 8255bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * 8265bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * On success this wrapper will restore arguments and *jump* to the target, leaving the lr 8275bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * pointing back to the original caller. 8285bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 8293031c8da0c5009183f770b005c245f9bf2a4d01bAndreas Gampe.macro INVOKE_TRAMPOLINE_BODY cxx_name 8305bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee .extern \cxx_name 831fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_AND_ARGS_FRAME # save callee saves in case allocation triggers GC 8327ea6a170486d81b127e69673cd1020c4db628c93Nicolas Geoffray move $a2, rSELF # pass Thread::Current 833590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, \cxx_name 834590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 # (method_idx, this, Thread*, $sp) 8357ea6a170486d81b127e69673cd1020c4db628c93Nicolas Geoffray addiu $a3, $sp, ARG_SLOT_SIZE # pass $sp (remove arg slots) 8367ea6a170486d81b127e69673cd1020c4db628c93Nicolas Geoffray move $a0, $v0 # save target Method* 837fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko RESTORE_SAVE_REFS_AND_ARGS_FRAME 838fa147e22a73c6df166b08a2f71f9c9b52b09d17cjeffhao beqz $v0, 1f 8397ea6a170486d81b127e69673cd1020c4db628c93Nicolas Geoffray move $t9, $v1 # save $v0->code_ 8408d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $t9 8415bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee nop 8425bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee1: 8435bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee DELIVER_PENDING_EXCEPTION 8443031c8da0c5009183f770b005c245f9bf2a4d01bAndreas Gampe.endm 8453031c8da0c5009183f770b005c245f9bf2a4d01bAndreas Gampe.macro INVOKE_TRAMPOLINE c_name, cxx_name 8463031c8da0c5009183f770b005c245f9bf2a4d01bAndreas GampeENTRY \c_name 8473031c8da0c5009183f770b005c245f9bf2a4d01bAndreas Gampe INVOKE_TRAMPOLINE_BODY \cxx_name 848d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND \c_name 8495bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm 8505bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 8518dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck 8525bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 8538dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck 8548dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck 8558dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck 8568dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck 8575bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 8581b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze// Each of the following macros expands into four instructions or 16 bytes. 8591b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze// They are used to build indexable "tables" of code. 8601b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 8611b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.macro LOAD_WORD_TO_REG reg, next_arg, index_reg, label 862ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic lw $\reg, -4($\next_arg) # next_arg points to argument after the current one (offset is 4) 863ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic b \label 8641b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $\index_reg, 16 8651b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .balign 16 866ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic.endm 867ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic 8681b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.macro LOAD_LONG_TO_REG reg1, reg2, next_arg, index_reg, next_index, label 869ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic lw $\reg1, -8($\next_arg) # next_arg points to argument after the current one (offset is 8) 870ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic lw $\reg2, -4($\next_arg) 871ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic b \label 8721b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze li $\index_reg, \next_index 8731b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .balign 16 874ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic.endm 875ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic 8761b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.macro LOAD_FLOAT_TO_REG reg, next_arg, index_reg, label 877ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic lwc1 $\reg, -4($\next_arg) # next_arg points to argument after the current one (offset is 4) 878ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic b \label 8791b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $\index_reg, 16 8801b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .balign 16 881ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic.endm 882ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic 8831b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#if defined(__mips_isa_rev) && __mips_isa_rev > 2 8841b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze// LDu expands into 3 instructions for 64-bit FPU, so index_reg cannot be updated here. 8851b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.macro LOAD_DOUBLE_TO_REG reg1, reg2, next_arg, index_reg, tmp, label 8861b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .set reorder # force use of the branch delay slot 887ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic LDu $\reg1, $\reg2, -8, $\next_arg, $\tmp # next_arg points to argument after the current one 888ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic # (offset is 8) 889ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic b \label 8901b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .set noreorder 8911b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .balign 16 8921b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.endm 8931b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#else 8941b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze// LDu expands into 2 instructions for 32-bit FPU, so index_reg is updated here. 8951b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.macro LOAD_DOUBLE_TO_REG reg1, reg2, next_arg, index_reg, tmp, label 8961b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LDu $\reg1, $\reg2, -8, $\next_arg, $\tmp # next_arg points to argument after the current one 8971b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze # (offset is 8) 8981b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze b \label 8991b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $\index_reg, 16 9001b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .balign 16 9011b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.endm 9021b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#endif 9031b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 9041b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.macro LOAD_END index_reg, next_index, label 9051b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze b \label 9061b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze li $\index_reg, \next_index 9071b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .balign 16 908ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic.endm 909ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic 910590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic#define SPILL_SIZE 32 911590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic 91279fe539587d4c09244172d0168eeed0ec9770466Jeff Hao /* 913ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * Invocation stub for quick code. 9145d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao * On entry: 9155d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao * a0 = method pointer 9162cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier * a1 = argument array or null for no argument methods 9175d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao * a2 = size of argument array in bytes 9185d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao * a3 = (managed) thread pointer 9196474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao * [sp + 16] = JValue* result 9200177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers * [sp + 20] = shorty 9215d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao */ 9225d9173014c1ca09f7249a6b07629aa37778b5f8fJeff HaoENTRY art_quick_invoke_stub 9235d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao sw $a0, 0($sp) # save out a0 924590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic addiu $sp, $sp, -SPILL_SIZE # spill s0, s1, fp, ra and gp 925590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic .cfi_adjust_cfa_offset SPILL_SIZE 926590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic sw $gp, 16($sp) 9275d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao sw $ra, 12($sp) 9285d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao .cfi_rel_offset 31, 12 9295d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao sw $fp, 8($sp) 9305d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao .cfi_rel_offset 30, 8 9315d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao sw $s1, 4($sp) 9325d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao .cfi_rel_offset 17, 4 9335d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao sw $s0, 0($sp) 9345d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao .cfi_rel_offset 16, 0 9355d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao move $fp, $sp # save sp in fp 9365d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao .cfi_def_cfa_register 30 9375d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao move $s1, $a3 # move managed thread pointer into s1 9385d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao addiu $s0, $zero, SUSPEND_CHECK_INTERVAL # reset s0 to suspend check interval 939ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic addiu $t0, $a2, 4 # create space for ArtMethod* in frame. 940735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung subu $t0, $sp, $t0 # reserve & align *stack* to 16 bytes: 941ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic srl $t0, $t0, 4 # native calling convention only aligns to 8B, 942ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic sll $sp, $t0, 4 # so we have to ensure ART 16B alignment ourselves. 943ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic addiu $a0, $sp, 4 # pass stack pointer + ArtMethod* as dest for memcpy 944590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, memcpy 945590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 # (dest, src, bytes) 9465d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao addiu $sp, $sp, -16 # make space for argument slots for memcpy 9475d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao addiu $sp, $sp, 16 # restore stack after memcpy 948590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic lw $gp, 16($fp) # restore $gp 949590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic lw $a0, SPILL_SIZE($fp) # restore ArtMethod* 950ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic lw $a1, 4($sp) # a1 = this* 9511b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t8, $sp, 8 # t8 = pointer to the current argument (skip ArtMethod* and this*) 9521b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze li $t6, 0 # t6 = gpr_index = 0 (corresponds to A2; A0 and A1 are skipped) 9531b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze li $t7, 0 # t7 = fp_index = 0 9541b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $t9, 20 + SPILL_SIZE($fp) # get shorty (20 is offset from the $sp on entry + SPILL_SIZE 955590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic # as the $fp is SPILL_SIZE bytes below the $sp on entry) 9561b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t9, 1 # t9 = shorty + 1 (skip 1 for return type) 9571b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 9581b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze // Load the base addresses of tabInt ... tabDouble. 9591b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze // We will use the register indices (gpr_index, fp_index) to branch. 9601b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze // Note that the indices are scaled by 16, so they can be added to the bases directly. 9611b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#if defined(__mips_isa_rev) && __mips_isa_rev >= 6 9621b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lapc $t2, tabInt 9631b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lapc $t3, tabLong 9641b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lapc $t4, tabSingle 9651b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lapc $t5, tabDouble 9661b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#else 9671b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze bltzal $zero, tabBase # nal 9681b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t2, $ra, %lo(tabInt - tabBase) 9691b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabBase: 9701b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t3, $ra, %lo(tabLong - tabBase) 9711b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t4, $ra, %lo(tabSingle - tabBase) 9721b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t5, $ra, %lo(tabDouble - tabBase) 9731b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#endif 9741b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 975ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevicloop: 9761b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lbu $ra, 0($t9) # ra = shorty[i] 9771b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze beqz $ra, loopEnd # finish getting args when shorty[i] == '\0' 9781b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t9, 1 9791b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 9801b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $ra, -'J' 9811b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze beqz $ra, isLong # branch if result type char == 'J' 9821b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $ra, 'J' - 'D' 9831b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze beqz $ra, isDouble # branch if result type char == 'D' 9841b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $ra, 'D' - 'F' 9851b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze beqz $ra, isSingle # branch if result type char == 'F' 9861b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 9871b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addu $ra, $t2, $t6 9881b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze jalr $zero, $ra 9891b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t8, 4 # next_arg = curr_arg + 4 990ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic 991ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicisLong: 9921b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addu $ra, $t3, $t6 9931b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze jalr $zero, $ra 9941b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t8, 8 # next_arg = curr_arg + 8 995ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic 996ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicisSingle: 9971b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addu $ra, $t4, $t7 9981b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze jalr $zero, $ra 9991b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t8, 4 # next_arg = curr_arg + 4 10001b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 10011b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzeisDouble: 10021b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addu $ra, $t5, $t7 10031b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#if defined(__mips_isa_rev) && __mips_isa_rev > 2 10041b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t7, 16 # fp_index += 16 didn't fit into LOAD_DOUBLE_TO_REG 10051b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#endif 10061b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze jalr $zero, $ra 10071b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t8, 8 # next_arg = curr_arg + 8 1008ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic 1009ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicloopEnd: 1010e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier lw $t9, ART_METHOD_QUICK_CODE_OFFSET_32($a0) # get pointer to the code 10115d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao jalr $t9 # call the method 1012ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic sw $zero, 0($sp) # store null for ArtMethod* at bottom of frame 10135d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao move $sp, $fp # restore the stack 10145d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao lw $s0, 0($sp) 1015bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 16 10165d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao lw $s1, 4($sp) 1017bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 17 10185d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao lw $fp, 8($sp) 1019bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 30 10205d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao lw $ra, 12($sp) 1021bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison .cfi_restore 31 1022590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic addiu $sp, $sp, SPILL_SIZE 1023590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic .cfi_adjust_cfa_offset -SPILL_SIZE 10245d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao lw $t0, 16($sp) # get result pointer 10250177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers lw $t1, 20($sp) # get shorty 10260177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers lb $t1, 0($t1) # get result type char 1027ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic li $t2, 'D' # put char 'D' into t2 1028ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic beq $t1, $t2, 5f # branch if result type char == 'D' 1029ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic li $t3, 'F' # put char 'F' into t3 1030ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic beq $t1, $t3, 5f # branch if result type char == 'F' 10315d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao sw $v0, 0($t0) # store the result 10328d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $ra 10335d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao sw $v1, 4($t0) # store the other half of the result 1034ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic5: 1035e34652f15f32666323052a6718a63248244f1e66Duane Sand SDu $f0, $f1, 0, $t0, $t1 # store floating point result 10368d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $ra 1037e34652f15f32666323052a6718a63248244f1e66Duane Sand nop 10381b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 10391b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze // Note that gpr_index is kept within the range of tabInt and tabLong 10401b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze // and fp_index is kept within the range of tabSingle and tabDouble. 10411b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .balign 16 10421b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabInt: 10431b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_WORD_TO_REG a2, t8, t6, loop # a2 = current argument, gpr_index += 16 10441b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_WORD_TO_REG a3, t8, t6, loop # a3 = current argument, gpr_index += 16 10451b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_WORD_TO_REG t0, t8, t6, loop # t0 = current argument, gpr_index += 16 10461b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_WORD_TO_REG t1, t8, t6, loop # t1 = current argument, gpr_index += 16 10471b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_END t6, 4*16, loop # no more GPR args, gpr_index = 4*16 10481b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabLong: 10491b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_LONG_TO_REG a2, a3, t8, t6, 2*16, loop # a2_a3 = curr_arg, gpr_index = 2*16 10501b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_LONG_TO_REG t0, t1, t8, t6, 4*16, loop # t0_t1 = curr_arg, gpr_index = 4*16 10511b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_LONG_TO_REG t0, t1, t8, t6, 4*16, loop # t0_t1 = curr_arg, gpr_index = 4*16 10521b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_END t6, 4*16, loop # no more GPR args, gpr_index = 4*16 10531b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_END t6, 4*16, loop # no more GPR args, gpr_index = 4*16 10541b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabSingle: 10551b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_FLOAT_TO_REG f8, t8, t7, loop # f8 = curr_arg, fp_index += 16 10561b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_FLOAT_TO_REG f10, t8, t7, loop # f10 = curr_arg, fp_index += 16 10571b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_FLOAT_TO_REG f12, t8, t7, loop # f12 = curr_arg, fp_index += 16 10581b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_FLOAT_TO_REG f14, t8, t7, loop # f14 = curr_arg, fp_index += 16 10591b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_FLOAT_TO_REG f16, t8, t7, loop # f16 = curr_arg, fp_index += 16 10601b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_FLOAT_TO_REG f18, t8, t7, loop # f18 = curr_arg, fp_index += 16 10611b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_END t7, 6*16, loop # no more FPR args, fp_index = 6*16 10621b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabDouble: 10631b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_DOUBLE_TO_REG f8, f9, t8, t7, ra, loop # f8_f9 = curr_arg; if FPU32, fp_index += 16 10641b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_DOUBLE_TO_REG f10, f11, t8, t7, ra, loop # f10_f11 = curr_arg; if FPU32, fp_index += 16 10651b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_DOUBLE_TO_REG f12, f13, t8, t7, ra, loop # f12_f13 = curr_arg; if FPU32, fp_index += 16 10661b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_DOUBLE_TO_REG f14, f15, t8, t7, ra, loop # f14_f15 = curr_arg; if FPU32, fp_index += 16 10671b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_DOUBLE_TO_REG f16, f17, t8, t7, ra, loop # f16_f17 = curr_arg; if FPU32, fp_index += 16 10681b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_DOUBLE_TO_REG f18, f19, t8, t7, ra, loop # f18_f19 = curr_arg; if FPU32, fp_index += 16 10691b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_END t7, 6*16, loop # no more FPR args, fp_index = 6*16 10705d9173014c1ca09f7249a6b07629aa37778b5f8fJeff HaoEND art_quick_invoke_stub 10715d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 10725d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao /* 1073ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic * Invocation static stub for quick code. 1074ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic * On entry: 1075ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic * a0 = method pointer 1076ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic * a1 = argument array or null for no argument methods 1077ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic * a2 = size of argument array in bytes 1078ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic * a3 = (managed) thread pointer 1079ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic * [sp + 16] = JValue* result 1080ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic * [sp + 20] = shorty 1081ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic */ 1082ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicENTRY art_quick_invoke_static_stub 1083ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic sw $a0, 0($sp) # save out a0 1084590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic addiu $sp, $sp, -SPILL_SIZE # spill s0, s1, fp, ra and gp 1085590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic .cfi_adjust_cfa_offset SPILL_SIZE 1086590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic sw $gp, 16($sp) 1087ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic sw $ra, 12($sp) 1088ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic .cfi_rel_offset 31, 12 1089ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic sw $fp, 8($sp) 1090ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic .cfi_rel_offset 30, 8 1091ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic sw $s1, 4($sp) 1092ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic .cfi_rel_offset 17, 4 1093ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic sw $s0, 0($sp) 1094ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic .cfi_rel_offset 16, 0 1095ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic move $fp, $sp # save sp in fp 1096ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic .cfi_def_cfa_register 30 1097ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic move $s1, $a3 # move managed thread pointer into s1 1098ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic addiu $s0, $zero, SUSPEND_CHECK_INTERVAL # reset s0 to suspend check interval 1099ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic addiu $t0, $a2, 4 # create space for ArtMethod* in frame. 1100ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic subu $t0, $sp, $t0 # reserve & align *stack* to 16 bytes: 1101ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic srl $t0, $t0, 4 # native calling convention only aligns to 8B, 1102ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic sll $sp, $t0, 4 # so we have to ensure ART 16B alignment ourselves. 1103ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic addiu $a0, $sp, 4 # pass stack pointer + ArtMethod* as dest for memcpy 1104590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, memcpy 1105590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 # (dest, src, bytes) 1106ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic addiu $sp, $sp, -16 # make space for argument slots for memcpy 1107ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic addiu $sp, $sp, 16 # restore stack after memcpy 1108590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic lw $gp, 16($fp) # restore $gp 1109590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic lw $a0, SPILL_SIZE($fp) # restore ArtMethod* 11101b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t8, $sp, 4 # t8 = pointer to the current argument (skip ArtMethod*) 11111b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze li $t6, 0 # t6 = gpr_index = 0 (corresponds to A1; A0 is skipped) 11121b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze li $t7, 0 # t7 = fp_index = 0 11131b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $t9, 20 + SPILL_SIZE($fp) # get shorty (20 is offset from the $sp on entry + SPILL_SIZE 1114590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic # as the $fp is SPILL_SIZE bytes below the $sp on entry) 11151b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t9, 1 # t9 = shorty + 1 (skip 1 for return type) 11161b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 11171b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze // Load the base addresses of tabIntS ... tabDoubleS. 11181b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze // We will use the register indices (gpr_index, fp_index) to branch. 11191b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze // Note that the indices are scaled by 16, so they can be added to the bases directly. 11201b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#if defined(__mips_isa_rev) && __mips_isa_rev >= 6 11211b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lapc $t2, tabIntS 11221b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lapc $t3, tabLongS 11231b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lapc $t4, tabSingleS 11241b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lapc $t5, tabDoubleS 11251b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#else 11261b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze bltzal $zero, tabBaseS # nal 11271b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t2, $ra, %lo(tabIntS - tabBaseS) 11281b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabBaseS: 11291b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t3, $ra, %lo(tabLongS - tabBaseS) 11301b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t4, $ra, %lo(tabSingleS - tabBaseS) 11311b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t5, $ra, %lo(tabDoubleS - tabBaseS) 11321b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#endif 11331b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 1134ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicloopS: 11351b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lbu $ra, 0($t9) # ra = shorty[i] 11361b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze beqz $ra, loopEndS # finish getting args when shorty[i] == '\0' 11371b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t9, 1 11381b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 11391b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $ra, -'J' 11401b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze beqz $ra, isLongS # branch if result type char == 'J' 11411b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $ra, 'J' - 'D' 11421b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze beqz $ra, isDoubleS # branch if result type char == 'D' 11431b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $ra, 'D' - 'F' 11441b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze beqz $ra, isSingleS # branch if result type char == 'F' 11451b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 11461b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addu $ra, $t2, $t6 11471b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze jalr $zero, $ra 11481b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t8, 4 # next_arg = curr_arg + 4 1149ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic 1150ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicisLongS: 11511b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addu $ra, $t3, $t6 11521b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze jalr $zero, $ra 11531b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t8, 8 # next_arg = curr_arg + 8 1154ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic 1155ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicisSingleS: 11561b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addu $ra, $t4, $t7 11571b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze jalr $zero, $ra 11581b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t8, 4 # next_arg = curr_arg + 4 11591b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 11601b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzeisDoubleS: 11611b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addu $ra, $t5, $t7 11621b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#if defined(__mips_isa_rev) && __mips_isa_rev > 2 11631b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t7, 16 # fp_index += 16 didn't fit into LOAD_DOUBLE_TO_REG 11641b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#endif 11651b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze jalr $zero, $ra 11661b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addiu $t8, 8 # next_arg = curr_arg + 8 1167ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic 1168ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicloopEndS: 1169ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic lw $t9, ART_METHOD_QUICK_CODE_OFFSET_32($a0) # get pointer to the code 1170ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic jalr $t9 # call the method 1171ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic sw $zero, 0($sp) # store null for ArtMethod* at bottom of frame 1172ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic move $sp, $fp # restore the stack 1173ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic lw $s0, 0($sp) 1174ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic .cfi_restore 16 1175ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic lw $s1, 4($sp) 1176ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic .cfi_restore 17 1177ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic lw $fp, 8($sp) 1178ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic .cfi_restore 30 1179ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic lw $ra, 12($sp) 1180ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic .cfi_restore 31 1181590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic addiu $sp, $sp, SPILL_SIZE 1182590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic .cfi_adjust_cfa_offset -SPILL_SIZE 1183ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic lw $t0, 16($sp) # get result pointer 1184ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic lw $t1, 20($sp) # get shorty 1185ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic lb $t1, 0($t1) # get result type char 1186ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic li $t2, 'D' # put char 'D' into t2 1187ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic beq $t1, $t2, 6f # branch if result type char == 'D' 1188ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic li $t3, 'F' # put char 'F' into t3 1189ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic beq $t1, $t3, 6f # branch if result type char == 'F' 1190ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic sw $v0, 0($t0) # store the result 1191ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic jalr $zero, $ra 1192ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic sw $v1, 4($t0) # store the other half of the result 1193ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic6: 1194ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic SDu $f0, $f1, 0, $t0, $t1 # store floating point result 1195ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic jalr $zero, $ra 1196ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic nop 11971b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 11981b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze // Note that gpr_index is kept within the range of tabIntS and tabLongS 11991b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze // and fp_index is kept within the range of tabSingleS and tabDoubleS. 12001b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze .balign 16 12011b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabIntS: 12021b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_WORD_TO_REG a1, t8, t6, loopS # a1 = current argument, gpr_index += 16 12031b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_WORD_TO_REG a2, t8, t6, loopS # a2 = current argument, gpr_index += 16 12041b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_WORD_TO_REG a3, t8, t6, loopS # a3 = current argument, gpr_index += 16 12051b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_WORD_TO_REG t0, t8, t6, loopS # t0 = current argument, gpr_index += 16 12061b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_WORD_TO_REG t1, t8, t6, loopS # t1 = current argument, gpr_index += 16 12071b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_END t6, 5*16, loopS # no more GPR args, gpr_index = 5*16 12081b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabLongS: 12091b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_LONG_TO_REG a2, a3, t8, t6, 3*16, loopS # a2_a3 = curr_arg, gpr_index = 3*16 12101b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_LONG_TO_REG a2, a3, t8, t6, 3*16, loopS # a2_a3 = curr_arg, gpr_index = 3*16 12111b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_LONG_TO_REG t0, t1, t8, t6, 5*16, loopS # t0_t1 = curr_arg, gpr_index = 5*16 12121b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_LONG_TO_REG t0, t1, t8, t6, 5*16, loopS # t0_t1 = curr_arg, gpr_index = 5*16 12131b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_END t6, 5*16, loopS # no more GPR args, gpr_index = 5*16 12141b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_END t6, 5*16, loopS # no more GPR args, gpr_index = 5*16 12151b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabSingleS: 12161b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_FLOAT_TO_REG f8, t8, t7, loopS # f8 = curr_arg, fp_index += 16 12171b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_FLOAT_TO_REG f10, t8, t7, loopS # f10 = curr_arg, fp_index += 16 12181b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_FLOAT_TO_REG f12, t8, t7, loopS # f12 = curr_arg, fp_index += 16 12191b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_FLOAT_TO_REG f14, t8, t7, loopS # f14 = curr_arg, fp_index += 16 12201b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_FLOAT_TO_REG f16, t8, t7, loopS # f16 = curr_arg, fp_index += 16 12211b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_FLOAT_TO_REG f18, t8, t7, loopS # f18 = curr_arg, fp_index += 16 12221b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_END t7, 6*16, loopS # no more FPR args, fp_index = 6*16 12231b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabDoubleS: 12241b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_DOUBLE_TO_REG f8, f9, t8, t7, ra, loopS # f8_f9 = curr_arg; if FPU32, fp_index += 16 12251b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_DOUBLE_TO_REG f10, f11, t8, t7, ra, loopS # f10_f11 = curr_arg; if FPU32, fp_index += 16 12261b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_DOUBLE_TO_REG f12, f13, t8, t7, ra, loopS # f12_f13 = curr_arg; if FPU32, fp_index += 16 12271b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_DOUBLE_TO_REG f14, f15, t8, t7, ra, loopS # f14_f15 = curr_arg; if FPU32, fp_index += 16 12281b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_DOUBLE_TO_REG f16, f17, t8, t7, ra, loopS # f16_f17 = curr_arg; if FPU32, fp_index += 16 12291b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_DOUBLE_TO_REG f18, f19, t8, t7, ra, loopS # f18_f19 = curr_arg; if FPU32, fp_index += 16 12301b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze LOAD_END t7, 6*16, loopS # no more FPR args, fp_index = 6*16 1231ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicEND art_quick_invoke_static_stub 1232ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic 1233590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic#undef SPILL_SIZE 1234590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic 1235ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic /* 12365bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Entry from managed code that calls artHandleFillArrayDataFromCode and delivers exception on 12375bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * failure. 12385bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 1239d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao .extern artHandleFillArrayDataFromCode 1240468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_handle_fill_data 1241fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko lw $a2, 0($sp) # pass referrer's Method* 1242fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_ONLY_FRAME # save callee saves in case exception allocation triggers GC 1243590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artHandleFillArrayDataFromCode 1244fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko jalr $t9 # (payload offset, Array*, method, Thread*) 1245fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko move $a3, rSELF # pass Thread::Current 1246fc6a30e2fa8f0d44e6c95bbeb5deca4b499f67cejeffhao RETURN_IF_ZERO 1247468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_handle_fill_data 12485bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 12495bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 125057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * Entry from managed code that calls artLockObjectFromCode, may block for GC. 12515bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 1252d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao .extern artLockObjectFromCode 1253468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_lock_object 1254804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko beqz $a0, art_quick_throw_null_pointer_exception 1255ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze li $t8, LOCK_WORD_THIN_LOCK_COUNT_ONE 1256ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze li $t3, LOCK_WORD_GC_STATE_MASK_SHIFTED_TOGGLED 1257ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze.Lretry_lock: 1258ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze lw $t0, THREAD_ID_OFFSET(rSELF) # TODO: Can the thread ID really change during the loop? 1259ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze ll $t1, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0) 1260ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze and $t2, $t1, $t3 # zero the gc bits 1261ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze bnez $t2, .Lnot_unlocked # already thin locked 1262ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze # Unlocked case - $t1: original lock word that's zero except for the read barrier bits. 1263ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze or $t2, $t1, $t0 # $t2 holds thread id with count of 0 with preserved read barrier bits 1264ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze sc $t2, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0) 1265ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze beqz $t2, .Lretry_lock # store failed, retry 1266a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers nop 1267ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze jalr $zero, $ra 1268ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze sync # full (LoadLoad|LoadStore) memory barrier 1269ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze.Lnot_unlocked: 1270ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze # $t1: original lock word, $t0: thread_id with count of 0 and zero read barrier bits 1271ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze srl $t2, $t1, LOCK_WORD_STATE_SHIFT 1272ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze bnez $t2, .Lslow_lock # if either of the top two bits are set, go slow path 1273ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze xor $t2, $t1, $t0 # lock_word.ThreadId() ^ self->ThreadId() 1274ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze andi $t2, $t2, 0xFFFF # zero top 16 bits 1275ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze bnez $t2, .Lslow_lock # lock word and self thread id's match -> recursive lock 1276ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze # otherwise contention, go to slow path 1277ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze and $t2, $t1, $t3 # zero the gc bits 1278ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze addu $t2, $t2, $t8 # increment count in lock word 1279ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze srl $t2, $t2, LOCK_WORD_STATE_SHIFT # if the first gc state bit is set, we overflowed. 1280ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze bnez $t2, .Lslow_lock # if we overflow the count go slow path 1281ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze addu $t2, $t1, $t8 # increment count for real 1282ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze sc $t2, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0) 1283ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze beqz $t2, .Lretry_lock # store failed, retry 1284ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze nop 1285ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze jalr $zero, $ra 1286ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze nop 1287ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze.Lslow_lock: 1288fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_ONLY_FRAME # save callee saves in case we block 1289590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artLockObjectFromCode 1290590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 # (Object* obj, Thread*) 12917fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao move $a1, rSELF # pass Thread::Current 12926bcd163d322b867578fbcfe60e4e3b247c42974bIan Rogers RETURN_IF_ZERO 1293468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_lock_object 12945bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 1295c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas GampeENTRY art_quick_lock_object_no_inline 1296804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko beqz $a0, art_quick_throw_null_pointer_exception 1297c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe nop 1298fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_ONLY_FRAME # save callee saves in case we block 1299c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe la $t9, artLockObjectFromCode 1300c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe jalr $t9 # (Object* obj, Thread*) 1301c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe move $a1, rSELF # pass Thread::Current 1302c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe RETURN_IF_ZERO 1303c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas GampeEND art_quick_lock_object_no_inline 1304c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe 13055bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 13065bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Entry from managed code that calls artUnlockObjectFromCode and delivers exception on failure. 13075bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 1308d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao .extern artUnlockObjectFromCode 1309468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_unlock_object 1310804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko beqz $a0, art_quick_throw_null_pointer_exception 1311ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze li $t8, LOCK_WORD_THIN_LOCK_COUNT_ONE 1312ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze li $t3, LOCK_WORD_GC_STATE_MASK_SHIFTED_TOGGLED 1313ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze.Lretry_unlock: 1314ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#ifndef USE_READ_BARRIER 1315ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze lw $t1, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0) 1316ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#else 1317ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze ll $t1, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0) # Need to use atomic read-modify-write for read barrier 1318ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#endif 1319ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze srl $t2, $t1, LOCK_WORD_STATE_SHIFT 1320ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze bnez $t2, .Lslow_unlock # if either of the top two bits are set, go slow path 1321ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze lw $t0, THREAD_ID_OFFSET(rSELF) 1322ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze and $t2, $t1, $t3 # zero the gc bits 1323ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze xor $t2, $t2, $t0 # lock_word.ThreadId() ^ self->ThreadId() 1324ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze andi $t2, $t2, 0xFFFF # zero top 16 bits 1325ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze bnez $t2, .Lslow_unlock # do lock word and self thread id's match? 1326ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze and $t2, $t1, $t3 # zero the gc bits 1327ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze bgeu $t2, $t8, .Lrecursive_thin_unlock 1328ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze # transition to unlocked 1329ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze nor $t2, $zero, $t3 # $t2 = LOCK_WORD_GC_STATE_MASK_SHIFTED 1330ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze and $t2, $t1, $t2 # $t2: zero except for the preserved gc bits 1331ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze sync # full (LoadStore|StoreStore) memory barrier 1332ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#ifndef USE_READ_BARRIER 1333ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze jalr $zero, $ra 1334ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze sw $t2, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0) 1335ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#else 1336ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze sc $t2, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0) 1337ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze beqz $t2, .Lretry_unlock # store failed, retry 1338a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers nop 1339ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze jalr $zero, $ra 1340ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze nop 1341ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#endif 1342ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze.Lrecursive_thin_unlock: 1343ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze # t1: original lock word 1344ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze subu $t2, $t1, $t8 # decrement count 1345ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#ifndef USE_READ_BARRIER 1346ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze jalr $zero, $ra 1347ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze sw $t2, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0) 1348ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#else 1349ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze sc $t2, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0) 1350ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze beqz $t2, .Lretry_unlock # store failed, retry 1351ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze nop 1352ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze jalr $zero, $ra 1353ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze nop 1354ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#endif 1355ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze.Lslow_unlock: 1356ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze SETUP_SAVE_REFS_ONLY_FRAME # save callee saves in case exception allocation triggers GC 1357590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artUnlockObjectFromCode 1358ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze jalr $t9 # (Object* obj, Thread*) 1359ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze move $a1, rSELF # pass Thread::Current 13605bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee RETURN_IF_ZERO 1361468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_unlock_object 13625bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 1363c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas GampeENTRY art_quick_unlock_object_no_inline 1364804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko beqz $a0, art_quick_throw_null_pointer_exception 1365c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe nop 1366fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_ONLY_FRAME # save callee saves in case exception allocation triggers GC 1367c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe la $t9, artUnlockObjectFromCode 1368c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe jalr $t9 # (Object* obj, Thread*) 1369c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe move $a1, rSELF # pass Thread::Current 1370c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe RETURN_IF_ZERO 1371c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas GampeEND art_quick_unlock_object_no_inline 1372c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe 13735bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 1374b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu Chartier * Entry from managed code that calls artInstanceOfFromCode and delivers exception on failure. 13755bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 1376b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu Chartier .extern artInstanceOfFromCode 1377b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu Chartier .extern artThrowClassCastExceptionForObject 1378b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu ChartierENTRY art_quick_check_instance_of 1379590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic addiu $sp, $sp, -32 1380590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic .cfi_adjust_cfa_offset 32 1381590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic sw $gp, 16($sp) 1382a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers sw $ra, 12($sp) 1383a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers .cfi_rel_offset 31, 12 1384a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers sw $t9, 8($sp) 1385a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers sw $a1, 4($sp) 1386a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers sw $a0, 0($sp) 1387b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu Chartier la $t9, artInstanceOfFromCode 1388590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 1389735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, -16 # reserve argument slots on the stack 1390735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, 16 1391590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic lw $gp, 16($sp) 139286bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers beqz $v0, .Lthrow_class_cast_exception 1393a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers lw $ra, 12($sp) 13948d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $ra 1395590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic addiu $sp, $sp, 32 1396590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic .cfi_adjust_cfa_offset -32 139786bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers.Lthrow_class_cast_exception: 1398a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers lw $t9, 8($sp) 1399a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers lw $a1, 4($sp) 1400a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers lw $a0, 0($sp) 1401590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic addiu $sp, $sp, 32 1402590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic .cfi_adjust_cfa_offset -32 1403fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_ALL_CALLEE_SAVES_FRAME 1404b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu Chartier la $t9, artThrowClassCastExceptionForObject 1405b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu Chartier jalr $zero, $t9 # artThrowClassCastException (Object*, Class*, Thread*) 14061d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers move $a2, rSELF # pass Thread::Current 1407b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu ChartierEND art_quick_check_instance_of 14085bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 14095bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 14101aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao * Restore rReg's value from offset($sp) if rReg is not the same as rExclude. 14111aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao * nReg is the register number for rReg. 14121aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao */ 14131aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao.macro POP_REG_NE rReg, nReg, offset, rExclude 14141aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .ifnc \rReg, \rExclude 14151aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao lw \rReg, \offset($sp) # restore rReg 14161aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_restore \nReg 14171aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .endif 14181aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao.endm 14191aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao 14201aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao /* 14211aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao * Macro to insert read barrier, only used in art_quick_aput_obj. 14221aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao * rObj and rDest are registers, offset is a defined literal such as MIRROR_OBJECT_CLASS_OFFSET. 14231aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao * TODO: When read barrier has a fast path, add heap unpoisoning support for the fast path. 14241aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao */ 14251aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao.macro READ_BARRIER rDest, rObj, offset 14261aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#ifdef USE_READ_BARRIER 14271aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao # saved registers used in art_quick_aput_obj: a0-a2, t0-t1, t9, ra. 8 words for 16B alignment. 14281aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao addiu $sp, $sp, -32 14291aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_adjust_cfa_offset 32 14301aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao sw $ra, 28($sp) 14311aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_rel_offset 31, 28 14321aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao sw $t9, 24($sp) 14331aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_rel_offset 25, 24 14341aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao sw $t1, 20($sp) 14351aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_rel_offset 9, 20 14361aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao sw $t0, 16($sp) 14371aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_rel_offset 8, 16 14381aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao sw $a2, 8($sp) # padding slot at offset 12 (padding can be any slot in the 32B) 14391aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_rel_offset 6, 8 14401aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao sw $a1, 4($sp) 14411aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_rel_offset 5, 4 14421aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao sw $a0, 0($sp) 14431aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_rel_offset 4, 0 14441aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao 14456306921722283d2b0f8aac01883ad83215d6e864Man Cao # move $a0, \rRef # pass ref in a0 (no-op for now since parameter ref is unused) 14461aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .ifnc \rObj, $a1 14471aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao move $a1, \rObj # pass rObj 14481aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .endif 1449590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic addiu $a2, $zero, \offset # pass offset 1450590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artReadBarrierSlow 1451590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 # artReadBarrierSlow(ref, rObj, offset) 14521aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao addiu $sp, $sp, -16 # Use branch delay slot to reserve argument slots on the stack 14531aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao # before the call to artReadBarrierSlow. 14541aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao addiu $sp, $sp, 16 # restore stack after call to artReadBarrierSlow 14551aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao # No need to unpoison return value in v0, artReadBarrierSlow() would do the unpoisoning. 14561aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao move \rDest, $v0 # save return value in rDest 14571aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao # (rDest cannot be v0 in art_quick_aput_obj) 14581aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao 14591aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao lw $a0, 0($sp) # restore registers except rDest 14601aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao # (rDest can only be t0 or t1 in art_quick_aput_obj) 14611aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_restore 4 14621aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao lw $a1, 4($sp) 14631aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_restore 5 14641aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao lw $a2, 8($sp) 14651aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_restore 6 14661aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao POP_REG_NE $t0, 8, 16, \rDest 14671aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao POP_REG_NE $t1, 9, 20, \rDest 14681aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao lw $t9, 24($sp) 14691aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_restore 25 14701aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao lw $ra, 28($sp) # restore $ra 14711aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_restore 31 14721aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao addiu $sp, $sp, 32 14731aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .cfi_adjust_cfa_offset -32 14741aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#else 14751aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao lw \rDest, \offset(\rObj) 14761aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao UNPOISON_HEAP_REF \rDest 14771aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#endif // USE_READ_BARRIER 14781aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao.endm 14791aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao 14801aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#ifdef USE_READ_BARRIER 14811aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .extern artReadBarrierSlow 14821aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#endif 1483a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersENTRY art_quick_aput_obj 148486bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers beqz $a2, .Ldo_aput_null 1485a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers nop 14861aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao READ_BARRIER $t0, $a0, MIRROR_OBJECT_CLASS_OFFSET 14871aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao READ_BARRIER $t1, $a2, MIRROR_OBJECT_CLASS_OFFSET 14881aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao READ_BARRIER $t0, $t0, MIRROR_CLASS_COMPONENT_TYPE_OFFSET 148986bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers bne $t1, $t0, .Lcheck_assignability # value's type == array's component type - trivial assignability 1490a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers nop 149186bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers.Ldo_aput: 1492a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers sll $a1, $a1, 2 1493a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers add $t0, $a0, $a1 1494bfa5eb6e8d15ea73a36f8df449630f285a91e995Hiroshi Yamauchi POISON_HEAP_REF $a2 14951d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers sw $a2, MIRROR_OBJECT_ARRAY_DATA_OFFSET($t0) 1496a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers lw $t0, THREAD_CARD_TABLE_OFFSET(rSELF) 1497afdcbcb56d0c2f985d0291c369bbc493eedb05b0Mathieu Chartier srl $t1, $a0, CARD_TABLE_CARD_SHIFT 1498a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers add $t1, $t1, $t0 1499a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers sb $t0, ($t1) 15008d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $ra 1501a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers nop 150286bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers.Ldo_aput_null: 1503a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers sll $a1, $a1, 2 1504a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers add $t0, $a0, $a1 15051d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers sw $a2, MIRROR_OBJECT_ARRAY_DATA_OFFSET($t0) 15068d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $ra 1507a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers nop 150886bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers.Lcheck_assignability: 1509a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers addiu $sp, $sp, -32 1510a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers .cfi_adjust_cfa_offset 32 1511a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers sw $ra, 28($sp) 1512a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers .cfi_rel_offset 31, 28 1513590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic sw $gp, 16($sp) 1514a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers sw $t9, 12($sp) 1515a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers sw $a2, 8($sp) 1516a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers sw $a1, 4($sp) 1517a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers sw $a0, 0($sp) 1518a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers move $a1, $t1 1519a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers move $a0, $t0 1520590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artIsAssignableFromCode 1521590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 # (Class*, Class*) 1522590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic addiu $sp, $sp, -16 # reserve argument slots on the stack 1523590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic addiu $sp, $sp, 16 1524a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers lw $ra, 28($sp) 1525590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic lw $gp, 16($sp) 1526a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers lw $t9, 12($sp) 1527a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers lw $a2, 8($sp) 1528a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers lw $a1, 4($sp) 1529a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers lw $a0, 0($sp) 1530e34652f15f32666323052a6718a63248244f1e66Duane Sand addiu $sp, 32 1531a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers .cfi_adjust_cfa_offset -32 153286bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers bnez $v0, .Ldo_aput 1533a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers nop 1534fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_ALL_CALLEE_SAVES_FRAME 1535a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers move $a1, $a2 1536a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers la $t9, artThrowArrayStoreException 15378d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $t9 # artThrowArrayStoreException(Class*, Class*, Thread*) 15381d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers move $a2, rSELF # pass Thread::Current 1539a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersEND art_quick_aput_obj 15405bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 15410cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze// Macros taking opportunity of code similarities for downcalls. 15420cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.macro ONE_ARG_REF_DOWNCALL name, entrypoint, return 15430cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze .extern \entrypoint 15440cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeENTRY \name 15450cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze SETUP_SAVE_REFS_ONLY_FRAME # save callee saves in case of GC 15460cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze la $t9, \entrypoint 15470cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze jalr $t9 # (field_idx, Thread*) 15480cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze move $a1, rSELF # pass Thread::Current 15490cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze \return # RETURN_IF_NO_EXCEPTION or RETURN_IF_ZERO 15500cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeEND \name 15510cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.endm 155237f05ef45e0393de812d51261dc293240c17294dFred Shih 15530cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.macro TWO_ARG_REF_DOWNCALL name, entrypoint, return 15540cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze .extern \entrypoint 15550cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeENTRY \name 15560cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze SETUP_SAVE_REFS_ONLY_FRAME # save callee saves in case of GC 15570cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze la $t9, \entrypoint 15580cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze jalr $t9 # (field_idx, Object*, Thread*) or 15590cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze # (field_idx, new_val, Thread*) 15600cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze move $a2, rSELF # pass Thread::Current 15610cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze \return # RETURN_IF_NO_EXCEPTION or RETURN_IF_ZERO 15620cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeEND \name 15630cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.endm 156437f05ef45e0393de812d51261dc293240c17294dFred Shih 15650cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.macro THREE_ARG_REF_DOWNCALL name, entrypoint, return 15660cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze .extern \entrypoint 15670cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeENTRY \name 15680cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze SETUP_SAVE_REFS_ONLY_FRAME # save callee saves in case of GC 15690cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze la $t9, \entrypoint 15700cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze jalr $t9 # (field_idx, Object*, new_val, Thread*) 15710cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze move $a3, rSELF # pass Thread::Current 15720cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze \return # RETURN_IF_NO_EXCEPTION or RETURN_IF_ZERO 15730cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeEND \name 15740cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.endm 15755bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 15760cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.macro FOUR_ARG_REF_DOWNCALL name, entrypoint, return 15770cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze .extern \entrypoint 15780cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeENTRY \name 15790cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze SETUP_SAVE_REFS_ONLY_FRAME # save callee saves in case of GC 15800cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze la $t9, \entrypoint 15810cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze jalr $t9 # (field_idx, Object*, 64-bit new_val, Thread*) or 15820cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze # (field_idx, 64-bit new_val, Thread*) 15830cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze # Note that a 64-bit new_val needs to be aligned with 15840cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze # an even-numbered register, hence A1 may be skipped 15850cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze # for new_val to reside in A2-A3. 15860cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze sw rSELF, 16($sp) # pass Thread::Current 15870cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze \return # RETURN_IF_NO_EXCEPTION or RETURN_IF_ZERO 15880cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeEND \name 15890cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.endm 15905bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 15915bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 15920cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze * Called by managed code to resolve a static/instance field and load/store a value. 15935bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 15940cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCompiledCode, RETURN_IF_NO_EXCEPTION 15950cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCompiledCode, RETURN_IF_NO_EXCEPTION 15960cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCompiledCode, RETURN_IF_NO_EXCEPTION 15970cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCompiledCode, RETURN_IF_NO_EXCEPTION 15980cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCompiledCode, RETURN_IF_NO_EXCEPTION 15990cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCompiledCode, RETURN_IF_NO_EXCEPTION 16000cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCompiledCode, RETURN_IF_NO_EXCEPTION 16010cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION 16020cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION 16030cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION 16040cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION 16050cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION 16060cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION 16070cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION 16080cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCompiledCode, RETURN_IF_ZERO 16090cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCompiledCode, RETURN_IF_ZERO 16100cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCompiledCode, RETURN_IF_ZERO 16110cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCompiledCode, RETURN_IF_ZERO 16120cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeFOUR_ARG_REF_DOWNCALL art_quick_set64_static, artSet64StaticFromCompiledCode, RETURN_IF_ZERO 16130cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTHREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCompiledCode, RETURN_IF_ZERO 16140cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTHREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCompiledCode, RETURN_IF_ZERO 16150cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTHREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCompiledCode, RETURN_IF_ZERO 16160cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTHREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCompiledCode, RETURN_IF_ZERO 16170cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeFOUR_ARG_REF_DOWNCALL art_quick_set64_instance, artSet64InstanceFromCompiledCode, RETURN_IF_ZERO 16185bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 1619a3c382738bc54f464a57e2b51b51ad305eb03dd2Vladimir Marko// Macro to facilitate adding new allocation entrypoints. 16205ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko.macro ONE_ARG_DOWNCALL name, entrypoint, return 16215ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko .extern \entrypoint 16225ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir MarkoENTRY \name 1623fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_ONLY_FRAME # save callee saves in case of GC 1624590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, \entrypoint 1625590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 16265ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko move $a1, rSELF # pass Thread::Current 16275ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko \return 16285ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir MarkoEND \name 16295ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko.endm 16305ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko 1631cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier.macro TWO_ARG_DOWNCALL name, entrypoint, return 1632cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier .extern \entrypoint 1633cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu ChartierENTRY \name 1634fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_ONLY_FRAME # save callee saves in case of GC 1635590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, \entrypoint 1636590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 16371d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers move $a2, rSELF # pass Thread::Current 1638cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier \return 1639cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu ChartierEND \name 1640cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier.endm 16415bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 1642cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier.macro THREE_ARG_DOWNCALL name, entrypoint, return 1643cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier .extern \entrypoint 1644cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu ChartierENTRY \name 1645fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_ONLY_FRAME # save callee saves in case of GC 1646590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, \entrypoint 1647590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 16481d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers move $a3, rSELF # pass Thread::Current 1649cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier \return 1650cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu ChartierEND \name 1651cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier.endm 16525bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 1653848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao.macro FOUR_ARG_DOWNCALL name, entrypoint, return 1654848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao .extern \entrypoint 1655848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff HaoENTRY \name 1656fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_ONLY_FRAME # save callee saves in case of GC 1657590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, \entrypoint 1658590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 1659a3c382738bc54f464a57e2b51b51ad305eb03dd2Vladimir Marko sw rSELF, 16($sp) # pass Thread::Current 1660848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao \return 1661848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff HaoEND \name 1662848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao.endm 1663848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 16647410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier// Generate the allocation entrypoints for each allocator. 1665854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_FOR_NON_TLAB_ALLOCATORS 1666854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// Comment out allocators that have mips specific asm. 1667854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB) 1668854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab, RegionTLAB) 1669854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB) 1670854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB) 1671854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region_tlab, RegionTLAB) 1672854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region_tlab, RegionTLAB) 1673854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED32(_region_tlab, RegionTLAB) 1674854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED64(_region_tlab, RegionTLAB) 1675854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_BYTES(_region_tlab, RegionTLAB) 1676854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_CHARS(_region_tlab, RegionTLAB) 1677854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_STRING(_region_tlab, RegionTLAB) 1678854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1679854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB) 1680854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB) 1681854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB) 1682854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB) 1683854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_tlab, TLAB) 1684854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_tlab, TLAB) 1685854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED32(_tlab, TLAB) 1686854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED64(_tlab, TLAB) 1687854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_BYTES(_tlab, TLAB) 1688854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_CHARS(_tlab, TLAB) 1689854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_STRING(_tlab, TLAB) 169010d4c08c0ea9df0a85a11e1c77974df24078c0ecHiroshi Yamauchi 16912449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic// A hand-written override for: 16922449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_rosalloc, RosAlloc) 16932449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_rosalloc, RosAlloc) 1694854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro ART_QUICK_ALLOC_OBJECT_ROSALLOC c_name, cxx_name, isInitialized 1695854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicENTRY_NO_GP \c_name 16962449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # Fast path rosalloc allocation 16972449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # a0: type 16982449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # s1: Thread::Current 16992449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # ----------------------------- 17002449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # t1: object size 17012449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # t2: rosalloc run 17022449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # t3: thread stack top offset 17032449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # t4: thread stack bottom offset 17042449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # v0: free list head 17052449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # 17062449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # t5, t6 : temps 17072449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic lw $t3, THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET($s1) # Check if thread local allocation 17082449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic lw $t4, THREAD_LOCAL_ALLOC_STACK_END_OFFSET($s1) # stack has any room left. 17092449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic bgeu $t3, $t4, .Lslow_path_\c_name 17102449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic 17112449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic lw $t1, MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET($a0) # Load object size (t1). 17122449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic li $t5, ROSALLOC_MAX_THREAD_LOCAL_BRACKET_SIZE # Check if size is for a thread local 17132449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # allocation. Also does the 17142449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # initialized and finalizable checks. 1715854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # When isInitialized == 0, then the class is potentially not yet initialized. 1716854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # If the class is not yet initialized, the object size will be very large to force the branch 1717854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # below to be taken. 1718854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # 1719854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # See InitializeClassVisitors in class-inl.h for more details. 17202449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic bgtu $t1, $t5, .Lslow_path_\c_name 17212449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic 17222449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # Compute the rosalloc bracket index from the size. Since the size is already aligned we can 17232449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # combine the two shifts together. 17242449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic srl $t1, $t1, (ROSALLOC_BRACKET_QUANTUM_SIZE_SHIFT - POINTER_SIZE_SHIFT) 17252449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic 17262449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic addu $t2, $t1, $s1 17272449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic lw $t2, (THREAD_ROSALLOC_RUNS_OFFSET - __SIZEOF_POINTER__)($t2) # Load rosalloc run (t2). 17282449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic 17292449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # Load the free list head (v0). 17302449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # NOTE: this will be the return val. 17312449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic lw $v0, (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_HEAD_OFFSET)($t2) 17322449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic beqz $v0, .Lslow_path_\c_name 17332449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic nop 17342449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic 17352449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # Load the next pointer of the head and update the list head with the next pointer. 17362449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic lw $t5, ROSALLOC_SLOT_NEXT_OFFSET($v0) 17372449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic sw $t5, (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_HEAD_OFFSET)($t2) 17382449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic 17392449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # Store the class pointer in the header. This also overwrites the first pointer. The offsets are 17402449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # asserted to match. 17412449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic 17422449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic#if ROSALLOC_SLOT_NEXT_OFFSET != MIRROR_OBJECT_CLASS_OFFSET 17432449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic#error "Class pointer needs to overwrite next pointer." 17442449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic#endif 17452449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic 17462449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic POISON_HEAP_REF $a0 17472449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic sw $a0, MIRROR_OBJECT_CLASS_OFFSET($v0) 17482449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic 17492449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # Push the new object onto the thread local allocation stack and increment the thread local 17502449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # allocation stack top. 17512449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic sw $v0, 0($t3) 17522449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic addiu $t3, $t3, COMPRESSED_REFERENCE_SIZE 17532449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic sw $t3, THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET($s1) 17542449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic 17552449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic # Decrement the size of the free list. 17562449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic lw $t5, (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_SIZE_OFFSET)($t2) 17572449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic addiu $t5, $t5, -1 17582449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic sw $t5, (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_SIZE_OFFSET)($t2) 17592449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic 1760854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.if \isInitialized == 0 1761854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # This barrier is only necessary when the allocation also requires a class initialization check. 1762854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # 1763854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # If the class is already observably initialized, then new-instance allocations are protected 1764854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # from publishing by the compiler which inserts its own StoreStore barrier. 17652449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic sync # Fence. 1766854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endif 17672449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic jalr $zero, $ra 17682449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic nop 17692449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic 17702449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic .Lslow_path_\c_name: 1771854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addiu $t9, $t9, (.Lslow_path_\c_name - \c_name) + 4 1772854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic .cpload $t9 17732449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic SETUP_SAVE_REFS_ONLY_FRAME 17742449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic la $t9, \cxx_name 17752449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic jalr $t9 17762449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic move $a1, $s1 # Pass self as argument. 17772449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER 17782449e5c95b536791fc11344530365b36ae18e0dfGoran JakovljevicEND \c_name 17792449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic.endm 17802449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic 1781854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicART_QUICK_ALLOC_OBJECT_ROSALLOC art_quick_alloc_object_resolved_rosalloc, artAllocObjectFromCodeResolvedRosAlloc, /* isInitialized */ 0 1782854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicART_QUICK_ALLOC_OBJECT_ROSALLOC art_quick_alloc_object_initialized_rosalloc, artAllocObjectFromCodeInitializedRosAlloc, /* isInitialized */ 1 1783854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1784854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// The common fast path code for art_quick_alloc_object_resolved/initialized_tlab 1785854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// and art_quick_alloc_object_resolved/initialized_region_tlab. 1786854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// 1787854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// a0: type, s1(rSELF): Thread::Current. 1788854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// Need to preserve a0 to the slow path. 1789854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// 1790854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// If isInitialized=1 then the compiler assumes the object's class has already been initialized. 1791854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// If isInitialized=0 the compiler can only assume it's been at least resolved. 1792854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro ALLOC_OBJECT_RESOLVED_TLAB_FAST_PATH slowPathLabel isInitialized 1793854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic lw $v0, THREAD_LOCAL_POS_OFFSET(rSELF) # Load thread_local_pos. 1794854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic lw $a2, THREAD_LOCAL_END_OFFSET(rSELF) # Load thread_local_end. 1795854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic subu $a3, $a2, $v0 # Compute the remaining buffer size. 1796854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic lw $t0, MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET($a0) # Load the object size. 1797854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1798854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # When isInitialized == 0, then the class is potentially not yet initialized. 1799854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # If the class is not yet initialized, the object size will be very large to force the branch 1800854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # below to be taken. 1801854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # 1802854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # See InitializeClassVisitors in class-inl.h for more details. 1803854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic bgtu $t0, $a3, \slowPathLabel # Check if it fits. 1804854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addu $t1, $v0, $t0 # Add object size to tlab pos (in branch 1805854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # delay slot). 1806854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # "Point of no slow path". Won't go to the slow path from here on. 1807854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic sw $t1, THREAD_LOCAL_POS_OFFSET(rSELF) # Store new thread_local_pos. 1808854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic lw $a2, THREAD_LOCAL_OBJECTS_OFFSET(rSELF) # Increment thread_local_objects. 1809854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addiu $a2, $a2, 1 1810854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic sw $a2, THREAD_LOCAL_OBJECTS_OFFSET(rSELF) 1811854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic POISON_HEAP_REF $a0 1812854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic sw $a0, MIRROR_OBJECT_CLASS_OFFSET($v0) # Store the class pointer. 1813854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1814854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.if \isInitialized == 0 1815854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # This barrier is only necessary when the allocation also requires a class initialization check. 1816854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # 1817854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # If the class is already observably initialized, then new-instance allocations are protected 1818854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # from publishing by the compiler which inserts its own StoreStore barrier. 1819854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic sync # Fence. 1820854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endif 1821854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic jalr $zero, $ra 1822854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic nop 1823854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm 1824854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1825854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// The common code for art_quick_alloc_object_resolved/initialized_tlab 1826854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// and art_quick_alloc_object_resolved/initialized_region_tlab. 1827854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro GENERATE_ALLOC_OBJECT_TLAB name, entrypoint, isInitialized 1828854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicENTRY_NO_GP \name 1829854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Fast path tlab allocation. 1830854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # a0: type, s1(rSELF): Thread::Current. 1831854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic ALLOC_OBJECT_RESOLVED_TLAB_FAST_PATH .Lslow_path_\name, \isInitialized 1832854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.Lslow_path_\name: 1833854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addiu $t9, $t9, (.Lslow_path_\name - \name) + 4 1834854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic .cpload $t9 1835854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic SETUP_SAVE_REFS_ONLY_FRAME # Save callee saves in case of GC. 1836854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic la $t9, \entrypoint 1837854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic jalr $t9 # (mirror::Class*, Thread*) 1838854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic move $a1, rSELF # Pass Thread::Current. 1839854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER 1840854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicEND \name 1841854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm 1842854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1843854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_OBJECT_TLAB art_quick_alloc_object_resolved_region_tlab, artAllocObjectFromCodeResolvedRegionTLAB, /* isInitialized */ 0 1844854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_OBJECT_TLAB art_quick_alloc_object_initialized_region_tlab, artAllocObjectFromCodeInitializedRegionTLAB, /* isInitialized */ 1 1845854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_OBJECT_TLAB art_quick_alloc_object_resolved_tlab, artAllocObjectFromCodeResolvedTLAB, /* isInitialized */ 0 1846854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_OBJECT_TLAB art_quick_alloc_object_initialized_tlab, artAllocObjectFromCodeInitializedTLAB, /* isInitialized */ 1 1847854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1848854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// The common fast path code for art_quick_alloc_array_resolved/initialized_tlab 1849854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// and art_quick_alloc_array_resolved/initialized_region_tlab. 1850854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// 1851854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// a0: type, a1: component_count, a2: total_size, s1(rSELF): Thread::Current. 1852854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// Need to preserve a0 and a1 to the slow path. 1853854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED_WITH_SIZE slowPathLabel 1854854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic li $a3, OBJECT_ALIGNMENT_MASK_TOGGLED # Apply alignemnt mask 1855854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic and $a2, $a2, $a3 # (addr + 7) & ~7. 1856854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1857854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic lw $v0, THREAD_LOCAL_POS_OFFSET(rSELF) # Load thread_local_pos. 1858854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic lw $t1, THREAD_LOCAL_END_OFFSET(rSELF) # Load thread_local_end. 1859854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic subu $t2, $t1, $v0 # Compute the remaining buffer size. 1860854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic bgtu $a2, $t2, \slowPathLabel # Check if it fits. 1861854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addu $a2, $v0, $a2 # Add object size to tlab pos (in branch 1862854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # delay slot). 1863854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1864854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # "Point of no slow path". Won't go to the slow path from here on. 1865854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic sw $a2, THREAD_LOCAL_POS_OFFSET(rSELF) # Store new thread_local_pos. 1866854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic lw $a2, THREAD_LOCAL_OBJECTS_OFFSET(rSELF) # Increment thread_local_objects. 1867854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addiu $a2, $a2, 1 1868854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic sw $a2, THREAD_LOCAL_OBJECTS_OFFSET(rSELF) 1869854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic POISON_HEAP_REF $a0 1870854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic sw $a0, MIRROR_OBJECT_CLASS_OFFSET($v0) # Store the class pointer. 1871854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic jalr $zero, $ra 1872854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic sw $a1, MIRROR_ARRAY_LENGTH_OFFSET($v0) # Store the array length. 1873854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm 1874854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1875854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro GENERATE_ALLOC_ARRAY_TLAB name, entrypoint, size_setup 1876854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicENTRY_NO_GP \name 1877854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Fast path array allocation for region tlab allocation. 1878854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # a0: mirror::Class* type 1879854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # a1: int32_t component_count 1880854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # s1(rSELF): Thread::Current 1881854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic \size_setup .Lslow_path_\name 1882854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED_WITH_SIZE .Lslow_path_\name 1883854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.Lslow_path_\name: 1884854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # a0: mirror::Class* type 1885854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # a1: int32_t component_count 1886854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # a2: Thread* self 1887854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addiu $t9, $t9, (.Lslow_path_\name - \name) + 4 1888854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic .cpload $t9 1889854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic SETUP_SAVE_REFS_ONLY_FRAME # Save callee saves in case of GC. 1890854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic la $t9, \entrypoint 1891854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic jalr $t9 1892854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic move $a2, rSELF # Pass Thread::Current. 1893854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER 1894854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicEND \name 1895854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm 1896854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1897854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro COMPUTE_ARRAY_SIZE_UNKNOWN slow_path 1898854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic break # We should never enter here. 1899854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Code below is for reference. 1900854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Possibly a large object, go slow. 1901854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Also does negative array size check. 1902854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic li $a2, ((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_WIDE_ARRAY_DATA_OFFSET) / 8) 1903854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic bgtu $a1, $a2, \slow_path 1904854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Array classes are never finalizable 1905854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # or uninitialized, no need to check. 1906854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic lw $a3, MIRROR_CLASS_COMPONENT_TYPE_OFFSET($a0) # Load component type. 1907854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic UNPOISON_HEAP_REF $a3 1908854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic lw $a3, MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET($a3) 1909854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic srl $a3, $a3, PRIMITIVE_TYPE_SIZE_SHIFT_SHIFT # Component size shift is in high 16 bits. 1910854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic sllv $a2, $a1, $a3 # Calculate data size. 1911854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Add array data offset and alignment. 1912854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addiu $a2, $a2, (MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK) 1913854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic#if MIRROR_WIDE_ARRAY_DATA_OFFSET != MIRROR_INT_ARRAY_DATA_OFFSET + 4 1914854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic#error Long array data offset must be 4 greater than int array data offset. 1915854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic#endif 1916854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1917854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addiu $a3, $a3, 1 # Add 4 to the length only if the component 1918854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic andi $a3, $a3, 4 # size shift is 3 (for 64 bit alignment). 1919854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addu $a2, $a2, $a3 1920854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm 1921854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1922854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro COMPUTE_ARRAY_SIZE_8 slow_path 1923854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Possibly a large object, go slow. 1924854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Also does negative array size check. 1925854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic li $a2, (MIN_LARGE_OBJECT_THRESHOLD - MIRROR_INT_ARRAY_DATA_OFFSET) 1926854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic bgtu $a1, $a2, \slow_path 1927854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Add array data offset and alignment (in branch delay slot). 1928854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addiu $a2, $a1, (MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK) 1929854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm 1930854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1931854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro COMPUTE_ARRAY_SIZE_16 slow_path 1932854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Possibly a large object, go slow. 1933854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Also does negative array size check. 1934854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic li $a2, ((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_INT_ARRAY_DATA_OFFSET) / 2) 1935854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic bgtu $a1, $a2, \slow_path 1936854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic sll $a2, $a1, 1 1937854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Add array data offset and alignment. 1938854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addiu $a2, $a2, (MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK) 1939854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm 1940854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1941854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro COMPUTE_ARRAY_SIZE_32 slow_path 1942854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Possibly a large object, go slow. 1943854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Also does negative array size check. 1944854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic li $a2, ((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_INT_ARRAY_DATA_OFFSET) / 4) 1945854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic bgtu $a1, $a2, \slow_path 1946854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic sll $a2, $a1, 2 1947854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Add array data offset and alignment. 1948854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addiu $a2, $a2, (MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK) 1949854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm 1950854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1951854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro COMPUTE_ARRAY_SIZE_64 slow_path 1952854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Possibly a large object, go slow. 1953854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Also does negative array size check. 1954854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic li $a2, ((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_LONG_ARRAY_DATA_OFFSET) / 8) 1955854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic bgtu $a1, $a2, \slow_path 1956854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic sll $a2, $a1, 3 1957854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic # Add array data offset and alignment. 1958854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic addiu $a2, $a2, (MIRROR_WIDE_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK) 1959854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm 19603b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi 1961854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_UNKNOWN 1962854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved8_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_8 1963854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved16_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_16 1964854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved32_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_32 1965854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved64_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_64 1966854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic 1967854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_UNKNOWN 1968854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved8_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_8 1969854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved16_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_16 1970854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved32_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_32 1971854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved64_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_64 197210d4c08c0ea9df0a85a11e1c77974df24078c0ecHiroshi Yamauchi 1973c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze// Macro for string and type resolution and initialization. 1974c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze// $a0 is both input and output. 1975c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL name, entrypoint 1976c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze .extern \entrypoint 1977c61c0761150340263160b568d8a952e9a3d80d56Alexey FrunzeENTRY_NO_GP \name 1978c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze SETUP_SAVE_EVERYTHING_FRAME # Save everything in case of GC. 1979c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze move $s2, $gp # Preserve $gp across the call for exception delivery. 1980c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze la $t9, \entrypoint 1981c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze jalr $t9 # (uint32_t index, Thread*) 1982c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze move $a1, rSELF # Pass Thread::Current (in delay slot). 1983c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze beqz $v0, 1f # Success? 1984c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze move $a0, $v0 # Move result to $a0 (in delay slot). 1985c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze RESTORE_SAVE_EVERYTHING_FRAME 0 # Restore everything except $a0. 1986c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze jalr $zero, $ra # Return on success. 1987c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze nop 1988c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze1: 1989c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze move $gp, $s2 1990c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze DELIVER_PENDING_EXCEPTION_FRAME_READY 1991c61c0761150340263160b568d8a952e9a3d80d56Alexey FrunzeEND \name 1992c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze.endm 1993c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze 19945bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 19951cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe * Entry from managed code to resolve a string, this stub will allocate a String and deliver an 19965ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko * exception on error. On success the String is returned. A0 holds the string index. The fast 19975ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko * path check for hit in strings cache has already been performed. 19981cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe */ 1999c61c0761150340263160b568d8a952e9a3d80d56Alexey FrunzeONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode 20001cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe 20011cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe /* 20021cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe * Entry from managed code when uninitialized static storage, this stub will run the class 20031cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe * initializer and deliver the exception on error. On success the static storage base is 20041cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe * returned. 20051cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe */ 2006c61c0761150340263160b568d8a952e9a3d80d56Alexey FrunzeONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode 20071cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe 20081cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe /* 20091cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe * Entry from managed code when dex cache misses for a type_idx. 20101cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe */ 2011c61c0761150340263160b568d8a952e9a3d80d56Alexey FrunzeONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode 20121cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe 20131cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe /* 20141cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe * Entry from managed code when type_idx needs to be checked for access and dex cache may also 20151cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe * miss. 20161cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe */ 2017c61c0761150340263160b568d8a952e9a3d80d56Alexey FrunzeONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode 20181cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe 20191cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe /* 202057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * Called by managed code when the value in rSUSPEND has been decremented to 0. 20215bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 2022d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao .extern artTestSuspendFromCode 2023952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir MarkoENTRY_NO_GP art_quick_test_suspend 2024952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko lh rSUSPEND, THREAD_FLAGS_OFFSET(rSELF) 2025952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko bnez rSUSPEND, 1f 2026e34652f15f32666323052a6718a63248244f1e66Duane Sand addiu rSUSPEND, $zero, SUSPEND_CHECK_INTERVAL # reset rSUSPEND to SUSPEND_CHECK_INTERVAL 20278d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $ra 20285bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee nop 20295bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee1: 2030fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_EVERYTHING_FRAME # save everything for stack crawl 2031590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artTestSuspendFromCode 2032952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko jalr $t9 # (Thread*) 20337fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao move $a0, rSELF 2034fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko RESTORE_SAVE_EVERYTHING_FRAME 2035952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko jalr $zero, $ra 2036952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko nop 2037d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_test_suspend 20385bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 20395bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 20405bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Called by managed code that is attempting to call a method on a proxy class. On entry 2041590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic * a0 holds the proxy method; a1, a2 and a3 may contain arguments. 20425bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 20435fa60c3db4208df407113b5a69d295a9c93d53b1Jeff Hao .extern artQuickProxyInvokeHandler 2044d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoENTRY art_quick_proxy_invoke_handler 2045fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_A0 2046735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung move $a2, rSELF # pass Thread::Current 2047590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artQuickProxyInvokeHandler 2048590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 # (Method* proxy method, receiver, Thread*, SP) 2049735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $a3, $sp, ARG_SLOT_SIZE # pass $sp (remove arg slots) 20501b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $t7, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_ 2051fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko RESTORE_SAVE_REFS_AND_ARGS_FRAME 20521b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze bnez $t7, 1f 2053e34652f15f32666323052a6718a63248244f1e66Duane Sand # don't care if $v0 and/or $v1 are modified, when exception branch taken 2054e34652f15f32666323052a6718a63248244f1e66Duane Sand MTD $v0, $v1, $f0, $f1 # move float value to return value 20558d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $ra 2056e34652f15f32666323052a6718a63248244f1e66Duane Sand nop 20575bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee1: 20585bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee DELIVER_PENDING_EXCEPTION 2059d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_proxy_invoke_handler 20605bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 206188474b416eb257078e590bf9bc7957cee604a186Jeff Hao /* 206259028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic * Called to resolve an imt conflict. 206359028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic * a0 is the conflict ArtMethod. 20641b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze * t7 is a hidden argument that holds the target interface method's dex method index. 206559028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic * 20661b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze * Note that this stub writes to a0, t7 and t8. 206788474b416eb257078e590bf9bc7957cee604a186Jeff Hao */ 206813738bf7c769638b7922cb2477471ad382632bc2Douglas LeungENTRY art_quick_imt_conflict_trampoline 20691b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $t8, 0($sp) # Load referrer. 20701b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $t8, ART_METHOD_DEX_CACHE_METHODS_OFFSET_32($t8) # Load dex cache methods array. 20711b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze sll $t7, $t7, POINTER_SIZE_SHIFT # Calculate offset. 20721b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze addu $t7, $t8, $t7 # Add offset to base. 20731b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $t7, 0($t7) # Load interface method. 207459028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic lw $a0, ART_METHOD_JNI_OFFSET_32($a0) # Load ImtConflictTable. 207559028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic 207659028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic.Limt_table_iterate: 20771b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $t8, 0($a0) # Load next entry in ImtConflictTable. 207859028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic # Branch if found. 20791b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze beq $t8, $t7, .Limt_table_found 208059028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic nop 208159028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic # If the entry is null, the interface method is not in the ImtConflictTable. 20821b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze beqz $t8, .Lconflict_trampoline 208359028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic nop 208459028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic # Iterate over the entries of the ImtConflictTable. 208559028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic b .Limt_table_iterate 208659028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic addiu $a0, $a0, 2 * __SIZEOF_POINTER__ # Iterate to the next entry. 208759028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic 208859028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic.Limt_table_found: 208959028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic # We successfully hit an entry in the table. Load the target method and jump to it. 209059028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic lw $a0, __SIZEOF_POINTER__($a0) 209159028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic lw $t9, ART_METHOD_QUICK_CODE_OFFSET_32($a0) 20921b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze jalr $zero, $t9 209359028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic nop 209459028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic 209559028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic.Lconflict_trampoline: 209659028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic # Call the runtime stub to populate the ImtConflictTable and jump to the resolved method. 20975667f56867383fc4113aa4a6551efdf9f48ee5e7Jeff Hao move $a0, $t7 # Load interface method. 20983031c8da0c5009183f770b005c245f9bf2a4d01bAndreas Gampe INVOKE_TRAMPOLINE_BODY artInvokeInterfaceTrampoline 209988474b416eb257078e590bf9bc7957cee604a186Jeff HaoEND art_quick_imt_conflict_trampoline 210088474b416eb257078e590bf9bc7957cee604a186Jeff Hao 2101468532ea115657709bc32ee498e701a4c71762d4Ian Rogers .extern artQuickResolutionTrampoline 2102468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_resolution_trampoline 2103fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_AND_ARGS_FRAME 2104735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung move $a2, rSELF # pass Thread::Current 2105590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artQuickResolutionTrampoline 2106590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 # (Method* called, receiver, Thread*, SP) 2107735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $a3, $sp, ARG_SLOT_SIZE # pass $sp (remove arg slots) 2108468532ea115657709bc32ee498e701a4c71762d4Ian Rogers beqz $v0, 1f 2109735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $a0, ARG_SLOT_SIZE($sp) # load resolved method to $a0 2110fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko RESTORE_SAVE_REFS_AND_ARGS_FRAME 211165d1b22d0b02fb0111f69013163c8170e68392f1Ian Rogers move $t9, $v0 # code pointer must be in $t9 to generate the global pointer 2112f96e8bdf47cfcbecd8ad8ebceb765e5a257ca143Douglas Leung jalr $zero, $t9 # tail call to method 21131984152ac92aad244ae15184d12f9ceade686b7bMathieu Chartier nop 2114468532ea115657709bc32ee498e701a4c71762d4Ian Rogers1: 2115fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko RESTORE_SAVE_REFS_AND_ARGS_FRAME 2116468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DELIVER_PENDING_EXCEPTION 2117468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_resolution_trampoline 2118468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 2119735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .extern artQuickGenericJniTrampoline 2120735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .extern artQuickGenericJniEndTrampoline 2121735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas LeungENTRY art_quick_generic_jni_trampoline 2122fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_A0 2123735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung move $s8, $sp # save $sp to $s8 2124735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung move $s3, $gp # save $gp to $s3 2125735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung 2126735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung # prepare for call to artQuickGenericJniTrampoline(Thread*, SP) 2127735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung move $a0, rSELF # pass Thread::Current 2128735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $a1, $sp, ARG_SLOT_SIZE # save $sp (remove arg slots) 2129590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artQuickGenericJniTrampoline 2130590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 # (Thread*, SP) 2131735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, -5120 # reserve space on the stack 2132735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung 2133735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung # The C call will have registered the complete save-frame on success. 2134735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung # The result of the call is: 2135735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung # v0: ptr to native code, 0 on error. 2136735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung # v1: ptr to the bottom of the used area of the alloca, can restore stack till here. 21371b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze beq $v0, $zero, 2f # check entry error 2138735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung move $t9, $v0 # save the code ptr 2139735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung move $sp, $v1 # release part of the alloca 2140735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung 2141735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung # Load parameters from stack into registers 2142735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $a0, 0($sp) 2143735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $a1, 4($sp) 2144735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $a2, 8($sp) 21451b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $a3, 12($sp) 21461b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze 21471b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze # artQuickGenericJniTrampoline sets bit 0 of the native code address to 1 21481b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze # when the first two arguments are both single precision floats. This lets 21491b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze # us extract them properly from the stack and load into floating point 21501b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze # registers. 21511b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze MTD $a0, $a1, $f12, $f13 21521b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze andi $t0, $t9, 1 21531b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze xor $t9, $t9, $t0 21541b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze bnez $t0, 1f 21551b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze mtc1 $a1, $f14 21561b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze MTD $a2, $a3, $f14, $f15 2157735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung 21581b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze1: 2159735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung jalr $t9 # native call 21601b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze nop 2161735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, 16 # remove arg slots 2162735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung 2163735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung move $gp, $s3 # restore $gp from $s3 2164735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung 2165735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung # result sign extension is handled in C code 2166735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung # prepare for call to artQuickGenericJniEndTrampoline(Thread*, result, result_f) 2167735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung move $a0, rSELF # pass Thread::Current 2168735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung move $a2, $v0 # pass result 2169735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung move $a3, $v1 2170735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, -24 # reserve arg slots 2171590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artQuickGenericJniEndTrampoline 2172590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 2173735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung s.d $f0, 16($sp) # pass result_f 2174735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung 2175735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_ 21761b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze bne $t0, $zero, 2f # check for pending exceptions 2177126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray 2178735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung move $sp, $s8 # tear down the alloca 2179735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung 21801b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze # tear down the callee-save frame 2181fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko RESTORE_SAVE_REFS_AND_ARGS_FRAME 2182735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung 2183e34652f15f32666323052a6718a63248244f1e66Duane Sand MTD $v0, $v1, $f0, $f1 # move float value to return value 21848d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $ra 2185e34652f15f32666323052a6718a63248244f1e66Duane Sand nop 2186735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung 21871b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze2: 2188c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze lw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) 2189c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze move $gp, $s3 # restore $gp from $s3 2190126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray # This will create a new save-all frame, required by the runtime. 2191735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung DELIVER_PENDING_EXCEPTION 2192735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas LeungEND art_quick_generic_jni_trampoline 21932da882315a61072664f7ce3c212307342e907207Andreas Gampe 2194468532ea115657709bc32ee498e701a4c71762d4Ian Rogers .extern artQuickToInterpreterBridge 2195468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_to_interpreter_bridge 2196fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_AND_ARGS_FRAME 2197735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung move $a1, rSELF # pass Thread::Current 2198590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artQuickToInterpreterBridge 2199590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic jalr $t9 # (Method* method, Thread*, SP) 2200735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $a2, $sp, ARG_SLOT_SIZE # pass $sp (remove arg slots) 22011b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze lw $t7, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_ 2202fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko RESTORE_SAVE_REFS_AND_ARGS_FRAME 22031b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze bnez $t7, 1f 2204e34652f15f32666323052a6718a63248244f1e66Duane Sand # don't care if $v0 and/or $v1 are modified, when exception branch taken 2205e34652f15f32666323052a6718a63248244f1e66Duane Sand MTD $v0, $v1, $f0, $f1 # move float value to return value 22068d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe jalr $zero, $ra 2207e34652f15f32666323052a6718a63248244f1e66Duane Sand nop 22087db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers1: 22097db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers DELIVER_PENDING_EXCEPTION 2210468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_to_interpreter_bridge 22117db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers 2212db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex Light .extern artInvokeObsoleteMethod 2213db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex LightENTRY art_invoke_obsolete_method_stub 2214db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex Light SETUP_SAVE_ALL_CALLEE_SAVES_FRAME 2215db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex Light la $t9, artInvokeObsoleteMethod 2216db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex Light jalr $t9 # (Method* method, Thread* self) 2217db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex Light move $a1, rSELF # pass Thread::Current 2218db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex LightEND art_invoke_obsolete_method_stub 2219db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex Light 22205bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 2221725a957985171d712d5c048cc3d00ff14968784bjeffhao * Routine that intercepts method calls and returns. 22225bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 2223d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao .extern artInstrumentationMethodEntryFromCode 2224d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao .extern artInstrumentationMethodExitFromCode 2225468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_instrumentation_entry 2226fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_AND_ARGS_FRAME 2227735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung sw $a0, 28($sp) # save arg0 in free arg slot 222825e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic addiu $a3, $sp, ARG_SLOT_SIZE # Pass $sp. 2229590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artInstrumentationMethodEntryFromCode 223025e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic jalr $t9 # (Method*, Object*, Thread*, SP) 223162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers move $a2, rSELF # pass Thread::Current 223225e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic beqz $v0, .Ldeliver_instrumentation_entry_exception 22338161c0336b97e11e02c000af357f8f40de2e23e4jeffhao move $t9, $v0 # $t9 holds reference to code 2234735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung lw $a0, 28($sp) # restore arg0 from free arg slot 2235fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko RESTORE_SAVE_REFS_AND_ARGS_FRAME 22368161c0336b97e11e02c000af357f8f40de2e23e4jeffhao jalr $t9 # call method 223762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers nop 2238468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_instrumentation_entry 22395bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* intentional fallthrough */ 2240468532ea115657709bc32ee498e701a4c71762d4Ian Rogers .global art_quick_instrumentation_exit 2241468532ea115657709bc32ee498e701a4c71762d4Ian Rogersart_quick_instrumentation_exit: 2242d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao .cfi_startproc 224312051ea86ec27703b07b3d5c2cd4604b20f71810jeffhao addiu $t9, $ra, 4 # put current address into $t9 to rebuild $gp 22441d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers .cpload $t9 2245c3d131e1ec030b4ff5c44fe2a45d5fb45b3295afDouglas Leung move $ra, $zero # link register is to here, so clobber with 0 for later checks 2246735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung 2247fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_REFS_ONLY_FRAME 2248735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung addiu $sp, $sp, -16 # allocate temp storage on the stack 2249735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung .cfi_adjust_cfa_offset 16 225025e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic sw $v0, ARG_SLOT_SIZE+8($sp) 225125e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic .cfi_rel_offset 2, ARG_SLOT_SIZE+8 225225e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic sw $v1, ARG_SLOT_SIZE+12($sp) 225325e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic .cfi_rel_offset 3, ARG_SLOT_SIZE+12 2254f96e8bdf47cfcbecd8ad8ebceb765e5a257ca143Douglas Leung s.d $f0, ARG_SLOT_SIZE($sp) 225525e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic addiu $a3, $sp, ARG_SLOT_SIZE # Pass fpr_res pointer. 225625e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic addiu $a2, $sp, ARG_SLOT_SIZE+8 # Pass gpr_res pointer. 225725e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic addiu $a1, $sp, ARG_SLOT_SIZE+16 # Pass $sp (remove arg slots and temp storage). 2258590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artInstrumentationMethodExitFromCode 225925e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic jalr $t9 # (Thread*, SP, gpr_res*, fpr_res*) 226025e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic move $a0, rSELF # Pass Thread::Current. 226125e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic move $t9, $v0 # Set aside returned link register. 226225e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic move $ra, $v1 # Set link register for deoptimization. 226325e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic lw $v0, ARG_SLOT_SIZE+8($sp) # Restore return values. 226425e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic lw $v1, ARG_SLOT_SIZE+12($sp) 2265f96e8bdf47cfcbecd8ad8ebceb765e5a257ca143Douglas Leung l.d $f0, ARG_SLOT_SIZE($sp) 226625e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic addiu $sp, $sp, 16 226725e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic .cfi_adjust_cfa_offset -16 226825e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic RESTORE_SAVE_REFS_ONLY_FRAME 226925e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic beqz $t9, .Ldo_deliver_instrumentation_exception 227025e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic nop # Deliver exception if we got nullptr as function. 227125e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic jalr $zero, $t9 # Otherwise, return. 227225e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic nop 227325e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic.Ldeliver_instrumentation_entry_exception: 227425e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic # Deliver exception for art_quick_instrumentation_entry placed after 227525e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic # art_quick_instrumentation_exit so that the fallthrough works. 227625e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic RESTORE_SAVE_REFS_AND_ARGS_FRAME 227725e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic.Ldo_deliver_instrumentation_exception: 227825e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic DELIVER_PENDING_EXCEPTION 2279468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_instrumentation_exit 22805bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 228112051ea86ec27703b07b3d5c2cd4604b20f71810jeffhao /* 228262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization 228362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers * will long jump to the upcall with a special exception of -1. 228412051ea86ec27703b07b3d5c2cd4604b20f71810jeffhao */ 2285d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao .extern artDeoptimize 2286d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoENTRY art_quick_deoptimize 2287fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko SETUP_SAVE_ALL_CALLEE_SAVES_FRAME 2288590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artDeoptimize 22894e92c3ce7ef354620a785553bbada554fca83a67Nicolas Geoffray jalr $t9 # (Thread*) 22901d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers move $a0, rSELF # pass Thread::current 2291d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_deoptimize 229212051ea86ec27703b07b3d5c2cd4604b20f71810jeffhao 22935bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 22940747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz * Compiled code has requested that we deoptimize into the interpreter. The deoptimization 22950747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz * will long jump to the upcall with a special exception of -1. 22960747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz */ 22970747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz .extern artDeoptimizeFromCompiledCode 22980747466fca310eedea5fc49e37d54f240a0b3c0fSebastien HertzENTRY art_quick_deoptimize_from_compiled_code 2299239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko SETUP_SAVE_EVERYTHING_FRAME 2300590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic la $t9, artDeoptimizeFromCompiledCode 23014e92c3ce7ef354620a785553bbada554fca83a67Nicolas Geoffray jalr $t9 # (DeoptimizationKind, Thread*) 23024e92c3ce7ef354620a785553bbada554fca83a67Nicolas Geoffray move $a1, rSELF # pass Thread::current 23030747466fca310eedea5fc49e37d54f240a0b3c0fSebastien HertzEND art_quick_deoptimize_from_compiled_code 23040747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz 23050747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz /* 23065bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Long integer shift. This is different from the generic 32/64-bit 23075bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * binary operations because vAA/vBB are 64-bit but vCC (the shift 23085bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low 23095bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * 6 bits. 23105bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * On entry: 23117fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * $a0: low word 23127fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * $a1: high word 23137fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * $a2: shift count 23145bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 23151d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersENTRY_NO_GP art_quick_shl_long 23165bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* shl-long vAA, vBB, vCC */ 23177fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao sll $v0, $a0, $a2 # rlo<- alo << (shift&31) 23187fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao not $v1, $a2 # rhi<- 31-shift (shift is 5b) 23197fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao srl $a0, 1 23207fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao srl $a0, $v1 # alo<- alo >> (32-(shift&31)) 23217fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao sll $v1, $a1, $a2 # rhi<- ahi << (shift&31) 23227fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao andi $a2, 0x20 # shift< shift & 0x20 2323e34652f15f32666323052a6718a63248244f1e66Duane Sand beqz $a2, 1f 2324e34652f15f32666323052a6718a63248244f1e66Duane Sand or $v1, $a0 # rhi<- rhi | alo 2325e34652f15f32666323052a6718a63248244f1e66Duane Sand 2326e34652f15f32666323052a6718a63248244f1e66Duane Sand move $v1, $v0 # rhi<- rlo (if shift&0x20) 2327e34652f15f32666323052a6718a63248244f1e66Duane Sand move $v0, $zero # rlo<- 0 (if shift&0x20) 2328e34652f15f32666323052a6718a63248244f1e66Duane Sand 23298d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe1: jalr $zero, $ra 2330e34652f15f32666323052a6718a63248244f1e66Duane Sand nop 2331d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_shl_long 23325bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 23335bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 23345bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Long integer shift. This is different from the generic 32/64-bit 23355bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * binary operations because vAA/vBB are 64-bit but vCC (the shift 23365bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low 23375bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * 6 bits. 23385bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * On entry: 23397fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * $a0: low word 23407fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * $a1: high word 23417fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao * $a2: shift count 23425bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 23431d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersENTRY_NO_GP art_quick_shr_long 23447fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao sra $v1, $a1, $a2 # rhi<- ahi >> (shift&31) 23457fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao srl $v0, $a0, $a2 # rlo<- alo >> (shift&31) 23467fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao sra $a3, $a1, 31 # $a3<- sign(ah) 23477fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao not $a0, $a2 # alo<- 31-shift (shift is 5b) 23487fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao sll $a1, 1 23497fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao sll $a1, $a0 # ahi<- ahi << (32-(shift&31)) 23507fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao andi $a2, 0x20 # shift & 0x20 2351475cfd8ff9dcc73d1a7502c9310efe0f1a30337fDouglas Leung beqz $a2, 1f 2352e34652f15f32666323052a6718a63248244f1e66Duane Sand or $v0, $a1 # rlo<- rlo | ahi 2353e34652f15f32666323052a6718a63248244f1e66Duane Sand 2354e34652f15f32666323052a6718a63248244f1e66Duane Sand move $v0, $v1 # rlo<- rhi (if shift&0x20) 2355e34652f15f32666323052a6718a63248244f1e66Duane Sand move $v1, $a3 # rhi<- sign(ahi) (if shift&0x20) 2356e34652f15f32666323052a6718a63248244f1e66Duane Sand 23578d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe1: jalr $zero, $ra 2358e34652f15f32666323052a6718a63248244f1e66Duane Sand nop 2359d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_shr_long 23605bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee 23615bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* 23625bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * Long integer shift. This is different from the generic 32/64-bit 23635bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * binary operations because vAA/vBB are 64-bit but vCC (the shift 23645bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low 23655bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * 6 bits. 23665bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee * On entry: 2367590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic * $a0: low word 2368590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic * $a1: high word 2369590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic * $a2: shift count 23705bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee */ 23715bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee /* ushr-long vAA, vBB, vCC */ 23721d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersENTRY_NO_GP art_quick_ushr_long 2373fc6a30e2fa8f0d44e6c95bbeb5deca4b499f67cejeffhao srl $v1, $a1, $a2 # rhi<- ahi >> (shift&31) 23747fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao srl $v0, $a0, $a2 # rlo<- alo >> (shift&31) 23757fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao not $a0, $a2 # alo<- 31-shift (shift is 5b) 23767fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao sll $a1, 1 23777fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao sll $a1, $a0 # ahi<- ahi << (32-(shift&31)) 23787fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao andi $a2, 0x20 # shift & 0x20 2379e34652f15f32666323052a6718a63248244f1e66Duane Sand beqz $a2, 1f 2380e34652f15f32666323052a6718a63248244f1e66Duane Sand or $v0, $a1 # rlo<- rlo | ahi 2381e34652f15f32666323052a6718a63248244f1e66Duane Sand 2382e34652f15f32666323052a6718a63248244f1e66Duane Sand move $v0, $v1 # rlo<- rhi (if shift&0x20) 2383e34652f15f32666323052a6718a63248244f1e66Duane Sand move $v1, $zero # rhi<- 0 (if shift&0x20) 2384e34652f15f32666323052a6718a63248244f1e66Duane Sand 23858d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe1: jalr $zero, $ra 2386e34652f15f32666323052a6718a63248244f1e66Duane Sand nop 2387d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_ushr_long 23887fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao 2389cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* java.lang.String.indexOf(int ch, int fromIndex=0) */ 2390cf283daf579e9eda586f312c3fc89444601e2525Chris LarsenENTRY_NO_GP art_quick_indexof 2391cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* $a0 holds address of "this" */ 2392cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* $a1 holds "ch" */ 2393cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* $a2 holds "fromIndex" */ 2394f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#if (STRING_COMPRESSION_FEATURE) 2395f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lw $a3, MIRROR_STRING_COUNT_OFFSET($a0) # 'count' field of this 2396f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#else 2397f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lw $t0, MIRROR_STRING_COUNT_OFFSET($a0) # this.length() 2398f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#endif 2399f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic slt $t1, $a2, $zero # if fromIndex < 0 2400cdb23d6f4d4049f6f26b0ed629fcc5018bfe3a57Goran Jakovljevic#if defined(_MIPS_ARCH_MIPS32R6) 2401f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic seleqz $a2, $a2, $t1 # fromIndex = 0; 2402cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen#else 2403f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic movn $a2, $zero, $t1 # fromIndex = 0; 2404cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen#endif 2405cdb23d6f4d4049f6f26b0ed629fcc5018bfe3a57Goran Jakovljevic 2406f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#if (STRING_COMPRESSION_FEATURE) 2407f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic srl $t0, $a3, 1 # $a3 holds count (with flag) and $t0 holds actual length 2408f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#endif 2409f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic subu $t0, $t0, $a2 # this.length() - fromIndex 2410f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic blez $t0, 6f # if this.length()-fromIndex <= 0 2411f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic li $v0, -1 # return -1; 2412f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic 2413f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#if (STRING_COMPRESSION_FEATURE) 2414f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic sll $a3, $a3, 31 # Extract compression flag. 2415f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic beqz $a3, .Lstring_indexof_compressed 2416f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic move $t2, $a0 # Save a copy in $t2 to later compute result (in branch delay slot). 2417f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#endif 2418f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic sll $v0, $a2, 1 # $a0 += $a2 * 2 2419f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic addu $a0, $a0, $v0 # " ditto " 2420f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic move $v0, $a2 # Set i to fromIndex. 2421cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen 2422cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen1: 2423f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lhu $t3, MIRROR_STRING_VALUE_OFFSET($a0) # if this.charAt(i) == ch 2424f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic beq $t3, $a1, 6f # return i; 2425f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic addu $a0, $a0, 2 # i++ 2426f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic subu $t0, $t0, 1 # this.length() - i 2427f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic bnez $t0, 1b # while this.length() - i > 0 2428f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic addu $v0, $v0, 1 # i++ 2429cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen 2430f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic li $v0, -1 # if this.length() - i <= 0 2431f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic # return -1; 2432cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen 2433cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen6: 2434f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic j $ra 2435f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic nop 2436f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic 2437f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#if (STRING_COMPRESSION_FEATURE) 2438f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_indexof_compressed: 2439f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic addu $a0, $a0, $a2 # $a0 += $a2 2440f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic 2441f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_indexof_compressed_loop: 2442f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lbu $t3, MIRROR_STRING_VALUE_OFFSET($a0) 2443f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic beq $t3, $a1, .Lstring_indexof_compressed_matched 2444f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic subu $t0, $t0, 1 2445f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic bgtz $t0, .Lstring_indexof_compressed_loop 2446f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic addu $a0, $a0, 1 2447f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic 2448f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_indexof_nomatch: 2449f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic jalr $zero, $ra 2450f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic li $v0, -1 # return -1; 2451f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic 2452f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_indexof_compressed_matched: 2453f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic jalr $zero, $ra 2454f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic subu $v0, $a0, $t2 # return (current - start); 2455f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#endif 2456cf283daf579e9eda586f312c3fc89444601e2525Chris LarsenEND art_quick_indexof 2457cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen 2458cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* java.lang.String.compareTo(String anotherString) */ 2459cf283daf579e9eda586f312c3fc89444601e2525Chris LarsenENTRY_NO_GP art_quick_string_compareto 2460cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* $a0 holds address of "this" */ 2461cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* $a1 holds address of "anotherString" */ 2462f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic beq $a0, $a1, .Lstring_compareto_length_diff # this and anotherString are the same object 2463f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic move $a3, $a2 # trick to return 0 (it returns a2 - a3) 2464f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic 2465f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#if (STRING_COMPRESSION_FEATURE) 2466f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lw $t0, MIRROR_STRING_COUNT_OFFSET($a0) # 'count' field of this 2467f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lw $t1, MIRROR_STRING_COUNT_OFFSET($a1) # 'count' field of anotherString 2468f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic sra $a2, $t0, 1 # this.length() 2469f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic sra $a3, $t1, 1 # anotherString.length() 2470f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#else 2471f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lw $a2, MIRROR_STRING_COUNT_OFFSET($a0) # this.length() 2472f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lw $a3, MIRROR_STRING_COUNT_OFFSET($a1) # anotherString.length() 2473f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#endif 2474cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen 2475f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic MINu $t2, $a2, $a3 2476f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic # $t2 now holds min(this.length(),anotherString.length()) 2477cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen 2478f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic # while min(this.length(),anotherString.length())-i != 0 2479f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic beqz $t2, .Lstring_compareto_length_diff # if $t2==0 2480f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic nop # return (this.length() - anotherString.length()) 2481f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic 2482f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#if (STRING_COMPRESSION_FEATURE) 2483f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic # Differ cases: 2484f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic sll $t3, $t0, 31 2485f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic beqz $t3, .Lstring_compareto_this_is_compressed 2486f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic sll $t3, $t1, 31 # In branch delay slot. 2487f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic beqz $t3, .Lstring_compareto_that_is_compressed 2488f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic nop 2489f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic b .Lstring_compareto_both_not_compressed 2490f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic nop 2491f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic 2492f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_this_is_compressed: 2493f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic beqz $t3, .Lstring_compareto_both_compressed 2494f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic nop 2495f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic /* If (this->IsCompressed() && that->IsCompressed() == false) */ 2496f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_loop_comparison_this_compressed: 2497f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lbu $t0, MIRROR_STRING_VALUE_OFFSET($a0) 2498f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lhu $t1, MIRROR_STRING_VALUE_OFFSET($a1) 2499f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic bne $t0, $t1, .Lstring_compareto_char_diff 2500f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic addiu $a0, $a0, 1 # point at this.charAt(i++) - compressed 2501f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i 2502f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic bnez $t2, .Lstring_compareto_loop_comparison_this_compressed 2503f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic addiu $a1, $a1, 2 # point at anotherString.charAt(i++) - uncompressed 2504f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic jalr $zero, $ra 2505f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic subu $v0, $a2, $a3 # return (this.length() - anotherString.length()) 2506f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic 2507f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_that_is_compressed: 2508f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lhu $t0, MIRROR_STRING_VALUE_OFFSET($a0) 2509f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lbu $t1, MIRROR_STRING_VALUE_OFFSET($a1) 2510f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic bne $t0, $t1, .Lstring_compareto_char_diff 2511f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic addiu $a0, $a0, 2 # point at this.charAt(i++) - uncompressed 2512f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i 2513f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic bnez $t2, .Lstring_compareto_that_is_compressed 2514f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic addiu $a1, $a1, 1 # point at anotherString.charAt(i++) - compressed 2515f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic jalr $zero, $ra 2516f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic subu $v0, $a2, $a3 # return (this.length() - anotherString.length()) 2517f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic 2518f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_both_compressed: 2519f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lbu $t0, MIRROR_STRING_VALUE_OFFSET($a0) 2520f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lbu $t1, MIRROR_STRING_VALUE_OFFSET($a1) 2521f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic bne $t0, $t1, .Lstring_compareto_char_diff 2522f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic addiu $a0, $a0, 1 # point at this.charAt(i++) - compressed 2523f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i 2524f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic bnez $t2, .Lstring_compareto_both_compressed 2525f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic addiu $a1, $a1, 1 # point at anotherString.charAt(i++) - compressed 2526f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic jalr $zero, $ra 2527f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic subu $v0, $a2, $a3 # return (this.length() - anotherString.length()) 2528f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#endif 2529f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic 2530f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_both_not_compressed: 2531f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lhu $t0, MIRROR_STRING_VALUE_OFFSET($a0) # while this.charAt(i) == anotherString.charAt(i) 2532f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic lhu $t1, MIRROR_STRING_VALUE_OFFSET($a1) 2533f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic bne $t0, $t1, .Lstring_compareto_char_diff # if this.charAt(i) != anotherString.charAt(i) 2534f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic # return (this.charAt(i) - anotherString.charAt(i)) 2535f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic addiu $a0, $a0, 2 # point at this.charAt(i++) 2536f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i 2537f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic bnez $t2, .Lstring_compareto_both_not_compressed 2538f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic addiu $a1, $a1, 2 # point at anotherString.charAt(i++) 2539f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic 2540f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_length_diff: 2541f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic jalr $zero, $ra 2542f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic subu $v0, $a2, $a3 # return (this.length() - anotherString.length()) 2543f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic 2544f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_char_diff: 2545f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic jalr $zero, $ra 2546f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic subu $v0, $t0, $t1 # return (this.charAt(i) - anotherString.charAt(i)) 2547cf283daf579e9eda586f312c3fc89444601e2525Chris LarsenEND art_quick_string_compareto 2548ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson 25491595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze /* 25501595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze * Create a function `name` calling the ReadBarrier::Mark routine, 25511595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze * getting its argument and returning its result through register 25521595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze * `reg`, saving and restoring all caller-save registers. 25531595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze */ 25541595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze.macro READ_BARRIER_MARK_REG name, reg 25551595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeENTRY \name 2556a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze // Null check so that we can load the lock word. 2557a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze bnez \reg, .Lnot_null_\name 2558a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze nop 2559a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze.Lret_rb_\name: 2560a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze jalr $zero, $ra 2561a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze nop 2562a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze.Lnot_null_\name: 2563a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze // Check lock word for mark bit, if marked return. 2564a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze lw $t9, MIRROR_OBJECT_LOCK_WORD_OFFSET(\reg) 2565a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze .set push 2566a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze .set noat 2567a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze sll $at, $t9, 31 - LOCK_WORD_MARK_BIT_SHIFT # Move mark bit to sign bit. 2568a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze bltz $at, .Lret_rb_\name 2569a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze#if (LOCK_WORD_STATE_SHIFT != 30) || (LOCK_WORD_STATE_FORWARDING_ADDRESS != 3) 2570a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze // The below code depends on the lock word state being in the highest bits 2571a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze // and the "forwarding address" state having all bits set. 2572a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze#error "Unexpected lock word state shift or forwarding address state value." 2573a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze#endif 2574a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze // Test that both the forwarding state bits are 1. 2575a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze sll $at, $t9, 1 2576a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze and $at, $at, $t9 # Sign bit = 1 IFF both bits are 1. 2577a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze bltz $at, .Lret_forwarding_address\name 2578a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze nop 2579a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze .set pop 2580a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze 2581a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze addiu $sp, $sp, -160 # Includes 16 bytes of space for argument registers a0-a3. 25821595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_adjust_cfa_offset 160 25831595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze 25841595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $ra, 156($sp) 25851595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 31, 156 25861595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $t8, 152($sp) 25871595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 24, 152 25881595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $t7, 148($sp) 25891595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 15, 148 25901595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $t6, 144($sp) 25911595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 14, 144 25921595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $t5, 140($sp) 25931595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 13, 140 25941595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $t4, 136($sp) 25951595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 12, 136 25961595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $t3, 132($sp) 25971595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 11, 132 25981595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $t2, 128($sp) 25991595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 10, 128 26001595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $t1, 124($sp) 26011595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 9, 124 26021595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $t0, 120($sp) 26031595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 8, 120 26041595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $a3, 116($sp) 26051595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 7, 116 26061595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $a2, 112($sp) 26071595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 6, 112 26081595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $a1, 108($sp) 26091595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 5, 108 26101595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $a0, 104($sp) 26111595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 4, 104 26121595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $v1, 100($sp) 26131595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 3, 100 26141595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sw $v0, 96($sp) 26151595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_rel_offset 2, 96 26161595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze 26171595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze la $t9, artReadBarrierMark 26181595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze 26191595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sdc1 $f18, 88($sp) 26201595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sdc1 $f16, 80($sp) 26211595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sdc1 $f14, 72($sp) 26221595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sdc1 $f12, 64($sp) 26231595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sdc1 $f10, 56($sp) 26241595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sdc1 $f8, 48($sp) 26251595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sdc1 $f6, 40($sp) 26261595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sdc1 $f4, 32($sp) 26271595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sdc1 $f2, 24($sp) 26281595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze 26291595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .ifnc \reg, $a0 26301595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze move $a0, \reg # pass obj from `reg` in a0 26311595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .endif 26321595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze jalr $t9 # v0 <- artReadBarrierMark(obj) 26331595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze sdc1 $f0, 16($sp) # in delay slot 26341595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze 26351595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $ra, 156($sp) 26361595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 31 26371595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $t8, 152($sp) 26381595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 24 26391595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $t7, 148($sp) 26401595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 15 26411595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $t6, 144($sp) 26421595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 14 26431595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $t5, 140($sp) 26441595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 13 26451595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $t4, 136($sp) 26461595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 12 26471595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $t3, 132($sp) 26481595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 11 26491595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $t2, 128($sp) 26501595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 10 26511595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $t1, 124($sp) 26521595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 9 26531595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $t0, 120($sp) 26541595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 8 26551595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $a3, 116($sp) 26561595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 7 26571595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $a2, 112($sp) 26581595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 6 26591595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $a1, 108($sp) 26601595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 5 26611595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $a0, 104($sp) 26621595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 4 26631595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $v1, 100($sp) 26641595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 3 26651595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze 26661595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .ifnc \reg, $v0 26671595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze move \reg, $v0 # `reg` <- v0 26681595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze lw $v0, 96($sp) 26691595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_restore 2 26701595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .endif 26711595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze 26721595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze ldc1 $f18, 88($sp) 26731595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze ldc1 $f16, 80($sp) 26741595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze ldc1 $f14, 72($sp) 26751595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze ldc1 $f12, 64($sp) 26761595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze ldc1 $f10, 56($sp) 26771595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze ldc1 $f8, 48($sp) 26781595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze ldc1 $f6, 40($sp) 26791595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze ldc1 $f4, 32($sp) 26801595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze ldc1 $f2, 24($sp) 26811595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze ldc1 $f0, 16($sp) 26821595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze 26831595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze jalr $zero, $ra 26841595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze addiu $sp, $sp, 160 26851595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze .cfi_adjust_cfa_offset -160 2686a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze 2687a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze.Lret_forwarding_address\name: 2688a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze jalr $zero, $ra 2689a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze // Shift left by the forwarding address shift. This clears out the state bits since they are 2690a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze // in the top 2 bits of the lock word. 2691a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze sll \reg, $t9, LOCK_WORD_STATE_FORWARDING_ADDRESS_SHIFT 26921595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeEND \name 26931595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze.endm 26941595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze 26951595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// Note that art_quick_read_barrier_mark_regXX corresponds to register XX+1. 26961595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// ZERO (register 0) is reserved. 26971595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// AT (register 1) is reserved as a temporary/scratch register. 26981595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg01, $v0 26991595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg02, $v1 27001595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg03, $a0 27011595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg04, $a1 27021595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg05, $a2 27031595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg06, $a3 27041595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg07, $t0 27051595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg08, $t1 27061595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg09, $t2 27071595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg10, $t3 27081595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg11, $t4 27091595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg12, $t5 27101595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg13, $t6 27111595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg14, $t7 27121595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// S0 and S1 (registers 16 and 17) are reserved as suspended and thread registers. 27131595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg17, $s2 27141595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg18, $s3 27151595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg19, $s4 27161595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg20, $s5 27171595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg21, $s6 27181595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg22, $s7 27191595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// T8 and T9 (registers 24 and 25) are reserved as temporary/scratch registers. 27201595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// K0, K1, GP, SP (registers 26 - 29) are reserved. 27211595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg29, $s8 27221595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// RA (register 31) is reserved. 27231595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze 27244147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// Caller code: 27254147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// Short constant offset/index: 27264147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// R2: | R6: 27274147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// lw $t9, pReadBarrierMarkReg00 27284147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// beqz $t9, skip_call | beqzc $t9, skip_call 27294147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// addiu $t9, $t9, thunk_disp | nop 27304147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// jalr $t9 | jialc $t9, thunk_disp 27314147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// nop | 27324147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// skip_call: | skip_call: 27334147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// lw `out`, ofs(`obj`) | lw `out`, ofs(`obj`) 27344147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// [subu `out`, $zero, `out`] | [subu `out`, $zero, `out`] # Unpoison reference. 27354147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.macro BRB_FIELD_SHORT_OFFSET_ENTRY obj 27364147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze1: 27374147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # Explicit null check. May be redundant (for array elements or when the field 27384147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # offset is larger than the page size, 4KB). 27394147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # $ra will be adjusted to point to lw's stack map when throwing NPE. 27404147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze beqz \obj, .Lintrospection_throw_npe 27414147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#if defined(_MIPS_ARCH_MIPS32R6) 27424147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lapc $gp, .Lintrospection_exits # $gp = address of .Lintrospection_exits. 27434147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#else 27444147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze addiu $gp, $t9, (.Lintrospection_exits - 1b) # $gp = address of .Lintrospection_exits. 27454147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#endif 27464147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .set push 27474147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .set noat 27484147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $at, MIRROR_OBJECT_LOCK_WORD_OFFSET(\obj) 27494147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sll $at, $at, 31 - LOCK_WORD_READ_BARRIER_STATE_SHIFT # Move barrier state bit 27504147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # to sign bit. 27514147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze bltz $at, .Lintrospection_field_array # If gray, load reference, mark. 27524147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze move $t8, \obj # Move `obj` to $t8 for common code. 27534147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .set pop 27544147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze jalr $zero, $ra # Otherwise, load-load barrier and return. 27554147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sync 27564147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.endm 27574147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 27584147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// Caller code (R2): 27594147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// Long constant offset/index: | Variable index: 27604147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// lw $t9, pReadBarrierMarkReg00 27614147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// lui $t8, ofs_hi | sll $t8, `index`, 2 27624147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// beqz $t9, skip_call | beqz $t9, skip_call 27634147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// addiu $t9, $t9, thunk_disp | addiu $t9, $t9, thunk_disp 27644147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// jalr $t9 | jalr $t9 27654147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// skip_call: | skip_call: 27664147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// addu $t8, $t8, `obj` | addu $t8, $t8, `obj` 27674147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// lw `out`, ofs_lo($t8) | lw `out`, ofs($t8) 27684147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// [subu `out`, $zero, `out`] | [subu `out`, $zero, `out`] # Unpoison reference. 27694147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// 27704147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// Caller code (R6): 27714147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// Long constant offset/index: | Variable index: 27724147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// lw $t9, pReadBarrierMarkReg00 27734147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// beqz $t9, skip_call | beqz $t9, skip_call 27744147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// aui $t8, `obj`, ofs_hi | lsa $t8, `index`, `obj`, 2 27754147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// jialc $t9, thunk_disp | jialc $t9, thunk_disp 27764147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// skip_call: | skip_call: 27774147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// lw `out`, ofs_lo($t8) | lw `out`, ofs($t8) 27784147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// [subu `out`, $zero, `out`] | [subu `out`, $zero, `out`] # Unpoison reference. 27794147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.macro BRB_FIELD_LONG_OFFSET_ENTRY obj 27804147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze1: 27814147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # No explicit null check for variable indices or large constant indices/offsets 27824147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # as it must have been done earlier. 27834147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#if defined(_MIPS_ARCH_MIPS32R6) 27844147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lapc $gp, .Lintrospection_exits # $gp = address of .Lintrospection_exits. 27854147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#else 27864147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze addiu $gp, $t9, (.Lintrospection_exits - 1b) # $gp = address of .Lintrospection_exits. 27874147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#endif 27884147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .set push 27894147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .set noat 27904147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $at, MIRROR_OBJECT_LOCK_WORD_OFFSET(\obj) 27914147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sll $at, $at, 31 - LOCK_WORD_READ_BARRIER_STATE_SHIFT # Move barrier state bit 27924147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # to sign bit. 27934147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze bltz $at, .Lintrospection_field_array # If gray, load reference, mark. 27944147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze nop 27954147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .set pop 27964147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze jalr $zero, $ra # Otherwise, load-load barrier and return. 27974147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sync 27984147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze break # Padding to 8 instructions. 27994147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.endm 28004147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 28014147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.macro BRB_GC_ROOT_ENTRY root 28024147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze1: 28034147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#if defined(_MIPS_ARCH_MIPS32R6) 28044147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lapc $gp, .Lintrospection_exit_\root # $gp = exit point address. 28054147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#else 28064147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze addiu $gp, $t9, (.Lintrospection_exit_\root - 1b) # $gp = exit point address. 28074147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#endif 28084147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze bnez \root, .Lintrospection_common 28094147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze move $t8, \root # Move reference to $t8 for common code. 28104147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze jalr $zero, $ra # Return if null. 28114147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # The next instruction (from the following BRB_GC_ROOT_ENTRY) fills the delay slot. 28124147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # This instruction has no effect (actual NOP for the last entry; otherwise changes $gp, 28134147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # which is unused after that anyway). 28144147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.endm 28154147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 28164147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.macro BRB_FIELD_EXIT out 28174147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_exit_\out: 28184147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze jalr $zero, $ra 28194147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze move \out, $t8 # Return reference in expected register. 28204147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.endm 28214147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 28224147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.macro BRB_FIELD_EXIT_BREAK 28234147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze break 28244147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze break 28254147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.endm 28264147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 28274147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey FrunzeENTRY_NO_GP art_quick_read_barrier_mark_introspection 28284147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # Entry points for offsets/indices not fitting into int16_t and for variable indices. 28294147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $v0 28304147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $v1 28314147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $a0 28324147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $a1 28334147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $a2 28344147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $a3 28354147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $t0 28364147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $t1 28374147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $t2 28384147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $t3 28394147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $t4 28404147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $t5 28414147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $t6 28424147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $t7 28434147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $s2 28444147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $s3 28454147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $s4 28464147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $s5 28474147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $s6 28484147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $s7 28494147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_LONG_OFFSET_ENTRY $s8 28504147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 28514147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # Entry points for offsets/indices fitting into int16_t. 28524147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $v0 28534147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $v1 28544147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $a0 28554147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $a1 28564147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $a2 28574147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $a3 28584147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $t0 28594147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $t1 28604147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $t2 28614147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $t3 28624147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $t4 28634147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $t5 28644147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $t6 28654147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $t7 28664147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $s2 28674147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $s3 28684147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $s4 28694147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $s5 28704147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $s6 28714147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $s7 28724147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_SHORT_OFFSET_ENTRY $s8 28734147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 28744147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .global art_quick_read_barrier_mark_introspection_gc_roots 28754147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunzeart_quick_read_barrier_mark_introspection_gc_roots: 28764147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # Entry points for GC roots. 28774147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $v0 28784147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $v1 28794147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $a0 28804147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $a1 28814147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $a2 28824147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $a3 28834147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $t0 28844147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $t1 28854147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $t2 28864147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $t3 28874147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $t4 28884147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $t5 28894147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $t6 28904147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $t7 28914147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $s2 28924147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $s3 28934147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $s4 28944147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $s5 28954147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $s6 28964147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $s7 28974147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_GC_ROOT_ENTRY $s8 28984147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .global art_quick_read_barrier_mark_introspection_end_of_entries 28994147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunzeart_quick_read_barrier_mark_introspection_end_of_entries: 29004147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze nop # Fill the delay slot of the last BRB_GC_ROOT_ENTRY. 29014147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29024147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_throw_npe: 29034147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze b art_quick_throw_null_pointer_exception 29044147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze addiu $ra, $ra, 4 # Skip lw, make $ra point to lw's stack map. 29054147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29064147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .set push 29074147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .set noat 29084147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29094147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // Fields and array elements. 29104147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29114147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_field_array: 29124147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // Get the field/element address using $t8 and the offset from the lw instruction. 29134147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lh $at, 0($ra) # $ra points to lw: $at = field/element offset. 29144147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze addiu $ra, $ra, 4 + HEAP_POISON_INSTR_SIZE # Skip lw(+subu). 29154147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze addu $t8, $t8, $at # $t8 = field/element address. 29164147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29174147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // Calculate the address of the exit point, store it in $gp and load the reference into $t8. 29184147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lb $at, (-HEAP_POISON_INSTR_SIZE - 2)($ra) # $ra-HEAP_POISON_INSTR_SIZE-4 points to 29194147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze # "lw `out`, ...". 29204147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze andi $at, $at, 31 # Extract `out` from lw. 29214147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sll $at, $at, 3 # Multiply `out` by the exit point size (BRB_FIELD_EXIT* macros). 29224147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29234147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $t8, 0($t8) # $t8 = reference. 29244147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze UNPOISON_HEAP_REF $t8 29254147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29264147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // Return if null reference. 29274147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze bnez $t8, .Lintrospection_common 29284147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze addu $gp, $gp, $at # $gp = address of the exit point. 29294147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29304147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // Early return through the exit point. 29314147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_return_early: 29324147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze jalr $zero, $gp # Move $t8 to `out` and return. 29334147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze nop 29344147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29354147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // Code common for GC roots, fields and array elements. 29364147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29374147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_common: 29384147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // Check lock word for mark bit, if marked return. 29394147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $t9, MIRROR_OBJECT_LOCK_WORD_OFFSET($t8) 29404147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sll $at, $t9, 31 - LOCK_WORD_MARK_BIT_SHIFT # Move mark bit to sign bit. 29414147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze bltz $at, .Lintrospection_return_early 29424147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#if (LOCK_WORD_STATE_SHIFT != 30) || (LOCK_WORD_STATE_FORWARDING_ADDRESS != 3) 29434147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // The below code depends on the lock word state being in the highest bits 29444147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // and the "forwarding address" state having all bits set. 29454147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#error "Unexpected lock word state shift or forwarding address state value." 29464147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#endif 29474147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // Test that both the forwarding state bits are 1. 29484147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sll $at, $t9, 1 29494147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze and $at, $at, $t9 # Sign bit = 1 IFF both bits are 1. 29504147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze bgez $at, .Lintrospection_mark 29514147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze nop 29524147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29534147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .set pop 29544147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29554147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // Shift left by the forwarding address shift. This clears out the state bits since they are 29564147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // in the top 2 bits of the lock word. 29574147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze jalr $zero, $gp # Move $t8 to `out` and return. 29584147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sll $t8, $t9, LOCK_WORD_STATE_FORWARDING_ADDRESS_SHIFT 29594147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29604147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_mark: 29614147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // Partially set up the stack frame preserving only $ra. 29624147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze addiu $sp, $sp, -160 # Includes 16 bytes of space for argument registers $a0-$a3. 29634147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_adjust_cfa_offset 160 29644147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $ra, 156($sp) 29654147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 31, 156 29664147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29674147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // Set up $gp, clobbering $ra and using the branch delay slot for a useful instruction. 29684147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze bal 1f 29694147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $gp, 152($sp) # Preserve the exit point address. 29704147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze1: 29714147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cpload $ra 29724147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 29734147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // Finalize the stack frame and call. 29744147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $t7, 148($sp) 29754147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 15, 148 29764147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $t6, 144($sp) 29774147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 14, 144 29784147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $t5, 140($sp) 29794147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 13, 140 29804147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $t4, 136($sp) 29814147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 12, 136 29824147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $t3, 132($sp) 29834147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 11, 132 29844147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $t2, 128($sp) 29854147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 10, 128 29864147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $t1, 124($sp) 29874147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 9, 124 29884147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $t0, 120($sp) 29894147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 8, 120 29904147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $a3, 116($sp) 29914147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 7, 116 29924147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $a2, 112($sp) 29934147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 6, 112 29944147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $a1, 108($sp) 29954147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 5, 108 29964147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $a0, 104($sp) 29974147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 4, 104 29984147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $v1, 100($sp) 29994147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 3, 100 30004147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sw $v0, 96($sp) 30014147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_rel_offset 2, 96 30024147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 30034147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze la $t9, artReadBarrierMark 30044147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 30054147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sdc1 $f18, 88($sp) 30064147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sdc1 $f16, 80($sp) 30074147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sdc1 $f14, 72($sp) 30084147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sdc1 $f12, 64($sp) 30094147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sdc1 $f10, 56($sp) 30104147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sdc1 $f8, 48($sp) 30114147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sdc1 $f6, 40($sp) 30124147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sdc1 $f4, 32($sp) 30134147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sdc1 $f2, 24($sp) 30144147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze sdc1 $f0, 16($sp) 30154147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 30164147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze jalr $t9 # $v0 <- artReadBarrierMark(reference) 30174147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze move $a0, $t8 # Pass reference in $a0. 30184147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze move $t8, $v0 30194147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 30204147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $ra, 156($sp) 30214147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 31 30224147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $gp, 152($sp) # $gp = address of the exit point. 30234147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $t7, 148($sp) 30244147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 15 30254147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $t6, 144($sp) 30264147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 14 30274147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $t5, 140($sp) 30284147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 13 30294147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $t4, 136($sp) 30304147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 12 30314147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $t3, 132($sp) 30324147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 11 30334147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $t2, 128($sp) 30344147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 10 30354147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $t1, 124($sp) 30364147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 9 30374147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $t0, 120($sp) 30384147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 8 30394147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $a3, 116($sp) 30404147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 7 30414147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $a2, 112($sp) 30424147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 6 30434147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $a1, 108($sp) 30444147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 5 30454147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $a0, 104($sp) 30464147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 4 30474147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $v1, 100($sp) 30484147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 3 30494147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze lw $v0, 96($sp) 30504147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_restore 2 30514147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 30524147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze ldc1 $f18, 88($sp) 30534147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze ldc1 $f16, 80($sp) 30544147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze ldc1 $f14, 72($sp) 30554147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze ldc1 $f12, 64($sp) 30564147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze ldc1 $f10, 56($sp) 30574147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze ldc1 $f8, 48($sp) 30584147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze ldc1 $f6, 40($sp) 30594147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze ldc1 $f4, 32($sp) 30604147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze ldc1 $f2, 24($sp) 30614147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze ldc1 $f0, 16($sp) 30624147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 30634147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze // Return through the exit point. 30644147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze jalr $zero, $gp # Move $t8 to `out` and return. 30654147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze addiu $sp, $sp, 160 30664147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze .cfi_adjust_cfa_offset -160 30674147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 30684147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_exits: 30694147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT_BREAK 30704147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT_BREAK 30714147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $v0 30724147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $v1 30734147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $a0 30744147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $a1 30754147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $a2 30764147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $a3 30774147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $t0 30784147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $t1 30794147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $t2 30804147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $t3 30814147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $t4 30824147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $t5 30834147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $t6 30844147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $t7 30854147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT_BREAK 30864147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT_BREAK 30874147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $s2 30884147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $s3 30894147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $s4 30904147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $s5 30914147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $s6 30924147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $s7 30934147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT_BREAK 30944147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT_BREAK 30954147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT_BREAK 30964147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT_BREAK 30974147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT_BREAK 30984147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT_BREAK 30994147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT $s8 31004147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze BRB_FIELD_EXIT_BREAK 31014147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey FrunzeEND art_quick_read_barrier_mark_introspection 31024147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze 3103ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.extern artInvokePolymorphic 3104ac141397dc29189ad2b2df41f8d4312246beec60Orion HodsonENTRY art_quick_invoke_polymorphic 3105ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson SETUP_SAVE_REFS_AND_ARGS_FRAME 3106ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson move $a2, rSELF # Make $a2 an alias for the current Thread. 3107c480b9853ac7be67581cd26c49c2ed7426ae68a4Alexey Frunze addiu $a3, $sp, ARG_SLOT_SIZE # Make $a3 a pointer to the saved frame context. 3108ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson sw $zero, 20($sp) # Initialize JValue result. 3109ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson sw $zero, 16($sp) 3110ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson la $t9, artInvokePolymorphic 3111ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson jalr $t9 # (result, receiver, Thread*, context) 3112c480b9853ac7be67581cd26c49c2ed7426ae68a4Alexey Frunze addiu $a0, $sp, 16 # Make $a0 a pointer to the JValue result 3113ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.macro MATCH_RETURN_TYPE c, handler 3114ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson li $t0, \c 3115ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson beq $v0, $t0, \handler 3116ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.endm 3117ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson MATCH_RETURN_TYPE 'V', .Lcleanup_and_return 3118ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson MATCH_RETURN_TYPE 'L', .Lstore_int_result 3119ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson MATCH_RETURN_TYPE 'I', .Lstore_int_result 3120ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson MATCH_RETURN_TYPE 'J', .Lstore_long_result 3121ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson MATCH_RETURN_TYPE 'B', .Lstore_int_result 3122ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson MATCH_RETURN_TYPE 'C', .Lstore_char_result 3123ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson MATCH_RETURN_TYPE 'D', .Lstore_double_result 3124ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson MATCH_RETURN_TYPE 'F', .Lstore_float_result 3125ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson MATCH_RETURN_TYPE 'S', .Lstore_int_result 3126c480b9853ac7be67581cd26c49c2ed7426ae68a4Alexey Frunze MATCH_RETURN_TYPE 'Z', .Lstore_boolean_result 3127ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.purgem MATCH_RETURN_TYPE 3128ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson nop 3129ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson b .Lcleanup_and_return 3130ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson nop 3131ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lstore_boolean_result: 3132ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson b .Lcleanup_and_return 3133c480b9853ac7be67581cd26c49c2ed7426ae68a4Alexey Frunze lbu $v0, 16($sp) # Move byte from JValue result to return value register. 3134ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lstore_char_result: 3135ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson b .Lcleanup_and_return 3136c480b9853ac7be67581cd26c49c2ed7426ae68a4Alexey Frunze lhu $v0, 16($sp) # Move char from JValue result to return value register. 3137ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lstore_double_result: 3138ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lstore_float_result: 3139ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson LDu $f0, $f1, 16, $sp, $t0 # Move double/float from JValue result to return value register. 3140ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson b .Lcleanup_and_return 3141ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson nop 3142ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lstore_long_result: 3143ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson lw $v1, 20($sp) # Move upper bits from JValue result to return value register. 3144ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson // Fall-through for lower bits. 3145ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lstore_int_result: 3146ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson lw $v0, 16($sp) # Move lower bits from JValue result to return value register. 3147ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson // Fall-through to clean up and return. 3148ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lcleanup_and_return: 3149ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson lw $t7, THREAD_EXCEPTION_OFFSET(rSELF) # Load Thread::Current()->exception_ 3150ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson RESTORE_SAVE_REFS_AND_ARGS_FRAME 3151ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson bnez $t7, 1f # Success if no exception is pending. 3152ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson nop 3153ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson jalr $zero, $ra 3154ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson nop 3155ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson1: 3156ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson DELIVER_PENDING_EXCEPTION 3157ac141397dc29189ad2b2df41f8d4312246beec60Orion HodsonEND art_quick_invoke_polymorphic 3158