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
40715f43e1553330bc804cea2951be195473dc343dChris Larsen    addiu  $sp, $sp, -112
41715f43e1553330bc804cea2951be195473dc343dChris Larsen    .cfi_adjust_cfa_offset 112
425c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe
435c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe     // Ugly compile-time check, but we only have the preprocessor.
44715f43e1553330bc804cea2951be195473dc343dChris Larsen#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVES != 112)
45fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko#error "FRAME_SIZE_SAVE_ALL_CALLEE_SAVES(MIPS) size not as expected."
465c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif
475c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe
48715f43e1553330bc804cea2951be195473dc343dChris Larsen    sw     $ra, 108($sp)
49715f43e1553330bc804cea2951be195473dc343dChris Larsen    .cfi_rel_offset 31, 108
50715f43e1553330bc804cea2951be195473dc343dChris Larsen    sw     $s8, 104($sp)
51715f43e1553330bc804cea2951be195473dc343dChris Larsen    .cfi_rel_offset 30, 104
52715f43e1553330bc804cea2951be195473dc343dChris Larsen    sw     $gp, 100($sp)
53715f43e1553330bc804cea2951be195473dc343dChris Larsen    .cfi_rel_offset 28, 100
54715f43e1553330bc804cea2951be195473dc343dChris Larsen    sw     $s7, 96($sp)
55715f43e1553330bc804cea2951be195473dc343dChris Larsen    .cfi_rel_offset 23, 96
56715f43e1553330bc804cea2951be195473dc343dChris Larsen    sw     $s6, 92($sp)
57715f43e1553330bc804cea2951be195473dc343dChris Larsen    .cfi_rel_offset 22, 92
58715f43e1553330bc804cea2951be195473dc343dChris Larsen    sw     $s5, 88($sp)
59715f43e1553330bc804cea2951be195473dc343dChris Larsen    .cfi_rel_offset 21, 88
60715f43e1553330bc804cea2951be195473dc343dChris Larsen    sw     $s4, 84($sp)
61715f43e1553330bc804cea2951be195473dc343dChris Larsen    .cfi_rel_offset 20, 84
62715f43e1553330bc804cea2951be195473dc343dChris Larsen    sw     $s3, 80($sp)
63715f43e1553330bc804cea2951be195473dc343dChris Larsen    .cfi_rel_offset 19, 80
64715f43e1553330bc804cea2951be195473dc343dChris Larsen    sw     $s2, 76($sp)
65715f43e1553330bc804cea2951be195473dc343dChris Larsen    .cfi_rel_offset 18, 76
66715f43e1553330bc804cea2951be195473dc343dChris Larsen    sw     $s1, 72($sp)
67715f43e1553330bc804cea2951be195473dc343dChris Larsen    .cfi_rel_offset 17, 72
68715f43e1553330bc804cea2951be195473dc343dChris Larsen    sw     $s0, 68($sp)
69715f43e1553330bc804cea2951be195473dc343dChris Larsen    .cfi_rel_offset 16, 68
70715f43e1553330bc804cea2951be195473dc343dChris Larsen    // 4-byte placeholder for register $zero, serving for alignment
71715f43e1553330bc804cea2951be195473dc343dChris Larsen    // of the following double precision floating point registers.
72715f43e1553330bc804cea2951be195473dc343dChris Larsen
73715f43e1553330bc804cea2951be195473dc343dChris Larsen    CHECK_ALIGNMENT $sp, $t1
74715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f30, 56($sp)
75715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f28, 48($sp)
76715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f26, 40($sp)
77715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f24, 32($sp)
78715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f22, 24($sp)
79715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f20, 16($sp)
80715f43e1553330bc804cea2951be195473dc343dChris Larsen
81715f43e1553330bc804cea2951be195473dc343dChris Larsen    # 1 word for holding Method* plus 12 bytes padding to keep contents of SP
82715f43e1553330bc804cea2951be195473dc343dChris Larsen    # a multiple of 16.
831d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers
844af77b7636fe98aae443b46a241fd9a29f16e291Douglas Leung    lw $t0, %got(_ZN3art7Runtime9instance_E)($gp)
854af77b7636fe98aae443b46a241fd9a29f16e291Douglas Leung    lw $t0, 0($t0)
86fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    lw $t0, RUNTIME_SAVE_ALL_CALLEE_SAVES_METHOD_OFFSET($t0)
871d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    sw $t0, 0($sp)                                # Place Method* at bottom of stack.
881d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF)  # Place sp in Thread::Current()->top_quick_frame.
89735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu  $sp, $sp, -ARG_SLOT_SIZE               # reserve argument slots on the stack
90735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_adjust_cfa_offset ARG_SLOT_SIZE
915bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm
925bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
935bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
945bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * Macro that sets up the callee save frame to conform with
95fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko     * Runtime::CreateCalleeSaveMethod(kSaveRefsOnly). Restoration assumes non-moving GC.
965bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * Does not include rSUSPEND or rSELF
97735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung     * callee-save: $s2-$s8 + $gp + $ra, 9 total + 2 words padding + 1 word to hold Method*
98735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung     * Clobbers $t0 and $sp
99735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung     * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots.
100fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko     * Reserves FRAME_SIZE_SAVE_REFS_ONLY + ARG_SLOT_SIZE bytes on the stack
1015bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
102fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko.macro SETUP_SAVE_REFS_ONLY_FRAME
103735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu  $sp, $sp, -48
104735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_adjust_cfa_offset 48
1055c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe
1065c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe    // Ugly compile-time check, but we only have the preprocessor.
107fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko#if (FRAME_SIZE_SAVE_REFS_ONLY != 48)
108fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko#error "FRAME_SIZE_SAVE_REFS_ONLY(MIPS) size not as expected."
1095c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif
1105c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe
111735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    sw     $ra, 44($sp)
112735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_rel_offset 31, 44
113735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    sw     $s8, 40($sp)
114735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_rel_offset 30, 40
115735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    sw     $gp, 36($sp)
116735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_rel_offset 28, 36
117735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    sw     $s7, 32($sp)
118735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_rel_offset 23, 32
119735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    sw     $s6, 28($sp)
120735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_rel_offset 22, 28
121735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    sw     $s5, 24($sp)
122735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_rel_offset 21, 24
123735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    sw     $s4, 20($sp)
124735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_rel_offset 20, 20
125735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    sw     $s3, 16($sp)
126735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_rel_offset 19, 16
127735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    sw     $s2, 12($sp)
128735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_rel_offset 18, 12
129735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    # 2 words for alignment and bottom word will hold Method*
1301d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers
1314af77b7636fe98aae443b46a241fd9a29f16e291Douglas Leung    lw $t0, %got(_ZN3art7Runtime9instance_E)($gp)
1324af77b7636fe98aae443b46a241fd9a29f16e291Douglas Leung    lw $t0, 0($t0)
133fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    lw $t0, RUNTIME_SAVE_REFS_ONLY_METHOD_OFFSET($t0)
1341d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    sw $t0, 0($sp)                                # Place Method* at bottom of stack.
1351d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF)  # Place sp in Thread::Current()->top_quick_frame.
136735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu  $sp, $sp, -ARG_SLOT_SIZE               # reserve argument slots on the stack
137735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_adjust_cfa_offset ARG_SLOT_SIZE
1385bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm
1395bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
140fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko.macro RESTORE_SAVE_REFS_ONLY_FRAME
141735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu  $sp, $sp, ARG_SLOT_SIZE                # remove argument slots on the stack
142735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_adjust_cfa_offset -ARG_SLOT_SIZE
143735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw     $ra, 44($sp)
144bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 31
145735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw     $s8, 40($sp)
146bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 30
147735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw     $gp, 36($sp)
148bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 28
149735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw     $s7, 32($sp)
150bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 23
151735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw     $s6, 28($sp)
152bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 22
153735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw     $s5, 24($sp)
154bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 21
155735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw     $s4, 20($sp)
156bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 20
157735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw     $s3, 16($sp)
158bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 19
159735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw     $s2, 12($sp)
160bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 18
161735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu  $sp, $sp, 48
162735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_adjust_cfa_offset -48
1635bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm
1645bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
165fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko.macro RESTORE_SAVE_REFS_ONLY_FRAME_AND_RETURN
166fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    RESTORE_SAVE_REFS_ONLY_FRAME
1678d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr   $zero, $ra
168735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    nop
1695bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm
1705bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
1715bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
172279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze     * Individually usable part of macro SETUP_SAVE_REFS_AND_ARGS_FRAME_REGISTERS_ONLY.
173279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze     */
174279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze.macro SETUP_SAVE_REFS_AND_ARGS_FRAME_S4_THRU_S8
175279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $s8, 104($sp)
176279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_rel_offset 30, 104
177279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $s7, 96($sp)
178279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_rel_offset 23, 96
179279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $s6, 92($sp)
180279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_rel_offset 22, 92
181279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $s5, 88($sp)
182279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_rel_offset 21, 88
183279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $s4, 84($sp)
184279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_rel_offset 20, 84
185279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze.endm
186279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze
187279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    /*
1885bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * Macro that sets up the callee save frame to conform with
189fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko     * Runtime::CreateCalleeSaveMethod(kSaveRefsAndArgs).
1901b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze     * callee-save: $a1-$a3, $t0-$t1, $s2-$s8, $gp, $ra, $f8-$f19
1911b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze     *              (26 total + 1 word padding + method*)
1925bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
193279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze.macro SETUP_SAVE_REFS_AND_ARGS_FRAME_REGISTERS_ONLY save_s4_thru_s8=1
194279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    addiu   $sp, $sp, -112
1951b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .cfi_adjust_cfa_offset 112
1965c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe
1975c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe    // Ugly compile-time check, but we only have the preprocessor.
1981b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#if (FRAME_SIZE_SAVE_REFS_AND_ARGS != 112)
199fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko#error "FRAME_SIZE_SAVE_REFS_AND_ARGS(MIPS) size not as expected."
2005c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif
2015c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe
202279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $ra, 108($sp)
2031b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .cfi_rel_offset 31, 108
204279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $gp, 100($sp)
2051b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .cfi_rel_offset 28, 100
206279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .if \save_s4_thru_s8
207279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      SETUP_SAVE_REFS_AND_ARGS_FRAME_S4_THRU_S8
208279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .endif
209279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $s3, 80($sp)
2101b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .cfi_rel_offset 19, 80
211279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $s2, 76($sp)
2121b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .cfi_rel_offset 18, 76
213279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $t1, 72($sp)
2141b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .cfi_rel_offset 9, 72
215279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $t0, 68($sp)
2161b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .cfi_rel_offset 8, 68
217279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $a3, 64($sp)
2181b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .cfi_rel_offset 7, 64
219279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $a2, 60($sp)
2201b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .cfi_rel_offset 6, 60
221279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sw      $a1, 56($sp)
2221b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .cfi_rel_offset 5, 56
223715f43e1553330bc804cea2951be195473dc343dChris Larsen    CHECK_ALIGNMENT $sp, $t8
224715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1    $f18, 48($sp)
225715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1    $f16, 40($sp)
226715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1    $f14, 32($sp)
227715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1    $f12, 24($sp)
228715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1    $f10, 16($sp)
229715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1    $f8,   8($sp)
230fa147e22a73c6df166b08a2f71f9c9b52b09d17cjeffhao    # bottom will hold Method*
231735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung.endm
2321d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers
233735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    /*
234735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung     * Macro that sets up the callee save frame to conform with
235fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko     * Runtime::CreateCalleeSaveMethod(kSaveRefsAndArgs). Restoration assumes non-moving GC.
2361b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze     * callee-save: $a1-$a3, $t0-$t1, $s2-$s8, $gp, $ra, $f8-$f19
2371b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze     *              (26 total + 1 word padding + method*)
238735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung     * Clobbers $t0 and $sp
239735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung     * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots.
240fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko     * Reserves FRAME_SIZE_SAVE_REFS_AND_ARGS + ARG_SLOT_SIZE bytes on the stack
241735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung     */
242279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze.macro SETUP_SAVE_REFS_AND_ARGS_FRAME save_s4_thru_s8_only=0
243279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .if \save_s4_thru_s8_only
244279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      // It is expected that `SETUP_SAVE_REFS_AND_ARGS_FRAME_REGISTERS_ONLY /* save_s4_thru_s8 */ 0`
245279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      // has been done prior to `SETUP_SAVE_REFS_AND_ARGS_FRAME /* save_s4_thru_s8_only */ 1`.
246279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      SETUP_SAVE_REFS_AND_ARGS_FRAME_S4_THRU_S8
247279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .else
248279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      SETUP_SAVE_REFS_AND_ARGS_FRAME_REGISTERS_ONLY
249279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .endif
2504af77b7636fe98aae443b46a241fd9a29f16e291Douglas Leung    lw $t0, %got(_ZN3art7Runtime9instance_E)($gp)
2514af77b7636fe98aae443b46a241fd9a29f16e291Douglas Leung    lw $t0, 0($t0)
252fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    lw $t0, RUNTIME_SAVE_REFS_AND_ARGS_METHOD_OFFSET($t0)
2531d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    sw $t0, 0($sp)                                # Place Method* at bottom of stack.
2541d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF)  # Place sp in Thread::Current()->top_quick_frame.
255735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu  $sp, $sp, -ARG_SLOT_SIZE               # reserve argument slots on the stack
256735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_adjust_cfa_offset ARG_SLOT_SIZE
257735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung.endm
258735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung
259735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    /*
260735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung     * Macro that sets up the callee save frame to conform with
261fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko     * Runtime::CreateCalleeSaveMethod(kSaveRefsAndArgs). Restoration assumes non-moving GC.
2621b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze     * callee-save: $a1-$a3, $t0-$t1, $s2-$s8, $gp, $ra, $f8-$f19
2631b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze     *              (26 total + 1 word padding + method*)
264735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung     * Clobbers $sp
265735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung     * Use $a0 as the Method* and loads it into bottom of stack.
266735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung     * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots.
267fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko     * Reserves FRAME_SIZE_SAVE_REFS_AND_ARGS + ARG_SLOT_SIZE bytes on the stack
268735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung     */
269fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko.macro SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_A0
270fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_AND_ARGS_FRAME_REGISTERS_ONLY
271735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    sw $a0, 0($sp)                                # Place Method* at bottom of stack.
272735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF)  # Place sp in Thread::Current()->top_quick_frame.
273735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu  $sp, $sp, -ARG_SLOT_SIZE               # reserve argument slots on the stack
274735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .cfi_adjust_cfa_offset ARG_SLOT_SIZE
2755bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm
2765bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
277279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    /*
278279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze     * Individually usable part of macro RESTORE_SAVE_REFS_AND_ARGS_FRAME.
279279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze     */
280279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze.macro RESTORE_SAVE_REFS_AND_ARGS_FRAME_GP
281279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $gp, 100($sp)
282bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 28
283279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze.endm
284279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze
285279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    /*
286279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze     * Individually usable part of macro RESTORE_SAVE_REFS_AND_ARGS_FRAME.
287279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze     */
288279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze.macro RESTORE_SAVE_REFS_AND_ARGS_FRAME_A1
289279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $a1, 56($sp)
290279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_restore 5
291279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze.endm
292279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze
293279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze.macro RESTORE_SAVE_REFS_AND_ARGS_FRAME restore_s4_thru_s8=1, remove_arg_slots=1
294279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .if \remove_arg_slots
295279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      addiu $sp, $sp, ARG_SLOT_SIZE                 # Remove argument slots from the stack.
296279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      .cfi_adjust_cfa_offset -ARG_SLOT_SIZE
297279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .endif
298279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $ra, 108($sp)
299279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_restore 31
300279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .if \restore_s4_thru_s8
301279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      lw    $s8, 104($sp)
302279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      .cfi_restore 30
303279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .endif
304279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    RESTORE_SAVE_REFS_AND_ARGS_FRAME_GP
305279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .if \restore_s4_thru_s8
306279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      lw    $s7, 96($sp)
307279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      .cfi_restore 23
308279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      lw    $s6, 92($sp)
309279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      .cfi_restore 22
310279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      lw    $s5, 88($sp)
311279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      .cfi_restore 21
312279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      lw    $s4, 84($sp)
313279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze      .cfi_restore 20
314279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .endif
315279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $s3, 80($sp)
316bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 19
317279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $s2, 76($sp)
318bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 18
319279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $t1, 72($sp)
3201b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .cfi_restore 9
321279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $t0, 68($sp)
3221b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .cfi_restore 8
323279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $a3, 64($sp)
324bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 7
325279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $a2, 60($sp)
326bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 6
327279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    RESTORE_SAVE_REFS_AND_ARGS_FRAME_A1
328715f43e1553330bc804cea2951be195473dc343dChris Larsen    CHECK_ALIGNMENT $sp, $t8
329715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f18, 48($sp)
330715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f16, 40($sp)
331715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f14, 32($sp)
332715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f12, 24($sp)
333715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f10, 16($sp)
334715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f8,   8($sp)
335279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    addiu   $sp, $sp, 112                           # Pop frame.
3361b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .cfi_adjust_cfa_offset -112
3375bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm
3385bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
3395bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
340952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko     * Macro that sets up the callee save frame to conform with
341952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko     * Runtime::CreateCalleeSaveMethod(kSaveEverything).
3423b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko     * when the $sp has already been decremented by FRAME_SIZE_SAVE_EVERYTHING.
343952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko     * Callee-save: $at, $v0-$v1, $a0-$a3, $t0-$t7, $s0-$s7, $t8-$t9, $gp, $fp $ra, $f0-$f31;
344952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko     *              28(GPR)+ 32(FPR) + 3 words for padding and 1 word for Method*
345952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko     * Clobbers $t0 and $t1.
346952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko     * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots.
347fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko     * Reserves FRAME_SIZE_SAVE_EVERYTHING + ARG_SLOT_SIZE bytes on the stack.
348952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko     * This macro sets up $gp; entrypoints using it should start with ENTRY_NO_GP.
349952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko     */
35019428ad0cc3494714470328fb6c74fa3e92a187bAlexey Frunze.macro SETUP_SAVE_EVERYTHING_FRAME_DECREMENTED_SP runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET
351952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko     // Ugly compile-time check, but we only have the preprocessor.
352fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko#if (FRAME_SIZE_SAVE_EVERYTHING != 256)
353fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko#error "FRAME_SIZE_SAVE_EVERYTHING(MIPS) size not as expected."
354952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko#endif
355952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko
356952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $ra, 252($sp)
357952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 31, 252
358952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $fp, 248($sp)
359952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 30, 248
360952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $gp, 244($sp)
361952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 28, 244
362952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $t9, 240($sp)
363952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 25, 240
364952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $t8, 236($sp)
365952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 24, 236
366952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $s7, 232($sp)
367952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 23, 232
368952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $s6, 228($sp)
369952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 22, 228
370952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $s5, 224($sp)
371952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 21, 224
372952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $s4, 220($sp)
373952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 20, 220
374952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $s3, 216($sp)
375952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 19, 216
376952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $s2, 212($sp)
377952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 18, 212
378952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $s1, 208($sp)
379952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 17, 208
380952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $s0, 204($sp)
381952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 16, 204
382952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $t7, 200($sp)
383952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 15, 200
384952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $t6, 196($sp)
385952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 14, 196
386952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $t5, 192($sp)
387952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 13, 192
388952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $t4, 188($sp)
389952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 12, 188
390952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $t3, 184($sp)
391952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 11, 184
392952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $t2, 180($sp)
393952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 10, 180
394952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $t1, 176($sp)
395952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 9, 176
396952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $t0, 172($sp)
397952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 8, 172
398952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $a3, 168($sp)
399952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 7, 168
400952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $a2, 164($sp)
401952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 6, 164
402952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $a1, 160($sp)
403952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 5, 160
404952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $a0, 156($sp)
405952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 4, 156
406952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $v1, 152($sp)
407952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 3, 152
408952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $v0, 148($sp)
409952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 2, 148
410952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko
411952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    // Set up $gp, clobbering $ra and using the branch delay slot for a useful instruction.
412952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    bal 1f
4132e42cf12e7bd62c5455a9c5ac0fc072de0f31884Goran Jakovljevic    .set push
4142e42cf12e7bd62c5455a9c5ac0fc072de0f31884Goran Jakovljevic    .set noat
415952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw     $at, 144($sp)
416952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_rel_offset 1, 144
4172e42cf12e7bd62c5455a9c5ac0fc072de0f31884Goran Jakovljevic    .set pop
418952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko1:
419952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cpload $ra
420952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko
421715f43e1553330bc804cea2951be195473dc343dChris Larsen    CHECK_ALIGNMENT $sp, $t1
422715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f30, 136($sp)
423715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f28, 128($sp)
424715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f26, 120($sp)
425715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f24, 112($sp)
426715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f22, 104($sp)
427715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f20,  96($sp)
428715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f18,  88($sp)
429715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f16,  80($sp)
430715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f14,  72($sp)
431715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f12,  64($sp)
432715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f10,  56($sp)
433715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f8,   48($sp)
434715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f6,   40($sp)
435715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f4,   32($sp)
436715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f2,   24($sp)
437715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f0,   16($sp)
438952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko
439952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    # 3 words padding and 1 word for holding Method*
440952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko
441952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw $t0, %got(_ZN3art7Runtime9instance_E)($gp)
442952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw $t0, 0($t0)
44319428ad0cc3494714470328fb6c74fa3e92a187bAlexey Frunze    lw $t0, \runtime_method_offset($t0)
444952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw $t0, 0($sp)                                # Place Method* at bottom of stack.
445952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF)  # Place sp in Thread::Current()->top_quick_frame.
446952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    addiu  $sp, $sp, -ARG_SLOT_SIZE               # reserve argument slots on the stack
447952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_adjust_cfa_offset ARG_SLOT_SIZE
448952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko.endm
449952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko
4503b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko    /*
4513b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko     * Macro that sets up the callee save frame to conform with
4523b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko     * Runtime::CreateCalleeSaveMethod(kSaveEverything).
4533b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko     * Callee-save: $at, $v0-$v1, $a0-$a3, $t0-$t7, $s0-$s7, $t8-$t9, $gp, $fp $ra, $f0-$f31;
4543b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko     *              28(GPR)+ 32(FPR) + 3 words for padding and 1 word for Method*
4553b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko     * Clobbers $t0 and $t1.
4563b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko     * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots.
4573b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko     * Reserves FRAME_SIZE_SAVE_EVERYTHING + ARG_SLOT_SIZE bytes on the stack.
4583b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko     * This macro sets up $gp; entrypoints using it should start with ENTRY_NO_GP.
4593b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko     */
46019428ad0cc3494714470328fb6c74fa3e92a187bAlexey Frunze.macro SETUP_SAVE_EVERYTHING_FRAME runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET
4613b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko    addiu  $sp, $sp, -(FRAME_SIZE_SAVE_EVERYTHING)
4623b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko    .cfi_adjust_cfa_offset (FRAME_SIZE_SAVE_EVERYTHING)
46319428ad0cc3494714470328fb6c74fa3e92a187bAlexey Frunze    SETUP_SAVE_EVERYTHING_FRAME_DECREMENTED_SP \runtime_method_offset
4643b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko.endm
4653b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko
466c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze.macro RESTORE_SAVE_EVERYTHING_FRAME restore_a0=1
467952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    addiu  $sp, $sp, ARG_SLOT_SIZE                # remove argument slots on the stack
468952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_adjust_cfa_offset -ARG_SLOT_SIZE
469952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko
470715f43e1553330bc804cea2951be195473dc343dChris Larsen    CHECK_ALIGNMENT $sp, $t1
471715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f30, 136($sp)
472715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f28, 128($sp)
473715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f26, 120($sp)
474715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f24, 112($sp)
475715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f22, 104($sp)
476715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f20,  96($sp)
477715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f18,  88($sp)
478715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f16,  80($sp)
479715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f14,  72($sp)
480715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f12,  64($sp)
481715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f10,  56($sp)
482715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f8,   48($sp)
483715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f6,   40($sp)
484715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f4,   32($sp)
485715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f2,   24($sp)
486715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1   $f0,   16($sp)
487952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko
488952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $ra, 252($sp)
489952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 31
490952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $fp, 248($sp)
491952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 30
492952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $gp, 244($sp)
493952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 28
494952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $t9, 240($sp)
495952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 25
496952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $t8, 236($sp)
497952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 24
498952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $s7, 232($sp)
499952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 23
500952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $s6, 228($sp)
501952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 22
502952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $s5, 224($sp)
503952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 21
504952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $s4, 220($sp)
505952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 20
506952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $s3, 216($sp)
507952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 19
508952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $s2, 212($sp)
509952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 18
510952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $s1, 208($sp)
511952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 17
512952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $s0, 204($sp)
513952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 16
514952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $t7, 200($sp)
515952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 15
516952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $t6, 196($sp)
517952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 14
518952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $t5, 192($sp)
519952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 13
520952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $t4, 188($sp)
521952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 12
522952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $t3, 184($sp)
523952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 11
524952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $t2, 180($sp)
525952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 10
526952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $t1, 176($sp)
527952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 9
528952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $t0, 172($sp)
529952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 8
530952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $a3, 168($sp)
531952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 7
532952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $a2, 164($sp)
533952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 6
534952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $a1, 160($sp)
535952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 5
536c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    .if \restore_a0
537952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $a0, 156($sp)
538952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 4
539c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    .endif
540952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $v1, 152($sp)
541952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 3
542952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $v0, 148($sp)
543952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 2
5442e42cf12e7bd62c5455a9c5ac0fc072de0f31884Goran Jakovljevic    .set push
5452e42cf12e7bd62c5455a9c5ac0fc072de0f31884Goran Jakovljevic    .set noat
546952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    lw     $at, 144($sp)
547952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_restore 1
5482e42cf12e7bd62c5455a9c5ac0fc072de0f31884Goran Jakovljevic    .set pop
549952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko
550952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    addiu  $sp, $sp, 256            # pop frame
551952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    .cfi_adjust_cfa_offset -256
552952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko.endm
553952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko
554952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    /*
555c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze     * Macro that calls through to artDeliverPendingExceptionFromCode, where the pending
556c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze     * exception is Thread::Current()->exception_ when the runtime method frame is ready.
557c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze     * Requires $gp properly set up.
5585bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
559c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze.macro DELIVER_PENDING_EXCEPTION_FRAME_READY
5608161c0336b97e11e02c000af357f8f40de2e23e4jeffhao    la      $t9, artDeliverPendingExceptionFromCode
5618d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr    $zero, $t9                   # artDeliverPendingExceptionFromCode(Thread*)
5621d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    move    $a0, rSELF                   # pass Thread::Current
5635bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm
5645bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
565c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    /*
566c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze     * Macro that calls through to artDeliverPendingExceptionFromCode, where the pending
567c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze     * exception is Thread::Current()->exception_.
568c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze     * Requires $gp properly set up.
569c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze     */
570c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze.macro DELIVER_PENDING_EXCEPTION
571c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    SETUP_SAVE_ALL_CALLEE_SAVES_FRAME    # save callee saves for throw
572c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    DELIVER_PENDING_EXCEPTION_FRAME_READY
573c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze.endm
574c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze
5755bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.macro RETURN_IF_NO_EXCEPTION
5767fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw     $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
577fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    RESTORE_SAVE_REFS_ONLY_FRAME
5788161c0336b97e11e02c000af357f8f40de2e23e4jeffhao    bnez   $t0, 1f                       # success if no exception is pending
5795bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    nop
5808d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr   $zero, $ra
5815bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    nop
5825bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee1:
5835bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    DELIVER_PENDING_EXCEPTION
5845bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm
5855bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
5865bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.macro RETURN_IF_ZERO
587fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    RESTORE_SAVE_REFS_ONLY_FRAME
5887fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    bnez   $v0, 1f                       # success?
5895bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    nop
5908d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr   $zero, $ra                    # return on success
5915bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    nop
5925bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee1:
5935bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    DELIVER_PENDING_EXCEPTION
5945bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm
5955bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
5961cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe.macro RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
597fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    RESTORE_SAVE_REFS_ONLY_FRAME
5987fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    beqz   $v0, 1f                       # success?
5995bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    nop
6008d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr   $zero, $ra                    # return on success
6015bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    nop
6025bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee1:
6035bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    DELIVER_PENDING_EXCEPTION
6045bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm
6055bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
6065bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
6073bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic     * On stack replacement stub.
6083bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic     * On entry:
6093bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic     *   a0 = stack to copy
6103bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic     *   a1 = size of stack
6113bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic     *   a2 = pc to call
6123bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic     *   a3 = JValue* result
6133bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic     *   [sp + 16] = shorty
6143bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic     *   [sp + 20] = thread
6153bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic     */
6163bc13817a19e36f3833bb44624ef86800892eaadGoran JakovljevicENTRY art_quick_osr_stub
6173bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    // Save callee general purpose registers, RA and GP.
6183bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    addiu  $sp, $sp, -48
6193bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_adjust_cfa_offset 48
6203bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $ra, 44($sp)
6213bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_rel_offset 31, 44
6223bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $s8, 40($sp)
6233bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_rel_offset 30, 40
6243bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $gp, 36($sp)
6253bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_rel_offset 28, 36
6263bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $s7, 32($sp)
6273bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_rel_offset 23, 32
6283bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $s6, 28($sp)
6293bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_rel_offset 22, 28
6303bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $s5, 24($sp)
6313bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_rel_offset 21, 24
6323bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $s4, 20($sp)
6333bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_rel_offset 20, 20
6343bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $s3, 16($sp)
6353bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_rel_offset 19, 16
6363bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $s2, 12($sp)
6373bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_rel_offset 18, 12
6383bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $s1, 8($sp)
6393bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_rel_offset 17, 8
6403bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $s0, 4($sp)
6413bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_rel_offset 16, 4
6423bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic
6433bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    move   $s8, $sp                        # Save the stack pointer
6443bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    move   $s7, $a1                        # Save size of stack
6453bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    move   $s6, $a2                        # Save the pc to call
6463bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     rSELF, 48+20($sp)               # Save managed thread pointer into rSELF
6473bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    addiu  $t0, $sp, -12                   # Reserve space for stack pointer,
6483bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic                                           #    JValue* result, and ArtMethod* slot.
6493bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    srl    $t0, $t0, 4                     # Align stack pointer to 16 bytes
6503bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sll    $sp, $t0, 4                     # Update stack pointer
6513bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $s8, 4($sp)                     # Save old stack pointer
6523bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $a3, 8($sp)                     # Save JValue* result
6533bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $zero, 0($sp)                   # Store null for ArtMethod* at bottom of frame
6543bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    subu   $sp, $a1                        # Reserve space for callee stack
6553bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    move   $a2, $a1
6563bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    move   $a1, $a0
6573bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    move   $a0, $sp
6583bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    la     $t9, memcpy
6593bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    jalr   $t9                             # memcpy (dest a0, src a1, bytes a2)
6603bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    addiu  $sp, $sp, -16                   # make space for argument slots for memcpy
6613bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    bal    .Losr_entry                     # Call the method
6623bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    addiu  $sp, $sp, 16                    # restore stack after memcpy
6633bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $a2, 8($sp)                     # Restore JValue* result
6643bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $sp, 4($sp)                     # Restore saved stack pointer
6653bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $a0, 48+16($sp)                 # load shorty
6663bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lbu    $a0, 0($a0)                     # load return type
6673bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    li     $a1, 'D'                        # put char 'D' into a1
6683bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    beq    $a0, $a1, .Losr_fp_result       # Test if result type char == 'D'
6693bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    li     $a1, 'F'                        # put char 'F' into a1
6703bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    beq    $a0, $a1, .Losr_fp_result       # Test if result type char == 'F'
6713bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    nop
6723bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $v0, 0($a2)
6733bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    b      .Losr_exit
6743bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $v1, 4($a2)                     # store v0/v1 into result
6753bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic.Losr_fp_result:
676715f43e1553330bc804cea2951be195473dc343dChris Larsen    CHECK_ALIGNMENT $a2, $t0, 8
677715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1   $f0, 0($a2)                     # store f0/f1 into result
6783bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic.Losr_exit:
6793bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $ra, 44($sp)
6803bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_restore 31
6813bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $s8, 40($sp)
6823bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_restore 30
6833bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $gp, 36($sp)
6843bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_restore 28
6853bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $s7, 32($sp)
6863bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_restore 23
6873bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $s6, 28($sp)
6883bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_restore 22
6893bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $s5, 24($sp)
6903bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_restore 21
6913bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $s4, 20($sp)
6923bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_restore 20
6933bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $s3, 16($sp)
6943bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_restore 19
6953bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $s2, 12($sp)
6963bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_restore 18
6973bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $s1, 8($sp)
6983bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_restore 17
6993bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    lw     $s0, 4($sp)
7003bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_restore 16
7013bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    jalr   $zero, $ra
7023bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    addiu  $sp, $sp, 48
7033bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    .cfi_adjust_cfa_offset -48
7043bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic.Losr_entry:
7053bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    addiu  $s7, $s7, -4
7063bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    addu   $t0, $s7, $sp
7073bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    move   $t9, $s6
7083bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    jalr   $zero, $t9
7093bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    sw     $ra, 0($t0)                     # Store RA per the compiler ABI
7103bc13817a19e36f3833bb44624ef86800892eaadGoran JakovljevicEND art_quick_osr_stub
7113bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic
7123bc13817a19e36f3833bb44624ef86800892eaadGoran Jakovljevic    /*
713715f43e1553330bc804cea2951be195473dc343dChris Larsen     * On entry $a0 is uint32_t* gprs_ and $a1 is uint32_t* fprs_.
714715f43e1553330bc804cea2951be195473dc343dChris Larsen     * Note that fprs_ is expected to be an address that is a multiple of 8.
7155bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * FIXME: just guessing about the shape of the jmpbuf.  Where will pc be?
7165bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
717d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoENTRY art_quick_do_long_jump
718715f43e1553330bc804cea2951be195473dc343dChris Larsen    CHECK_ALIGNMENT $a1, $t1, 8
719715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f0,   0*8($a1)
720715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f2,   1*8($a1)
721715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f4,   2*8($a1)
722715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f6,   3*8($a1)
723715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f8,   4*8($a1)
724715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f10,  5*8($a1)
725715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f12,  6*8($a1)
726715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f14,  7*8($a1)
727715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f16,  8*8($a1)
728715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f18,  9*8($a1)
729715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f20, 10*8($a1)
730715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f22, 11*8($a1)
731715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f24, 12*8($a1)
732715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f26, 13*8($a1)
733715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f28, 14*8($a1)
734715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1    $f30, 15*8($a1)
735e34652f15f32666323052a6718a63248244f1e66Duane Sand
736748dd957eecbce2f379a3182ce95c19be308a54eChris Dearman    .set push
737748dd957eecbce2f379a3182ce95c19be308a54eChris Dearman    .set nomacro
738748dd957eecbce2f379a3182ce95c19be308a54eChris Dearman    .set noat
7397fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $at, 4($a0)
740748dd957eecbce2f379a3182ce95c19be308a54eChris Dearman    .set pop
7417fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $v0, 8($a0)
7427fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $v1, 12($a0)
7437fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $a1, 20($a0)
7447fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $a2, 24($a0)
7457fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $a3, 28($a0)
7467fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $t0, 32($a0)
7477fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $t1, 36($a0)
7487fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $t2, 40($a0)
7497fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $t3, 44($a0)
7507fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $t4, 48($a0)
7517fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $t5, 52($a0)
7527fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $t6, 56($a0)
7537fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $t7, 60($a0)
7547fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $s0, 64($a0)
7557fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $s1, 68($a0)
7567fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $s2, 72($a0)
7577fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $s3, 76($a0)
7587fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $s4, 80($a0)
7597fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $s5, 84($a0)
7607fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $s6, 88($a0)
7617fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $s7, 92($a0)
7627fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $t8, 96($a0)
7637fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $t9, 100($a0)
7647fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $gp, 112($a0)
7657fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $sp, 116($a0)
7667fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $fp, 120($a0)
7677fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $ra, 124($a0)
7687fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    lw      $a0, 16($a0)
769590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    move    $v0, $zero          # clear result registers v0 and v1 (in branch delay slot)
77075969963213c39a029e01c3b9440fb388d793afbGoran Jakovljevic    jalr    $zero, $t9          # do long jump
7717fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    move    $v1, $zero
772d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_do_long_jump
7735bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
7745bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
7755bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * Called by managed code, saves most registers (forms basis of long jump context) and passes
7765bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * the bottom of the stack. artDeliverExceptionFromCode will place the callee save Method* at
77784bc06e30ba12c3ff07e577c52b63b9df162af7eLazar Trsic     * the bottom of the thread. On entry a0 holds Throwable*
7785bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
779468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_deliver_exception
780fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_ALL_CALLEE_SAVES_FRAME
7818161c0336b97e11e02c000af357f8f40de2e23e4jeffhao    la   $t9, artDeliverExceptionFromCode
7828d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr $zero, $t9                 # artDeliverExceptionFromCode(Throwable*, Thread*)
7831d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    move $a1, rSELF                 # pass Thread::Current
784468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_deliver_exception
7855bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
7865bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
7875bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * Called by managed code to create and deliver a NullPointerException
7885bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
789d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao    .extern artThrowNullPointerExceptionFromCode
790804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir MarkoENTRY_NO_GP art_quick_throw_null_pointer_exception
791804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko    // Note that setting up $gp does not rely on $t9 here, so branching here directly is OK,
792804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko    // even after clobbering any registers we don't need to preserve, such as $gp or $t0.
793804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko    SETUP_SAVE_EVERYTHING_FRAME
7948161c0336b97e11e02c000af357f8f40de2e23e4jeffhao    la   $t9, artThrowNullPointerExceptionFromCode
7958d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr $zero, $t9                 # artThrowNullPointerExceptionFromCode(Thread*)
7961d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    move $a0, rSELF                 # pass Thread::Current
797468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_throw_null_pointer_exception
7985bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
799e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray
800e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray    /*
801e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray     * Call installed by a signal handler to create and deliver a NullPointerException.
802e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray     */
803e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray    .extern artThrowNullPointerExceptionFromSignal
8043b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir MarkoENTRY_NO_GP_CUSTOM_CFA art_quick_throw_null_pointer_exception_from_signal, FRAME_SIZE_SAVE_EVERYTHING
8053b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko    SETUP_SAVE_EVERYTHING_FRAME_DECREMENTED_SP
8063b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko    # Retrieve the fault address from the padding where the signal handler stores it.
8073b7537bfc5a6b7ccb18b3970d8edf14b72464af7Vladimir Marko    lw   $a0, (ARG_SLOT_SIZE + __SIZEOF_POINTER__)($sp)
808e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray    la   $t9, artThrowNullPointerExceptionFromSignal
809e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray    jalr $zero, $t9                 # artThrowNullPointerExceptionFromSignal(uintptr_t, Thread*)
810e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray    move $a1, rSELF                 # pass Thread::Current
811e8e1127da3f154fae8d2eb16a94203544a182159Nicolas GeoffrayEND art_quick_throw_null_pointer_exception_from_signal
812e8e1127da3f154fae8d2eb16a94203544a182159Nicolas Geoffray
8135bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
8145bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * Called by managed code to create and deliver an ArithmeticException
8155bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
816d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao    .extern artThrowDivZeroFromCode
817804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir MarkoENTRY_NO_GP art_quick_throw_div_zero
818804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko    SETUP_SAVE_EVERYTHING_FRAME
8198161c0336b97e11e02c000af357f8f40de2e23e4jeffhao    la   $t9, artThrowDivZeroFromCode
8208d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr $zero, $t9                 # artThrowDivZeroFromCode(Thread*)
8211d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    move $a0, rSELF                 # pass Thread::Current
822468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_throw_div_zero
8235bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
8245bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
8255bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException
8265bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
827d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao    .extern artThrowArrayBoundsFromCode
828804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir MarkoENTRY_NO_GP art_quick_throw_array_bounds
829804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko    // Note that setting up $gp does not rely on $t9 here, so branching here directly is OK,
830804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko    // even after clobbering any registers we don't need to preserve, such as $gp or $t0.
831804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko    SETUP_SAVE_EVERYTHING_FRAME
8328161c0336b97e11e02c000af357f8f40de2e23e4jeffhao    la   $t9, artThrowArrayBoundsFromCode
8338d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr $zero, $t9                 # artThrowArrayBoundsFromCode(index, limit, Thread*)
8341d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    move $a2, rSELF                 # pass Thread::Current
835468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_throw_array_bounds
8365bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
83757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    /*
83887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko     * Called by managed code to create and deliver a StringIndexOutOfBoundsException
83987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko     * as if thrown from a call to String.charAt().
84087f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko     */
84187f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    .extern artThrowStringBoundsFromCode
842804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir MarkoENTRY_NO_GP art_quick_throw_string_bounds
843804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko    SETUP_SAVE_EVERYTHING_FRAME
84487f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    la   $t9, artThrowStringBoundsFromCode
84587f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    jalr $zero, $t9                 # artThrowStringBoundsFromCode(index, limit, Thread*)
84687f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    move $a2, rSELF                 # pass Thread::Current
84787f3fcbd0db352157fc59148e94647ef21b73bceVladimir MarkoEND art_quick_throw_string_bounds
84887f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko
84987f3fcbd0db352157fc59148e94647ef21b73bceVladimir Marko    /*
85057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code to create and deliver a StackOverflowError.
85157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     */
852d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao    .extern artThrowStackOverflowFromCode
853468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_throw_stack_overflow
854fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_ALL_CALLEE_SAVES_FRAME
8558161c0336b97e11e02c000af357f8f40de2e23e4jeffhao    la   $t9, artThrowStackOverflowFromCode
8568d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr $zero, $t9                 # artThrowStackOverflowFromCode(Thread*)
8571d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    move $a0, rSELF                 # pass Thread::Current
858468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_throw_stack_overflow
8595bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
86057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    /*
8615bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * All generated callsites for interface invokes and invocation slow paths will load arguments
8627fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao     * as usual - except instead of loading arg0/$a0 with the target Method*, arg0/$a0 will contain
8637ea6a170486d81b127e69673cd1020c4db628c93Nicolas Geoffray     * the method_idx.  This wrapper will save arg1-arg3, and call the appropriate C helper.
8647fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao     * NOTE: "this" is first visable argument of the target, and so can be found in arg1/$a1.
8655bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     *
8667fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao     * The helper will attempt to locate the target and return a 64-bit result in $v0/$v1 consisting
8677fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao     * of the target Method* in $v0 and method->code_ in $v1.
8685bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     *
8692cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier     * If unsuccessful, the helper will return null/null. There will be a pending exception in the
8705bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * thread and we branch to another stub to deliver it.
8715bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     *
8725bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * On success this wrapper will restore arguments and *jump* to the target, leaving the lr
8735bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * pointing back to the original caller.
8745bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
875279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze.macro INVOKE_TRAMPOLINE_BODY cxx_name, save_s4_thru_s8_only=0
8765bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    .extern \cxx_name
877279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    SETUP_SAVE_REFS_AND_ARGS_FRAME \save_s4_thru_s8_only  # save callee saves in case
878279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze                                                          # allocation triggers GC
8797ea6a170486d81b127e69673cd1020c4db628c93Nicolas Geoffray    move  $a2, rSELF                       # pass Thread::Current
880590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la    $t9, \cxx_name
881590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr  $t9                              # (method_idx, this, Thread*, $sp)
8827ea6a170486d81b127e69673cd1020c4db628c93Nicolas Geoffray    addiu $a3, $sp, ARG_SLOT_SIZE          # pass $sp (remove arg slots)
8837ea6a170486d81b127e69673cd1020c4db628c93Nicolas Geoffray    move  $a0, $v0                         # save target Method*
884fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    RESTORE_SAVE_REFS_AND_ARGS_FRAME
885fa147e22a73c6df166b08a2f71f9c9b52b09d17cjeffhao    beqz  $v0, 1f
8867ea6a170486d81b127e69673cd1020c4db628c93Nicolas Geoffray    move  $t9, $v1                         # save $v0->code_
8878d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr  $zero, $t9
8885bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    nop
8895bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee1:
8905bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    DELIVER_PENDING_EXCEPTION
8913031c8da0c5009183f770b005c245f9bf2a4d01bAndreas Gampe.endm
8923031c8da0c5009183f770b005c245f9bf2a4d01bAndreas Gampe.macro INVOKE_TRAMPOLINE c_name, cxx_name
8933031c8da0c5009183f770b005c245f9bf2a4d01bAndreas GampeENTRY \c_name
8943031c8da0c5009183f770b005c245f9bf2a4d01bAndreas Gampe    INVOKE_TRAMPOLINE_BODY \cxx_name
895d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND \c_name
8965bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee.endm
8975bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
8988dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
8995bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
9008dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck
9018dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck
9028dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
9038dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
9045bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
9051b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze// Each of the following macros expands into four instructions or 16 bytes.
9061b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze// They are used to build indexable "tables" of code.
9071b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
9081b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.macro LOAD_WORD_TO_REG reg, next_arg, index_reg, label
909ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    lw    $\reg, -4($\next_arg)   # next_arg points to argument after the current one (offset is 4)
910ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    b     \label
9111b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $\index_reg, 16
9121b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .balign 16
913ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic.endm
914ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic
9151b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.macro LOAD_LONG_TO_REG reg1, reg2, next_arg, index_reg, next_index, label
916ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    lw    $\reg1, -8($\next_arg)  # next_arg points to argument after the current one (offset is 8)
917ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    lw    $\reg2, -4($\next_arg)
918ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    b     \label
9191b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    li    $\index_reg, \next_index
9201b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .balign 16
921ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic.endm
922ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic
9231b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.macro LOAD_FLOAT_TO_REG reg, next_arg, index_reg, label
924ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    lwc1  $\reg, -4($\next_arg)   # next_arg points to argument after the current one (offset is 4)
925ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    b     \label
9261b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $\index_reg, 16
9271b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .balign 16
928ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic.endm
929ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic
9301b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#if defined(__mips_isa_rev) && __mips_isa_rev > 2
9311b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze// LDu expands into 3 instructions for 64-bit FPU, so index_reg cannot be updated here.
9321b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.macro LOAD_DOUBLE_TO_REG reg1, reg2, next_arg, index_reg, tmp, label
9331b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .set reorder                                # force use of the branch delay slot
934ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    LDu  $\reg1, $\reg2, -8, $\next_arg, $\tmp  # next_arg points to argument after the current one
935ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic                                                # (offset is 8)
936ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    b     \label
9371b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .set noreorder
9381b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .balign 16
9391b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.endm
9401b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#else
9411b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze// LDu expands into 2 instructions for 32-bit FPU, so index_reg is updated here.
9421b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.macro LOAD_DOUBLE_TO_REG reg1, reg2, next_arg, index_reg, tmp, label
9431b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LDu  $\reg1, $\reg2, -8, $\next_arg, $\tmp  # next_arg points to argument after the current one
9441b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze                                                # (offset is 8)
9451b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    b     \label
9461b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $\index_reg, 16
9471b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .balign 16
9481b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.endm
9491b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#endif
9501b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
9511b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze.macro LOAD_END index_reg, next_index, label
9521b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    b     \label
9531b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    li    $\index_reg, \next_index
9541b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .balign 16
955ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic.endm
956ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic
957590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic#define SPILL_SIZE    32
958590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic
95979fe539587d4c09244172d0168eeed0ec9770466Jeff Hao    /*
960ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers     * Invocation stub for quick code.
9615d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao     * On entry:
9625d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao     *   a0 = method pointer
9632cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier     *   a1 = argument array or null for no argument methods
9645d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao     *   a2 = size of argument array in bytes
9655d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao     *   a3 = (managed) thread pointer
9666474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao     *   [sp + 16] = JValue* result
9670177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers     *   [sp + 20] = shorty
9685d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao     */
9695d9173014c1ca09f7249a6b07629aa37778b5f8fJeff HaoENTRY art_quick_invoke_stub
9705d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    sw    $a0, 0($sp)           # save out a0
971590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    addiu $sp, $sp, -SPILL_SIZE # spill s0, s1, fp, ra and gp
972590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    .cfi_adjust_cfa_offset SPILL_SIZE
973590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    sw    $gp, 16($sp)
9745d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    sw    $ra, 12($sp)
9755d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset 31, 12
9765d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    sw    $fp, 8($sp)
9775d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset 30, 8
9785d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    sw    $s1, 4($sp)
9795d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset 17, 4
9805d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    sw    $s0, 0($sp)
9815d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_rel_offset 16, 0
9825d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    move  $fp, $sp              # save sp in fp
9835d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    .cfi_def_cfa_register 30
9845d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    move  $s1, $a3              # move managed thread pointer into s1
985ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    addiu $t0, $a2, 4           # create space for ArtMethod* in frame.
986735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    subu  $t0, $sp, $t0         # reserve & align *stack* to 16 bytes:
987ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    srl   $t0, $t0, 4           #   native calling convention only aligns to 8B,
988ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    sll   $sp, $t0, 4           #   so we have to ensure ART 16B alignment ourselves.
989ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    addiu $a0, $sp, 4           # pass stack pointer + ArtMethod* as dest for memcpy
990590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la    $t9, memcpy
991590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr  $t9                   # (dest, src, bytes)
9925d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    addiu $sp, $sp, -16         # make space for argument slots for memcpy
9935d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    addiu $sp, $sp, 16          # restore stack after memcpy
994590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    lw    $gp, 16($fp)          # restore $gp
995590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    lw    $a0, SPILL_SIZE($fp)  # restore ArtMethod*
996ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    lw    $a1, 4($sp)           # a1 = this*
9971b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t8, $sp, 8           # t8 = pointer to the current argument (skip ArtMethod* and this*)
9981b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    li    $t6, 0                # t6 = gpr_index = 0 (corresponds to A2; A0 and A1 are skipped)
9991b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    li    $t7, 0                # t7 = fp_index = 0
10001b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lw    $t9, 20 + SPILL_SIZE($fp)  # get shorty (20 is offset from the $sp on entry + SPILL_SIZE
1001590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic                                # as the $fp is SPILL_SIZE bytes below the $sp on entry)
10021b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t9, 1                # t9 = shorty + 1 (skip 1 for return type)
10031b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
10041b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    // Load the base addresses of tabInt ... tabDouble.
10051b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    // We will use the register indices (gpr_index, fp_index) to branch.
10061b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    // Note that the indices are scaled by 16, so they can be added to the bases directly.
10071b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#if defined(__mips_isa_rev) && __mips_isa_rev >= 6
10081b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lapc  $t2, tabInt
10091b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lapc  $t3, tabLong
10101b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lapc  $t4, tabSingle
10111b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lapc  $t5, tabDouble
10121b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#else
10131b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    bltzal $zero, tabBase       # nal
10141b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t2, $ra, %lo(tabInt - tabBase)
10151b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabBase:
10161b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t3, $ra, %lo(tabLong - tabBase)
10171b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t4, $ra, %lo(tabSingle - tabBase)
10181b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t5, $ra, %lo(tabDouble - tabBase)
10191b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#endif
10201b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
1021ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevicloop:
10221b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lbu   $ra, 0($t9)           # ra = shorty[i]
10231b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    beqz  $ra, loopEnd          # finish getting args when shorty[i] == '\0'
10241b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t9, 1
10251b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
10261b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $ra, -'J'
10271b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    beqz  $ra, isLong           # branch if result type char == 'J'
10281b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $ra, 'J' - 'D'
10291b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    beqz  $ra, isDouble         # branch if result type char == 'D'
10301b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $ra, 'D' - 'F'
10311b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    beqz  $ra, isSingle         # branch if result type char == 'F'
10321b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
10331b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addu  $ra, $t2, $t6
10341b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    jalr  $zero, $ra
10351b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t8, 4                # next_arg = curr_arg + 4
1036ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic
1037ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicisLong:
10381b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addu  $ra, $t3, $t6
10391b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    jalr  $zero, $ra
10401b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t8, 8                # next_arg = curr_arg + 8
1041ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic
1042ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicisSingle:
10431b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addu  $ra, $t4, $t7
10441b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    jalr  $zero, $ra
10451b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t8, 4                # next_arg = curr_arg + 4
10461b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
10471b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzeisDouble:
10481b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addu  $ra, $t5, $t7
10491b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#if defined(__mips_isa_rev) && __mips_isa_rev > 2
10501b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t7, 16               # fp_index += 16 didn't fit into LOAD_DOUBLE_TO_REG
10511b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#endif
10521b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    jalr  $zero, $ra
10531b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t8, 8                # next_arg = curr_arg + 8
1054ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic
1055ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicloopEnd:
1056e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    lw    $t9, ART_METHOD_QUICK_CODE_OFFSET_32($a0)  # get pointer to the code
10575d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    jalr  $t9                   # call the method
1058ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    sw    $zero, 0($sp)         # store null for ArtMethod* at bottom of frame
10595d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    move  $sp, $fp              # restore the stack
10605d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    lw    $s0, 0($sp)
1061bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 16
10625d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    lw    $s1, 4($sp)
1063bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 17
10645d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    lw    $fp, 8($sp)
1065bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 30
10665d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    lw    $ra, 12($sp)
1067bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    .cfi_restore 31
1068590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    addiu $sp, $sp, SPILL_SIZE
1069590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    .cfi_adjust_cfa_offset -SPILL_SIZE
10705d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    lw    $t0, 16($sp)          # get result pointer
10710177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers    lw    $t1, 20($sp)          # get shorty
10720177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers    lb    $t1, 0($t1)           # get result type char
1073ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    li    $t2, 'D'              # put char 'D' into t2
1074ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    beq   $t1, $t2, 5f          # branch if result type char == 'D'
1075ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    li    $t3, 'F'              # put char 'F' into t3
1076ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    beq   $t1, $t3, 5f          # branch if result type char == 'F'
10775d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    sw    $v0, 0($t0)           # store the result
10788d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr  $zero, $ra
10795d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    sw    $v1, 4($t0)           # store the other half of the result
1080ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic5:
1081715f43e1553330bc804cea2951be195473dc343dChris Larsen    CHECK_ALIGNMENT $t0, $t1, 8
1082715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1  $f0, 0($t0)           # store floating point result
10838d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr  $zero, $ra
1084e34652f15f32666323052a6718a63248244f1e66Duane Sand    nop
10851b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
10861b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    // Note that gpr_index is kept within the range of tabInt and tabLong
10871b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    // and fp_index is kept within the range of tabSingle and tabDouble.
10881b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .balign 16
10891b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabInt:
10901b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_WORD_TO_REG a2, t8, t6, loop             # a2 = current argument, gpr_index += 16
10911b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_WORD_TO_REG a3, t8, t6, loop             # a3 = current argument, gpr_index += 16
10921b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_WORD_TO_REG t0, t8, t6, loop             # t0 = current argument, gpr_index += 16
10931b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_WORD_TO_REG t1, t8, t6, loop             # t1 = current argument, gpr_index += 16
10941b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_END t6, 4*16, loop                       # no more GPR args, gpr_index = 4*16
10951b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabLong:
10961b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_LONG_TO_REG a2, a3, t8, t6, 2*16, loop   # a2_a3 = curr_arg, gpr_index = 2*16
10971b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_LONG_TO_REG t0, t1, t8, t6, 4*16, loop   # t0_t1 = curr_arg, gpr_index = 4*16
10981b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_LONG_TO_REG t0, t1, t8, t6, 4*16, loop   # t0_t1 = curr_arg, gpr_index = 4*16
10991b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_END t6, 4*16, loop                       # no more GPR args, gpr_index = 4*16
11001b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_END t6, 4*16, loop                       # no more GPR args, gpr_index = 4*16
11011b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabSingle:
11021b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_FLOAT_TO_REG f8, t8, t7, loop            # f8 = curr_arg, fp_index += 16
11031b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_FLOAT_TO_REG f10, t8, t7, loop           # f10 = curr_arg, fp_index += 16
11041b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_FLOAT_TO_REG f12, t8, t7, loop           # f12 = curr_arg, fp_index += 16
11051b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_FLOAT_TO_REG f14, t8, t7, loop           # f14 = curr_arg, fp_index += 16
11061b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_FLOAT_TO_REG f16, t8, t7, loop           # f16 = curr_arg, fp_index += 16
11071b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_FLOAT_TO_REG f18, t8, t7, loop           # f18 = curr_arg, fp_index += 16
11081b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_END t7, 6*16, loop                       # no more FPR args, fp_index = 6*16
11091b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabDouble:
11101b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_DOUBLE_TO_REG f8, f9, t8, t7, ra, loop   # f8_f9 = curr_arg; if FPU32, fp_index += 16
11111b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_DOUBLE_TO_REG f10, f11, t8, t7, ra, loop # f10_f11 = curr_arg; if FPU32, fp_index += 16
11121b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_DOUBLE_TO_REG f12, f13, t8, t7, ra, loop # f12_f13 = curr_arg; if FPU32, fp_index += 16
11131b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_DOUBLE_TO_REG f14, f15, t8, t7, ra, loop # f14_f15 = curr_arg; if FPU32, fp_index += 16
11141b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_DOUBLE_TO_REG f16, f17, t8, t7, ra, loop # f16_f17 = curr_arg; if FPU32, fp_index += 16
11151b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_DOUBLE_TO_REG f18, f19, t8, t7, ra, loop # f18_f19 = curr_arg; if FPU32, fp_index += 16
11161b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_END t7, 6*16, loop                       # no more FPR args, fp_index = 6*16
11175d9173014c1ca09f7249a6b07629aa37778b5f8fJeff HaoEND art_quick_invoke_stub
11185d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao
11195d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    /*
1120ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic     * Invocation static stub for quick code.
1121ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic     * On entry:
1122ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic     *   a0 = method pointer
1123ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic     *   a1 = argument array or null for no argument methods
1124ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic     *   a2 = size of argument array in bytes
1125ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic     *   a3 = (managed) thread pointer
1126ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic     *   [sp + 16] = JValue* result
1127ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic     *   [sp + 20] = shorty
1128ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic     */
1129ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicENTRY art_quick_invoke_static_stub
1130ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    sw    $a0, 0($sp)           # save out a0
1131590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    addiu $sp, $sp, -SPILL_SIZE # spill s0, s1, fp, ra and gp
1132590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    .cfi_adjust_cfa_offset SPILL_SIZE
1133590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    sw    $gp, 16($sp)
1134ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    sw    $ra, 12($sp)
1135ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    .cfi_rel_offset 31, 12
1136ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    sw    $fp, 8($sp)
1137ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    .cfi_rel_offset 30, 8
1138ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    sw    $s1, 4($sp)
1139ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    .cfi_rel_offset 17, 4
1140ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    sw    $s0, 0($sp)
1141ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    .cfi_rel_offset 16, 0
1142ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    move  $fp, $sp              # save sp in fp
1143ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    .cfi_def_cfa_register 30
1144ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    move  $s1, $a3              # move managed thread pointer into s1
1145ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    addiu $t0, $a2, 4           # create space for ArtMethod* in frame.
1146ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    subu  $t0, $sp, $t0         # reserve & align *stack* to 16 bytes:
1147ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    srl   $t0, $t0, 4           #   native calling convention only aligns to 8B,
1148ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    sll   $sp, $t0, 4           #   so we have to ensure ART 16B alignment ourselves.
1149ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    addiu $a0, $sp, 4           # pass stack pointer + ArtMethod* as dest for memcpy
1150590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la    $t9, memcpy
1151590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr  $t9                   # (dest, src, bytes)
1152ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    addiu $sp, $sp, -16         # make space for argument slots for memcpy
1153ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    addiu $sp, $sp, 16          # restore stack after memcpy
1154590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    lw    $gp, 16($fp)          # restore $gp
1155590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    lw    $a0, SPILL_SIZE($fp)  # restore ArtMethod*
11561b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t8, $sp, 4           # t8 = pointer to the current argument (skip ArtMethod*)
11571b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    li    $t6, 0                # t6 = gpr_index = 0 (corresponds to A1; A0 is skipped)
11581b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    li    $t7, 0                # t7 = fp_index = 0
11591b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lw    $t9, 20 + SPILL_SIZE($fp)  # get shorty (20 is offset from the $sp on entry + SPILL_SIZE
1160590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic                                # as the $fp is SPILL_SIZE bytes below the $sp on entry)
11611b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t9, 1                # t9 = shorty + 1 (skip 1 for return type)
11621b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
11631b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    // Load the base addresses of tabIntS ... tabDoubleS.
11641b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    // We will use the register indices (gpr_index, fp_index) to branch.
11651b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    // Note that the indices are scaled by 16, so they can be added to the bases directly.
11661b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#if defined(__mips_isa_rev) && __mips_isa_rev >= 6
11671b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lapc  $t2, tabIntS
11681b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lapc  $t3, tabLongS
11691b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lapc  $t4, tabSingleS
11701b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lapc  $t5, tabDoubleS
11711b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#else
11721b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    bltzal $zero, tabBaseS      # nal
11731b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t2, $ra, %lo(tabIntS - tabBaseS)
11741b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabBaseS:
11751b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t3, $ra, %lo(tabLongS - tabBaseS)
11761b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t4, $ra, %lo(tabSingleS - tabBaseS)
11771b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t5, $ra, %lo(tabDoubleS - tabBaseS)
11781b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#endif
11791b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
1180ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicloopS:
11811b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lbu   $ra, 0($t9)           # ra = shorty[i]
11821b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    beqz  $ra, loopEndS         # finish getting args when shorty[i] == '\0'
11831b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t9, 1
11841b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
11851b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $ra, -'J'
11861b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    beqz  $ra, isLongS          # branch if result type char == 'J'
11871b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $ra, 'J' - 'D'
11881b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    beqz  $ra, isDoubleS        # branch if result type char == 'D'
11891b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $ra, 'D' - 'F'
11901b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    beqz  $ra, isSingleS        # branch if result type char == 'F'
11911b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
11921b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addu  $ra, $t2, $t6
11931b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    jalr  $zero, $ra
11941b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t8, 4                # next_arg = curr_arg + 4
1195ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic
1196ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicisLongS:
11971b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addu  $ra, $t3, $t6
11981b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    jalr  $zero, $ra
11991b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t8, 8                # next_arg = curr_arg + 8
1200ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic
1201ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicisSingleS:
12021b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addu  $ra, $t4, $t7
12031b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    jalr  $zero, $ra
12041b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t8, 4                # next_arg = curr_arg + 4
12051b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
12061b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzeisDoubleS:
12071b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addu  $ra, $t5, $t7
12081b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#if defined(__mips_isa_rev) && __mips_isa_rev > 2
12091b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t7, 16               # fp_index += 16 didn't fit into LOAD_DOUBLE_TO_REG
12101b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze#endif
12111b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    jalr  $zero, $ra
12121b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    addiu $t8, 8                # next_arg = curr_arg + 8
1213ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic
1214ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicloopEndS:
1215ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    lw    $t9, ART_METHOD_QUICK_CODE_OFFSET_32($a0)  # get pointer to the code
1216ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    jalr  $t9                   # call the method
1217ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    sw    $zero, 0($sp)         # store null for ArtMethod* at bottom of frame
1218ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    move  $sp, $fp              # restore the stack
1219ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    lw    $s0, 0($sp)
1220ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    .cfi_restore 16
1221ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    lw    $s1, 4($sp)
1222ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    .cfi_restore 17
1223ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    lw    $fp, 8($sp)
1224ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    .cfi_restore 30
1225ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    lw    $ra, 12($sp)
1226ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    .cfi_restore 31
1227590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    addiu $sp, $sp, SPILL_SIZE
1228590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    .cfi_adjust_cfa_offset -SPILL_SIZE
1229ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    lw    $t0, 16($sp)          # get result pointer
1230ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    lw    $t1, 20($sp)          # get shorty
1231ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    lb    $t1, 0($t1)           # get result type char
1232ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    li    $t2, 'D'              # put char 'D' into t2
1233ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    beq   $t1, $t2, 6f          # branch if result type char == 'D'
1234ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    li    $t3, 'F'              # put char 'F' into t3
1235ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    beq   $t1, $t3, 6f          # branch if result type char == 'F'
1236ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    sw    $v0, 0($t0)           # store the result
1237ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    jalr  $zero, $ra
1238ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    sw    $v1, 4($t0)           # store the other half of the result
1239ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic6:
1240715f43e1553330bc804cea2951be195473dc343dChris Larsen    CHECK_ALIGNMENT $t0, $t1, 8
1241715f43e1553330bc804cea2951be195473dc343dChris Larsen    sdc1  $f0, 0($t0)           # store floating point result
1242ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    jalr  $zero, $ra
1243ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    nop
12441b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
12451b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    // Note that gpr_index is kept within the range of tabIntS and tabLongS
12461b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    // and fp_index is kept within the range of tabSingleS and tabDoubleS.
12471b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    .balign 16
12481b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabIntS:
12491b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_WORD_TO_REG a1, t8, t6, loopS             # a1 = current argument, gpr_index += 16
12501b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_WORD_TO_REG a2, t8, t6, loopS             # a2 = current argument, gpr_index += 16
12511b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_WORD_TO_REG a3, t8, t6, loopS             # a3 = current argument, gpr_index += 16
12521b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_WORD_TO_REG t0, t8, t6, loopS             # t0 = current argument, gpr_index += 16
12531b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_WORD_TO_REG t1, t8, t6, loopS             # t1 = current argument, gpr_index += 16
12541b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_END t6, 5*16, loopS                       # no more GPR args, gpr_index = 5*16
12551b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabLongS:
12561b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_LONG_TO_REG a2, a3, t8, t6, 3*16, loopS   # a2_a3 = curr_arg, gpr_index = 3*16
12571b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_LONG_TO_REG a2, a3, t8, t6, 3*16, loopS   # a2_a3 = curr_arg, gpr_index = 3*16
12581b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_LONG_TO_REG t0, t1, t8, t6, 5*16, loopS   # t0_t1 = curr_arg, gpr_index = 5*16
12591b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_LONG_TO_REG t0, t1, t8, t6, 5*16, loopS   # t0_t1 = curr_arg, gpr_index = 5*16
12601b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_END t6, 5*16, loopS                       # no more GPR args, gpr_index = 5*16
12611b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_END t6, 5*16, loopS                       # no more GPR args, gpr_index = 5*16
12621b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabSingleS:
12631b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_FLOAT_TO_REG f8, t8, t7, loopS            # f8 = curr_arg, fp_index += 16
12641b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_FLOAT_TO_REG f10, t8, t7, loopS           # f10 = curr_arg, fp_index += 16
12651b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_FLOAT_TO_REG f12, t8, t7, loopS           # f12 = curr_arg, fp_index += 16
12661b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_FLOAT_TO_REG f14, t8, t7, loopS           # f14 = curr_arg, fp_index += 16
12671b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_FLOAT_TO_REG f16, t8, t7, loopS           # f16 = curr_arg, fp_index += 16
12681b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_FLOAT_TO_REG f18, t8, t7, loopS           # f18 = curr_arg, fp_index += 16
12691b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_END t7, 6*16, loopS                       # no more FPR args, fp_index = 6*16
12701b8464d17c2266763714ae18be7c4dc26e28bf61Alexey FrunzetabDoubleS:
12711b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_DOUBLE_TO_REG f8, f9, t8, t7, ra, loopS   # f8_f9 = curr_arg; if FPU32, fp_index += 16
12721b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_DOUBLE_TO_REG f10, f11, t8, t7, ra, loopS # f10_f11 = curr_arg; if FPU32, fp_index += 16
12731b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_DOUBLE_TO_REG f12, f13, t8, t7, ra, loopS # f12_f13 = curr_arg; if FPU32, fp_index += 16
12741b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_DOUBLE_TO_REG f14, f15, t8, t7, ra, loopS # f14_f15 = curr_arg; if FPU32, fp_index += 16
12751b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_DOUBLE_TO_REG f16, f17, t8, t7, ra, loopS # f16_f17 = curr_arg; if FPU32, fp_index += 16
12761b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_DOUBLE_TO_REG f18, f19, t8, t7, ra, loopS # f18_f19 = curr_arg; if FPU32, fp_index += 16
12771b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    LOAD_END t7, 6*16, loopS                       # no more FPR args, fp_index = 6*16
1278ff73498a5539d87424a964265e43765e788aec44Goran JakovljevicEND art_quick_invoke_static_stub
1279ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic
1280590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic#undef SPILL_SIZE
1281590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic
1282ff73498a5539d87424a964265e43765e788aec44Goran Jakovljevic    /*
12835bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * Entry from managed code that calls artHandleFillArrayDataFromCode and delivers exception on
12845bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * failure.
12855bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
1286d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao    .extern artHandleFillArrayDataFromCode
1287468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_handle_fill_data
1288fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    lw     $a2, 0($sp)                # pass referrer's Method*
1289fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_ONLY_FRAME        # save callee saves in case exception allocation triggers GC
1290590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la     $t9, artHandleFillArrayDataFromCode
1291fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    jalr   $t9                        # (payload offset, Array*, method, Thread*)
1292fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    move   $a3, rSELF                 # pass Thread::Current
1293fc6a30e2fa8f0d44e6c95bbeb5deca4b499f67cejeffhao    RETURN_IF_ZERO
1294468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_handle_fill_data
12955bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
12965bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
129757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Entry from managed code that calls artLockObjectFromCode, may block for GC.
12985bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
1299d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao    .extern artLockObjectFromCode
1300468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_lock_object
1301804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko    beqz    $a0, art_quick_throw_null_pointer_exception
1302ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    li      $t8, LOCK_WORD_THIN_LOCK_COUNT_ONE
1303ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    li      $t3, LOCK_WORD_GC_STATE_MASK_SHIFTED_TOGGLED
1304ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze.Lretry_lock:
1305ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    lw      $t0, THREAD_ID_OFFSET(rSELF)  # TODO: Can the thread ID really change during the loop?
1306ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    ll      $t1, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0)
1307ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    and     $t2, $t1, $t3                 # zero the gc bits
1308ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    bnez    $t2, .Lnot_unlocked           # already thin locked
1309ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    # Unlocked case - $t1: original lock word that's zero except for the read barrier bits.
1310ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    or      $t2, $t1, $t0                 # $t2 holds thread id with count of 0 with preserved read barrier bits
1311ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    sc      $t2, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0)
1312ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    beqz    $t2, .Lretry_lock             # store failed, retry
1313a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    nop
1314ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    jalr    $zero, $ra
1315ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    sync                                  # full (LoadLoad|LoadStore) memory barrier
1316ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze.Lnot_unlocked:
1317ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    # $t1: original lock word, $t0: thread_id with count of 0 and zero read barrier bits
1318ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    srl     $t2, $t1, LOCK_WORD_STATE_SHIFT
1319ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    bnez    $t2, .Lslow_lock              # if either of the top two bits are set, go slow path
1320ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    xor     $t2, $t1, $t0                 # lock_word.ThreadId() ^ self->ThreadId()
1321ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    andi    $t2, $t2, 0xFFFF              # zero top 16 bits
1322ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    bnez    $t2, .Lslow_lock              # lock word and self thread id's match -> recursive lock
1323ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze                                          # otherwise contention, go to slow path
1324ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    and     $t2, $t1, $t3                 # zero the gc bits
1325ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    addu    $t2, $t2, $t8                 # increment count in lock word
1326ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    srl     $t2, $t2, LOCK_WORD_STATE_SHIFT  # if the first gc state bit is set, we overflowed.
1327ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    bnez    $t2, .Lslow_lock              # if we overflow the count go slow path
1328ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    addu    $t2, $t1, $t8                 # increment count for real
1329ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    sc      $t2, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0)
1330ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    beqz    $t2, .Lretry_lock             # store failed, retry
1331ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    nop
1332ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    jalr    $zero, $ra
1333ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    nop
1334ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze.Lslow_lock:
1335fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_ONLY_FRAME            # save callee saves in case we block
1336590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la      $t9, artLockObjectFromCode
1337590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr    $t9                           # (Object* obj, Thread*)
13387fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    move    $a1, rSELF                    # pass Thread::Current
13396bcd163d322b867578fbcfe60e4e3b247c42974bIan Rogers    RETURN_IF_ZERO
1340468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_lock_object
13415bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
1342c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas GampeENTRY art_quick_lock_object_no_inline
1343804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko    beqz    $a0, art_quick_throw_null_pointer_exception
1344c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe    nop
1345fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_ONLY_FRAME            # save callee saves in case we block
1346c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe    la      $t9, artLockObjectFromCode
1347c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe    jalr    $t9                           # (Object* obj, Thread*)
1348c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe    move    $a1, rSELF                    # pass Thread::Current
1349c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe    RETURN_IF_ZERO
1350c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas GampeEND art_quick_lock_object_no_inline
1351c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe
13525bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
13535bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * Entry from managed code that calls artUnlockObjectFromCode and delivers exception on failure.
13545bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
1355d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao    .extern artUnlockObjectFromCode
1356468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_unlock_object
1357804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko    beqz    $a0, art_quick_throw_null_pointer_exception
1358ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    li      $t8, LOCK_WORD_THIN_LOCK_COUNT_ONE
1359ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    li      $t3, LOCK_WORD_GC_STATE_MASK_SHIFTED_TOGGLED
1360ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze.Lretry_unlock:
1361ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#ifndef USE_READ_BARRIER
1362ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    lw      $t1, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0)
1363ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#else
1364ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    ll      $t1, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0)  # Need to use atomic read-modify-write for read barrier
1365ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#endif
1366ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    srl     $t2, $t1, LOCK_WORD_STATE_SHIFT
1367ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    bnez    $t2, .Lslow_unlock         # if either of the top two bits are set, go slow path
1368ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    lw      $t0, THREAD_ID_OFFSET(rSELF)
1369ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    and     $t2, $t1, $t3              # zero the gc bits
1370ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    xor     $t2, $t2, $t0              # lock_word.ThreadId() ^ self->ThreadId()
1371ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    andi    $t2, $t2, 0xFFFF           # zero top 16 bits
1372ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    bnez    $t2, .Lslow_unlock         # do lock word and self thread id's match?
1373ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    and     $t2, $t1, $t3              # zero the gc bits
1374ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    bgeu    $t2, $t8, .Lrecursive_thin_unlock
1375ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    # transition to unlocked
1376ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    nor     $t2, $zero, $t3            # $t2 = LOCK_WORD_GC_STATE_MASK_SHIFTED
1377ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    and     $t2, $t1, $t2              # $t2: zero except for the preserved gc bits
1378ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    sync                               # full (LoadStore|StoreStore) memory barrier
1379ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#ifndef USE_READ_BARRIER
1380ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    jalr    $zero, $ra
1381ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    sw      $t2, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0)
1382ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#else
1383ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    sc      $t2, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0)
1384ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    beqz    $t2, .Lretry_unlock        # store failed, retry
1385a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    nop
1386ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    jalr    $zero, $ra
1387ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    nop
1388ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#endif
1389ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze.Lrecursive_thin_unlock:
1390ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    # t1: original lock word
1391ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    subu    $t2, $t1, $t8              # decrement count
1392ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#ifndef USE_READ_BARRIER
1393ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    jalr    $zero, $ra
1394ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    sw      $t2, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0)
1395ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#else
1396ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    sc      $t2, MIRROR_OBJECT_LOCK_WORD_OFFSET($a0)
1397ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    beqz    $t2, .Lretry_unlock        # store failed, retry
1398ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    nop
1399ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    jalr    $zero, $ra
1400ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    nop
1401ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze#endif
1402ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze.Lslow_unlock:
1403ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    SETUP_SAVE_REFS_ONLY_FRAME         # save callee saves in case exception allocation triggers GC
1404590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la      $t9, artUnlockObjectFromCode
1405ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    jalr    $t9                        # (Object* obj, Thread*)
1406ad63fe5f330d10e08467e0c7c6f4c199b62fa3abAlexey Frunze    move    $a1, rSELF                 # pass Thread::Current
14075bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    RETURN_IF_ZERO
1408468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_unlock_object
14095bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
1410c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas GampeENTRY art_quick_unlock_object_no_inline
1411804b03ffb9b9dc6cc3153e004c2cd38667508b13Vladimir Marko    beqz    $a0, art_quick_throw_null_pointer_exception
1412c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe    nop
1413fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_ONLY_FRAME        # save callee saves in case exception allocation triggers GC
1414c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe    la      $t9, artUnlockObjectFromCode
1415c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe    jalr    $t9                       # (Object* obj, Thread*)
1416c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe    move    $a1, rSELF                # pass Thread::Current
1417c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe    RETURN_IF_ZERO
1418c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas GampeEND art_quick_unlock_object_no_inline
1419c7ed09bd5d6f2c7af3bcba1c39b3f9185af68796Andreas Gampe
14205bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
1421b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu Chartier     * Entry from managed code that calls artInstanceOfFromCode and delivers exception on failure.
14225bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
1423b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu Chartier    .extern artInstanceOfFromCode
1424b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu Chartier    .extern artThrowClassCastExceptionForObject
1425b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu ChartierENTRY art_quick_check_instance_of
1426590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    addiu  $sp, $sp, -32
1427590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    .cfi_adjust_cfa_offset 32
1428590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    sw     $gp, 16($sp)
1429a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    sw     $ra, 12($sp)
1430a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    .cfi_rel_offset 31, 12
1431a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    sw     $t9, 8($sp)
1432a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    sw     $a1, 4($sp)
1433a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    sw     $a0, 0($sp)
1434b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu Chartier    la     $t9, artInstanceOfFromCode
1435590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr   $t9
1436735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu  $sp, $sp, -16             # reserve argument slots on the stack
1437735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu  $sp, $sp, 16
1438590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    lw     $gp, 16($sp)
143986bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers    beqz   $v0, .Lthrow_class_cast_exception
1440a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    lw     $ra, 12($sp)
14418d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr   $zero, $ra
1442590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    addiu  $sp, $sp, 32
1443590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    .cfi_adjust_cfa_offset -32
144486bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers.Lthrow_class_cast_exception:
1445a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    lw     $t9, 8($sp)
1446a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    lw     $a1, 4($sp)
1447a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    lw     $a0, 0($sp)
1448590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    addiu  $sp, $sp, 32
1449590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    .cfi_adjust_cfa_offset -32
1450fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_ALL_CALLEE_SAVES_FRAME
1451b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu Chartier    la   $t9, artThrowClassCastExceptionForObject
1452b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu Chartier    jalr $zero, $t9                 # artThrowClassCastException (Object*, Class*, Thread*)
14531d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    move $a2, rSELF                 # pass Thread::Current
1454b99f4d6463e7cb5654af3893ed7b3113665df658Mathieu ChartierEND art_quick_check_instance_of
14555bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
14565bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
14571aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao     * Restore rReg's value from offset($sp) if rReg is not the same as rExclude.
14581aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao     * nReg is the register number for rReg.
14591aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao     */
14601aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao.macro POP_REG_NE rReg, nReg, offset, rExclude
14611aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .ifnc \rReg, \rExclude
14621aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao        lw \rReg, \offset($sp)      # restore rReg
14631aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao        .cfi_restore \nReg
14641aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .endif
14651aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao.endm
14661aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao
14671aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    /*
14681aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao     * Macro to insert read barrier, only used in art_quick_aput_obj.
14691aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao     * rObj and rDest are registers, offset is a defined literal such as MIRROR_OBJECT_CLASS_OFFSET.
14701aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao     * TODO: When read barrier has a fast path, add heap unpoisoning support for the fast path.
14711aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao     */
14721aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao.macro READ_BARRIER rDest, rObj, offset
14731aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#ifdef USE_READ_BARRIER
14741aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    # saved registers used in art_quick_aput_obj: a0-a2, t0-t1, t9, ra. 8 words for 16B alignment.
14751aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    addiu  $sp, $sp, -32
14761aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_adjust_cfa_offset 32
14771aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    sw     $ra, 28($sp)
14781aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_rel_offset 31, 28
14791aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    sw     $t9, 24($sp)
14801aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_rel_offset 25, 24
14811aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    sw     $t1, 20($sp)
14821aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_rel_offset 9, 20
14831aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    sw     $t0, 16($sp)
14841aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_rel_offset 8, 16
14851aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    sw     $a2, 8($sp)              # padding slot at offset 12 (padding can be any slot in the 32B)
14861aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_rel_offset 6, 8
14871aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    sw     $a1, 4($sp)
14881aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_rel_offset 5, 4
14891aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    sw     $a0, 0($sp)
14901aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_rel_offset 4, 0
14911aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao
14926306921722283d2b0f8aac01883ad83215d6e864Man Cao    # move $a0, \rRef               # pass ref in a0 (no-op for now since parameter ref is unused)
14931aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .ifnc \rObj, $a1
14941aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao        move $a1, \rObj             # pass rObj
14951aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .endif
1496590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    addiu  $a2, $zero, \offset      # pass offset
1497590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la     $t9, artReadBarrierSlow
1498590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr   $t9                      # artReadBarrierSlow(ref, rObj, offset)
14991aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    addiu  $sp, $sp, -16            # Use branch delay slot to reserve argument slots on the stack
15001aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao                                    # before the call to artReadBarrierSlow.
15011aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    addiu  $sp, $sp, 16             # restore stack after call to artReadBarrierSlow
15021aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    # No need to unpoison return value in v0, artReadBarrierSlow() would do the unpoisoning.
15031aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    move \rDest, $v0                # save return value in rDest
15041aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao                                    # (rDest cannot be v0 in art_quick_aput_obj)
15051aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao
15061aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    lw     $a0, 0($sp)              # restore registers except rDest
15071aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao                                    # (rDest can only be t0 or t1 in art_quick_aput_obj)
15081aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_restore 4
15091aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    lw     $a1, 4($sp)
15101aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_restore 5
15111aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    lw     $a2, 8($sp)
15121aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_restore 6
15131aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    POP_REG_NE $t0, 8, 16, \rDest
15141aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    POP_REG_NE $t1, 9, 20, \rDest
15151aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    lw     $t9, 24($sp)
15161aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_restore 25
15171aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    lw     $ra, 28($sp)             # restore $ra
15181aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_restore 31
15191aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    addiu  $sp, $sp, 32
15201aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .cfi_adjust_cfa_offset -32
15211aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#else
15221aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    lw     \rDest, \offset(\rObj)
15231aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    UNPOISON_HEAP_REF \rDest
15241aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#endif  // USE_READ_BARRIER
15251aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao.endm
15261aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao
15271aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#ifdef USE_READ_BARRIER
15281aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    .extern artReadBarrierSlow
15291aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#endif
1530a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersENTRY art_quick_aput_obj
153186bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers    beqz $a2, .Ldo_aput_null
1532a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    nop
15331aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    READ_BARRIER $t0, $a0, MIRROR_OBJECT_CLASS_OFFSET
15341aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    READ_BARRIER $t1, $a2, MIRROR_OBJECT_CLASS_OFFSET
15351aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao    READ_BARRIER $t0, $t0, MIRROR_CLASS_COMPONENT_TYPE_OFFSET
153686bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers    bne $t1, $t0, .Lcheck_assignability  # value's type == array's component type - trivial assignability
1537a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    nop
153886bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers.Ldo_aput:
1539a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    sll $a1, $a1, 2
1540a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    add $t0, $a0, $a1
1541bfa5eb6e8d15ea73a36f8df449630f285a91e995Hiroshi Yamauchi    POISON_HEAP_REF $a2
15421d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    sw  $a2, MIRROR_OBJECT_ARRAY_DATA_OFFSET($t0)
1543a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    lw  $t0, THREAD_CARD_TABLE_OFFSET(rSELF)
1544afdcbcb56d0c2f985d0291c369bbc493eedb05b0Mathieu Chartier    srl $t1, $a0, CARD_TABLE_CARD_SHIFT
1545a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    add $t1, $t1, $t0
1546a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    sb  $t0, ($t1)
15478d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr $zero, $ra
1548a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    nop
154986bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers.Ldo_aput_null:
1550a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    sll $a1, $a1, 2
1551a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    add $t0, $a0, $a1
15521d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    sw  $a2, MIRROR_OBJECT_ARRAY_DATA_OFFSET($t0)
15538d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr $zero, $ra
1554a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    nop
155586bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers.Lcheck_assignability:
1556a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    addiu  $sp, $sp, -32
1557a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    .cfi_adjust_cfa_offset 32
1558a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    sw     $ra, 28($sp)
1559a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    .cfi_rel_offset 31, 28
1560590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    sw     $gp, 16($sp)
1561a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    sw     $t9, 12($sp)
1562a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    sw     $a2, 8($sp)
1563a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    sw     $a1, 4($sp)
1564a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    sw     $a0, 0($sp)
1565a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    move   $a1, $t1
1566a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    move   $a0, $t0
1567590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la     $t9, artIsAssignableFromCode
1568590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr   $t9               # (Class*, Class*)
1569590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    addiu  $sp, $sp, -16     # reserve argument slots on the stack
1570590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    addiu  $sp, $sp, 16
1571a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    lw     $ra, 28($sp)
1572590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    lw     $gp, 16($sp)
1573a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    lw     $t9, 12($sp)
1574a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    lw     $a2, 8($sp)
1575a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    lw     $a1, 4($sp)
1576a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    lw     $a0, 0($sp)
1577e34652f15f32666323052a6718a63248244f1e66Duane Sand    addiu  $sp, 32
1578a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    .cfi_adjust_cfa_offset -32
157986bcdc251f5ae22fcedd18c096ea538b7dbfa8cbIan Rogers    bnez   $v0, .Ldo_aput
1580a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    nop
1581fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_ALL_CALLEE_SAVES_FRAME
1582a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    move $a1, $a2
1583a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    la   $t9, artThrowArrayStoreException
15848d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr $zero, $t9                 # artThrowArrayStoreException(Class*, Class*, Thread*)
15851d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    move $a2, rSELF                 # pass Thread::Current
1586a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersEND art_quick_aput_obj
15875bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
15880cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze// Macros taking opportunity of code similarities for downcalls.
15890cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.macro ONE_ARG_REF_DOWNCALL name, entrypoint, return
15900cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    .extern \entrypoint
15910cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeENTRY \name
15920cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    SETUP_SAVE_REFS_ONLY_FRAME        # save callee saves in case of GC
15930cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    la      $t9, \entrypoint
15940cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    jalr    $t9                       # (field_idx, Thread*)
15950cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    move    $a1, rSELF                # pass Thread::Current
15960cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    \return                           # RETURN_IF_NO_EXCEPTION or RETURN_IF_ZERO
15970cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeEND \name
15980cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.endm
159937f05ef45e0393de812d51261dc293240c17294dFred Shih
16000cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.macro TWO_ARG_REF_DOWNCALL name, entrypoint, return
16010cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    .extern \entrypoint
16020cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeENTRY \name
16030cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    SETUP_SAVE_REFS_ONLY_FRAME        # save callee saves in case of GC
16040cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    la      $t9, \entrypoint
16050cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    jalr    $t9                       # (field_idx, Object*, Thread*) or
16060cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze                                      # (field_idx, new_val, Thread*)
16070cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    move    $a2, rSELF                # pass Thread::Current
16080cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    \return                           # RETURN_IF_NO_EXCEPTION or RETURN_IF_ZERO
16090cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeEND \name
16100cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.endm
161137f05ef45e0393de812d51261dc293240c17294dFred Shih
16120cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.macro THREE_ARG_REF_DOWNCALL name, entrypoint, return
16130cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    .extern \entrypoint
16140cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeENTRY \name
16150cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    SETUP_SAVE_REFS_ONLY_FRAME        # save callee saves in case of GC
16160cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    la      $t9, \entrypoint
16170cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    jalr    $t9                       # (field_idx, Object*, new_val, Thread*)
16180cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    move    $a3, rSELF                # pass Thread::Current
16190cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    \return                           # RETURN_IF_NO_EXCEPTION or RETURN_IF_ZERO
16200cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeEND \name
16210cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.endm
16225bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
16230cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.macro FOUR_ARG_REF_DOWNCALL name, entrypoint, return
16240cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    .extern \entrypoint
16250cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeENTRY \name
16260cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    SETUP_SAVE_REFS_ONLY_FRAME        # save callee saves in case of GC
16270cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    la      $t9, \entrypoint
16280cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    jalr    $t9                       # (field_idx, Object*, 64-bit new_val, Thread*) or
16290cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze                                      # (field_idx, 64-bit new_val, Thread*)
16300cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze                                      # Note that a 64-bit new_val needs to be aligned with
16310cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze                                      # an even-numbered register, hence A1 may be skipped
16320cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze                                      # for new_val to reside in A2-A3.
16330cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    sw      rSELF, 16($sp)            # pass Thread::Current
16340cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze    \return                           # RETURN_IF_NO_EXCEPTION or RETURN_IF_ZERO
16350cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeEND \name
16360cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze.endm
16375bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
16385bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
16390cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey Frunze     * Called by managed code to resolve a static/instance field and load/store a value.
1640809f5b1652eb68ad496af138370d2cc198510322Roland Levillain     *
1641809f5b1652eb68ad496af138370d2cc198510322Roland Levillain     * Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are
1642809f5b1652eb68ad496af138370d2cc198510322Roland Levillain     * defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc.
16435bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
16440cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCompiledCode, RETURN_IF_NO_EXCEPTION
16450cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCompiledCode, RETURN_IF_NO_EXCEPTION
16460cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCompiledCode, RETURN_IF_NO_EXCEPTION
16470cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCompiledCode, RETURN_IF_NO_EXCEPTION
16480cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCompiledCode, RETURN_IF_NO_EXCEPTION
16490cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCompiledCode, RETURN_IF_NO_EXCEPTION
16500cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCompiledCode, RETURN_IF_NO_EXCEPTION
16510cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION
16520cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION
16530cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION
16540cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION
16550cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION
16560cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION
16570cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCompiledCode, RETURN_IF_NO_EXCEPTION
16580cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCompiledCode, RETURN_IF_ZERO
16590cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCompiledCode, RETURN_IF_ZERO
16600cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCompiledCode, RETURN_IF_ZERO
16610cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCompiledCode, RETURN_IF_ZERO
16620cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeFOUR_ARG_REF_DOWNCALL art_quick_set64_static, artSet64StaticFromCompiledCode, RETURN_IF_ZERO
16630cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTHREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCompiledCode, RETURN_IF_ZERO
16640cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTHREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCompiledCode, RETURN_IF_ZERO
16650cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTHREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCompiledCode, RETURN_IF_ZERO
16660cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeTHREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCompiledCode, RETURN_IF_ZERO
16670cb124219e986a27c40001a1b22ea7ebd833a2d8Alexey FrunzeFOUR_ARG_REF_DOWNCALL art_quick_set64_instance, artSet64InstanceFromCompiledCode, RETURN_IF_ZERO
16685bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
1669a3c382738bc54f464a57e2b51b51ad305eb03dd2Vladimir Marko// Macro to facilitate adding new allocation entrypoints.
16705ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko.macro ONE_ARG_DOWNCALL name, entrypoint, return
16715ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko    .extern \entrypoint
16725ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir MarkoENTRY \name
1673fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_ONLY_FRAME        # save callee saves in case of GC
1674590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la      $t9, \entrypoint
1675590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr    $t9
16765ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko    move    $a1, rSELF                # pass Thread::Current
16775ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko    \return
16785ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir MarkoEND \name
16795ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko.endm
16805ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko
1681cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier.macro TWO_ARG_DOWNCALL name, entrypoint, return
1682cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier    .extern \entrypoint
1683cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu ChartierENTRY \name
1684fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_ONLY_FRAME        # save callee saves in case of GC
1685590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la      $t9, \entrypoint
1686590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr    $t9
16871d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    move    $a2, rSELF                # pass Thread::Current
1688cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier    \return
1689cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu ChartierEND \name
1690cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier.endm
16915bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
1692cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier.macro THREE_ARG_DOWNCALL name, entrypoint, return
1693cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier    .extern \entrypoint
1694cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu ChartierENTRY \name
1695fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_ONLY_FRAME        # save callee saves in case of GC
1696590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la      $t9, \entrypoint
1697590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr    $t9
16981d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers    move    $a3, rSELF                # pass Thread::Current
1699cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier    \return
1700cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu ChartierEND \name
1701cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier.endm
17025bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
1703848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao.macro FOUR_ARG_DOWNCALL name, entrypoint, return
1704848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    .extern \entrypoint
1705848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff HaoENTRY \name
1706fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_ONLY_FRAME        # save callee saves in case of GC
1707590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la      $t9, \entrypoint
1708590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr    $t9
1709a3c382738bc54f464a57e2b51b51ad305eb03dd2Vladimir Marko    sw      rSELF, 16($sp)            # pass Thread::Current
1710848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    \return
1711848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff HaoEND \name
1712848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao.endm
1713848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao
17147410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier// Generate the allocation entrypoints for each allocator.
1715854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_FOR_NON_TLAB_ALLOCATORS
1716854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// Comment out allocators that have mips specific asm.
1717854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB)
1718854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab, RegionTLAB)
1719854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB)
1720854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB)
1721854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region_tlab, RegionTLAB)
1722854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region_tlab, RegionTLAB)
1723854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED32(_region_tlab, RegionTLAB)
1724854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED64(_region_tlab, RegionTLAB)
1725854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_BYTES(_region_tlab, RegionTLAB)
1726854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_CHARS(_region_tlab, RegionTLAB)
1727854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_STRING(_region_tlab, RegionTLAB)
1728854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1729854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB)
1730854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB)
1731854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB)
1732854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB)
1733854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_tlab, TLAB)
1734854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_tlab, TLAB)
1735854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED32(_tlab, TLAB)
1736854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED64(_tlab, TLAB)
1737854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_BYTES(_tlab, TLAB)
1738854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_CHARS(_tlab, TLAB)
1739854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_STRING(_tlab, TLAB)
174010d4c08c0ea9df0a85a11e1c77974df24078c0ecHiroshi Yamauchi
17412449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic// A hand-written override for:
17422449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic//   GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_rosalloc, RosAlloc)
17432449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic//   GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_rosalloc, RosAlloc)
1744854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro ART_QUICK_ALLOC_OBJECT_ROSALLOC c_name, cxx_name, isInitialized
1745854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicENTRY_NO_GP \c_name
17462449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # Fast path rosalloc allocation
17472449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # a0: type
17482449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # s1: Thread::Current
17492449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # -----------------------------
17502449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # t1: object size
17512449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # t2: rosalloc run
17522449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # t3: thread stack top offset
17532449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # t4: thread stack bottom offset
17542449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # v0: free list head
17552449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    #
17562449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # t5, t6 : temps
17572449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    lw    $t3, THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET($s1)        # Check if thread local allocation
17582449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    lw    $t4, THREAD_LOCAL_ALLOC_STACK_END_OFFSET($s1)        # stack has any room left.
17592449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    bgeu  $t3, $t4, .Lslow_path_\c_name
17602449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic
17612449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    lw    $t1, MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET($a0)  # Load object size (t1).
17622449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    li    $t5, ROSALLOC_MAX_THREAD_LOCAL_BRACKET_SIZE          # Check if size is for a thread local
17632449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic                                                               # allocation. Also does the
17642449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic                                                               # initialized and finalizable checks.
1765854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # When isInitialized == 0, then the class is potentially not yet initialized.
1766854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # If the class is not yet initialized, the object size will be very large to force the branch
1767854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # below to be taken.
1768854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    #
1769854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # See InitializeClassVisitors in class-inl.h for more details.
17702449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    bgtu  $t1, $t5, .Lslow_path_\c_name
17712449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic
17722449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # Compute the rosalloc bracket index from the size. Since the size is already aligned we can
17732449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # combine the two shifts together.
17742449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    srl   $t1, $t1, (ROSALLOC_BRACKET_QUANTUM_SIZE_SHIFT - POINTER_SIZE_SHIFT)
17752449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic
17762449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    addu  $t2, $t1, $s1
17772449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    lw    $t2, (THREAD_ROSALLOC_RUNS_OFFSET - __SIZEOF_POINTER__)($t2)  # Load rosalloc run (t2).
17782449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic
17792449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # Load the free list head (v0).
17802449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # NOTE: this will be the return val.
17812449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    lw    $v0, (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_HEAD_OFFSET)($t2)
17822449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    beqz  $v0, .Lslow_path_\c_name
17832449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    nop
17842449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic
17852449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # Load the next pointer of the head and update the list head with the next pointer.
17862449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    lw    $t5, ROSALLOC_SLOT_NEXT_OFFSET($v0)
17872449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    sw    $t5, (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_HEAD_OFFSET)($t2)
17882449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic
17892449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # Store the class pointer in the header. This also overwrites the first pointer. The offsets are
17902449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # asserted to match.
17912449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic
17922449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic#if ROSALLOC_SLOT_NEXT_OFFSET != MIRROR_OBJECT_CLASS_OFFSET
17932449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic#error "Class pointer needs to overwrite next pointer."
17942449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic#endif
17952449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic
17962449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    POISON_HEAP_REF $a0
17972449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    sw    $a0, MIRROR_OBJECT_CLASS_OFFSET($v0)
17982449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic
17992449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # Push the new object onto the thread local allocation stack and increment the thread local
18002449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # allocation stack top.
18012449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    sw    $v0, 0($t3)
18022449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    addiu $t3, $t3, COMPRESSED_REFERENCE_SIZE
18032449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    sw    $t3, THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET($s1)
18042449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic
18052449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    # Decrement the size of the free list.
18062449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    lw    $t5, (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_SIZE_OFFSET)($t2)
18072449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    addiu $t5, $t5, -1
18082449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    sw    $t5, (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_SIZE_OFFSET)($t2)
18092449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic
1810854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.if \isInitialized == 0
1811854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # This barrier is only necessary when the allocation also requires a class initialization check.
1812854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    #
1813854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # If the class is already observably initialized, then new-instance allocations are protected
1814854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # from publishing by the compiler which inserts its own StoreStore barrier.
18152449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    sync                                                          # Fence.
1816854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endif
18172449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    jalr  $zero, $ra
18182449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    nop
18192449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic
18202449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic  .Lslow_path_\c_name:
1821854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addiu $t9, $t9, (.Lslow_path_\c_name - \c_name) + 4
1822854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    .cpload $t9
18232449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    SETUP_SAVE_REFS_ONLY_FRAME
18242449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    la    $t9, \cxx_name
18252449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    jalr  $t9
18262449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    move  $a1, $s1                                                # Pass self as argument.
18272449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic    RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
18282449e5c95b536791fc11344530365b36ae18e0dfGoran JakovljevicEND \c_name
18292449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic.endm
18302449e5c95b536791fc11344530365b36ae18e0dfGoran Jakovljevic
1831854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicART_QUICK_ALLOC_OBJECT_ROSALLOC art_quick_alloc_object_resolved_rosalloc, artAllocObjectFromCodeResolvedRosAlloc, /* isInitialized */ 0
1832854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicART_QUICK_ALLOC_OBJECT_ROSALLOC art_quick_alloc_object_initialized_rosalloc, artAllocObjectFromCodeInitializedRosAlloc, /* isInitialized */ 1
1833854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1834854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// The common fast path code for art_quick_alloc_object_resolved/initialized_tlab
1835854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// and art_quick_alloc_object_resolved/initialized_region_tlab.
1836854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic//
1837854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// a0: type, s1(rSELF): Thread::Current.
1838854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// Need to preserve a0 to the slow path.
1839854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic//
1840854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// If isInitialized=1 then the compiler assumes the object's class has already been initialized.
1841854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// If isInitialized=0 the compiler can only assume it's been at least resolved.
1842854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro ALLOC_OBJECT_RESOLVED_TLAB_FAST_PATH slowPathLabel isInitialized
1843854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    lw    $v0, THREAD_LOCAL_POS_OFFSET(rSELF)          # Load thread_local_pos.
1844854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    lw    $a2, THREAD_LOCAL_END_OFFSET(rSELF)          # Load thread_local_end.
1845854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    subu  $a3, $a2, $v0                                # Compute the remaining buffer size.
1846854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    lw    $t0, MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET($a0)  # Load the object size.
1847854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1848854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # When isInitialized == 0, then the class is potentially not yet initialized.
1849854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # If the class is not yet initialized, the object size will be very large to force the branch
1850854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # below to be taken.
1851854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    #
1852854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # See InitializeClassVisitors in class-inl.h for more details.
1853854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    bgtu  $t0, $a3, \slowPathLabel                     # Check if it fits.
1854854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addu  $t1, $v0, $t0                                # Add object size to tlab pos (in branch
1855854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic                                                       # delay slot).
1856854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # "Point of no slow path". Won't go to the slow path from here on.
1857854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    sw    $t1, THREAD_LOCAL_POS_OFFSET(rSELF)          # Store new thread_local_pos.
1858854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    lw    $a2, THREAD_LOCAL_OBJECTS_OFFSET(rSELF)      # Increment thread_local_objects.
1859854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addiu $a2, $a2, 1
1860854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    sw    $a2, THREAD_LOCAL_OBJECTS_OFFSET(rSELF)
1861854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    POISON_HEAP_REF $a0
1862854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    sw    $a0, MIRROR_OBJECT_CLASS_OFFSET($v0)         # Store the class pointer.
1863854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1864854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.if \isInitialized == 0
1865854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # This barrier is only necessary when the allocation also requires a class initialization check.
1866854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    #
1867854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # If the class is already observably initialized, then new-instance allocations are protected
1868854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # from publishing by the compiler which inserts its own StoreStore barrier.
1869854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    sync                                               # Fence.
1870854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endif
1871854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    jalr  $zero, $ra
1872854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    nop
1873854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm
1874854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1875854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// The common code for art_quick_alloc_object_resolved/initialized_tlab
1876854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// and art_quick_alloc_object_resolved/initialized_region_tlab.
1877854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro GENERATE_ALLOC_OBJECT_TLAB name, entrypoint, isInitialized
1878854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicENTRY_NO_GP \name
1879854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Fast path tlab allocation.
1880854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # a0: type, s1(rSELF): Thread::Current.
1881854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    ALLOC_OBJECT_RESOLVED_TLAB_FAST_PATH .Lslow_path_\name, \isInitialized
1882854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.Lslow_path_\name:
1883854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addiu $t9, $t9, (.Lslow_path_\name - \name) + 4
1884854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    .cpload $t9
1885854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    SETUP_SAVE_REFS_ONLY_FRAME                         # Save callee saves in case of GC.
1886854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    la    $t9, \entrypoint
1887854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    jalr  $t9                                          # (mirror::Class*, Thread*)
1888854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    move  $a1, rSELF                                   # Pass Thread::Current.
1889854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
1890854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicEND \name
1891854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm
1892854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1893854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_OBJECT_TLAB art_quick_alloc_object_resolved_region_tlab, artAllocObjectFromCodeResolvedRegionTLAB, /* isInitialized */ 0
1894854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_OBJECT_TLAB art_quick_alloc_object_initialized_region_tlab, artAllocObjectFromCodeInitializedRegionTLAB, /* isInitialized */ 1
1895854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_OBJECT_TLAB art_quick_alloc_object_resolved_tlab, artAllocObjectFromCodeResolvedTLAB, /* isInitialized */ 0
1896854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_OBJECT_TLAB art_quick_alloc_object_initialized_tlab, artAllocObjectFromCodeInitializedTLAB, /* isInitialized */ 1
1897854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1898854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// The common fast path code for art_quick_alloc_array_resolved/initialized_tlab
1899854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// and art_quick_alloc_array_resolved/initialized_region_tlab.
1900854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic//
1901854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// a0: type, a1: component_count, a2: total_size, s1(rSELF): Thread::Current.
1902854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic// Need to preserve a0 and a1 to the slow path.
1903854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED_WITH_SIZE slowPathLabel
1904854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    li    $a3, OBJECT_ALIGNMENT_MASK_TOGGLED           # Apply alignemnt mask
1905854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    and   $a2, $a2, $a3                                # (addr + 7) & ~7.
1906854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1907854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    lw    $v0, THREAD_LOCAL_POS_OFFSET(rSELF)          # Load thread_local_pos.
1908854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    lw    $t1, THREAD_LOCAL_END_OFFSET(rSELF)          # Load thread_local_end.
1909854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    subu  $t2, $t1, $v0                                # Compute the remaining buffer size.
1910854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    bgtu  $a2, $t2, \slowPathLabel                     # Check if it fits.
1911854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addu  $a2, $v0, $a2                                # Add object size to tlab pos (in branch
1912854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic                                                       # delay slot).
1913854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1914854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # "Point of no slow path". Won't go to the slow path from here on.
1915854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    sw    $a2, THREAD_LOCAL_POS_OFFSET(rSELF)          # Store new thread_local_pos.
1916854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    lw    $a2, THREAD_LOCAL_OBJECTS_OFFSET(rSELF)      # Increment thread_local_objects.
1917854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addiu $a2, $a2, 1
1918854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    sw    $a2, THREAD_LOCAL_OBJECTS_OFFSET(rSELF)
1919854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    POISON_HEAP_REF $a0
1920854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    sw    $a0, MIRROR_OBJECT_CLASS_OFFSET($v0)         # Store the class pointer.
1921854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    jalr  $zero, $ra
1922854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    sw    $a1, MIRROR_ARRAY_LENGTH_OFFSET($v0)         # Store the array length.
1923854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm
1924854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1925854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro GENERATE_ALLOC_ARRAY_TLAB name, entrypoint, size_setup
1926854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicENTRY_NO_GP \name
1927854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Fast path array allocation for region tlab allocation.
1928854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # a0: mirror::Class* type
1929854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # a1: int32_t component_count
1930854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # s1(rSELF): Thread::Current
1931854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    \size_setup .Lslow_path_\name
1932854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED_WITH_SIZE .Lslow_path_\name
1933854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.Lslow_path_\name:
1934854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # a0: mirror::Class* type
1935854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # a1: int32_t component_count
1936854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # a2: Thread* self
1937854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addiu $t9, $t9, (.Lslow_path_\name - \name) + 4
1938854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    .cpload $t9
1939854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    SETUP_SAVE_REFS_ONLY_FRAME                         # Save callee saves in case of GC.
1940854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    la    $t9, \entrypoint
1941854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    jalr  $t9
1942854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    move  $a2, rSELF                                   # Pass Thread::Current.
1943854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
1944854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicEND \name
1945854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm
1946854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1947854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro COMPUTE_ARRAY_SIZE_UNKNOWN slow_path
1948854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    break                                              # We should never enter here.
1949854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic                                                       # Code below is for reference.
1950854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic                                                       # Possibly a large object, go slow.
1951854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic                                                       # Also does negative array size check.
1952854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    li    $a2, ((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_WIDE_ARRAY_DATA_OFFSET) / 8)
1953854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    bgtu  $a1, $a2, \slow_path
1954854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic                                                       # Array classes are never finalizable
1955854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic                                                       # or uninitialized, no need to check.
1956854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    lw    $a3, MIRROR_CLASS_COMPONENT_TYPE_OFFSET($a0) # Load component type.
1957854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    UNPOISON_HEAP_REF $a3
1958854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    lw    $a3, MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET($a3)
1959854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    srl   $a3, $a3, PRIMITIVE_TYPE_SIZE_SHIFT_SHIFT    # Component size shift is in high 16 bits.
1960854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    sllv  $a2, $a1, $a3                                # Calculate data size.
1961854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic                                                       # Add array data offset and alignment.
1962854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addiu $a2, $a2, (MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK)
1963854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic#if MIRROR_WIDE_ARRAY_DATA_OFFSET != MIRROR_INT_ARRAY_DATA_OFFSET + 4
1964854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic#error Long array data offset must be 4 greater than int array data offset.
1965854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic#endif
1966854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1967854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addiu $a3, $a3, 1                                  # Add 4 to the length only if the component
1968854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    andi  $a3, $a3, 4                                  # size shift is 3 (for 64 bit alignment).
1969854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addu  $a2, $a2, $a3
1970854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm
1971854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1972854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro COMPUTE_ARRAY_SIZE_8 slow_path
1973854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Possibly a large object, go slow.
1974854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Also does negative array size check.
1975854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    li    $a2, (MIN_LARGE_OBJECT_THRESHOLD - MIRROR_INT_ARRAY_DATA_OFFSET)
1976854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    bgtu  $a1, $a2, \slow_path
1977854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Add array data offset and alignment (in branch delay slot).
1978854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addiu $a2, $a1, (MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK)
1979854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm
1980854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1981854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro COMPUTE_ARRAY_SIZE_16 slow_path
1982854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Possibly a large object, go slow.
1983854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Also does negative array size check.
1984854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    li    $a2, ((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_INT_ARRAY_DATA_OFFSET) / 2)
1985854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    bgtu  $a1, $a2, \slow_path
1986854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    sll   $a2, $a1, 1
1987854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Add array data offset and alignment.
1988854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addiu $a2, $a2, (MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK)
1989854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm
1990854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
1991854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro COMPUTE_ARRAY_SIZE_32 slow_path
1992854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Possibly a large object, go slow.
1993854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Also does negative array size check.
1994854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    li    $a2, ((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_INT_ARRAY_DATA_OFFSET) / 4)
1995854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    bgtu  $a1, $a2, \slow_path
1996854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    sll   $a2, $a1, 2
1997854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Add array data offset and alignment.
1998854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addiu $a2, $a2, (MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK)
1999854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm
2000854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
2001854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.macro COMPUTE_ARRAY_SIZE_64 slow_path
2002854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Possibly a large object, go slow.
2003854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Also does negative array size check.
2004854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    li    $a2, ((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_LONG_ARRAY_DATA_OFFSET) / 8)
2005854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    bgtu  $a1, $a2, \slow_path
2006854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    sll   $a2, $a1, 3
2007854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    # Add array data offset and alignment.
2008854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic    addiu $a2, $a2, (MIRROR_WIDE_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK)
2009854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic.endm
20103b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi
2011854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_UNKNOWN
2012854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved8_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_8
2013854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved16_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_16
2014854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved32_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_32
2015854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved64_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_64
2016854df416f12c48b52239fe163ab8a7fcac4cddd3Goran Jakovljevic
2017854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_UNKNOWN
2018854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved8_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_8
2019854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved16_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_16
2020854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved32_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_32
2021854df416f12c48b52239fe163ab8a7fcac4cddd3Goran JakovljevicGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved64_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_64
202210d4c08c0ea9df0a85a11e1c77974df24078c0ecHiroshi Yamauchi
2023c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze// Macro for string and type resolution and initialization.
2024c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze// $a0 is both input and output.
202519428ad0cc3494714470328fb6c74fa3e92a187bAlexey Frunze.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL name, entrypoint, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET
2026c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    .extern \entrypoint
2027c61c0761150340263160b568d8a952e9a3d80d56Alexey FrunzeENTRY_NO_GP \name
202819428ad0cc3494714470328fb6c74fa3e92a187bAlexey Frunze    SETUP_SAVE_EVERYTHING_FRAME \runtime_method_offset  # Save everything in case of GC.
2029c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    move    $s2, $gp                  # Preserve $gp across the call for exception delivery.
2030c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    la      $t9, \entrypoint
2031c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    jalr    $t9                       # (uint32_t index, Thread*)
2032c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    move    $a1, rSELF                # Pass Thread::Current (in delay slot).
2033c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    beqz    $v0, 1f                   # Success?
2034c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    move    $a0, $v0                  # Move result to $a0 (in delay slot).
2035c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    RESTORE_SAVE_EVERYTHING_FRAME 0   # Restore everything except $a0.
2036c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    jalr    $zero, $ra                # Return on success.
2037c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    nop
2038c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze1:
2039c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    move    $gp, $s2
2040c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    DELIVER_PENDING_EXCEPTION_FRAME_READY
2041c61c0761150340263160b568d8a952e9a3d80d56Alexey FrunzeEND \name
2042c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze.endm
2043c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze
204419428ad0cc3494714470328fb6c74fa3e92a187bAlexey Frunze.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT name, entrypoint
204519428ad0cc3494714470328fb6c74fa3e92a187bAlexey Frunze    ONE_ARG_SAVE_EVERYTHING_DOWNCALL \name, \entrypoint, RUNTIME_SAVE_EVERYTHING_FOR_CLINIT_METHOD_OFFSET
204619428ad0cc3494714470328fb6c74fa3e92a187bAlexey Frunze.endm
204719428ad0cc3494714470328fb6c74fa3e92a187bAlexey Frunze
20485bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
20491cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe     * Entry from managed code to resolve a string, this stub will allocate a String and deliver an
20505ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko     * exception on error. On success the String is returned. A0 holds the string index. The fast
20515ea536aa4a6414db01beaf6f8bd8cb9adc5cfc92Vladimir Marko     * path check for hit in strings cache has already been performed.
20521cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe     */
2053c61c0761150340263160b568d8a952e9a3d80d56Alexey FrunzeONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode
20541cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe
20551cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    /*
20561cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe     * Entry from managed code when uninitialized static storage, this stub will run the class
20571cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe     * initializer and deliver the exception on error. On success the static storage base is
20581cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe     * returned.
20591cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe     */
206019428ad0cc3494714470328fb6c74fa3e92a187bAlexey FrunzeONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_static_storage, artInitializeStaticStorageFromCode
20611cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe
20621cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    /*
20631cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe     * Entry from managed code when dex cache misses for a type_idx.
20641cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe     */
206519428ad0cc3494714470328fb6c74fa3e92a187bAlexey FrunzeONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_type, artInitializeTypeFromCode
20661cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe
20671cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    /*
20681cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe     * Entry from managed code when type_idx needs to be checked for access and dex cache may also
20691cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe     * miss.
20701cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe     */
2071c61c0761150340263160b568d8a952e9a3d80d56Alexey FrunzeONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode
20721cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe
20731cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe    /*
207457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers     * Called by managed code when the value in rSUSPEND has been decremented to 0.
20755bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
2076d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao    .extern artTestSuspendFromCode
2077952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir MarkoENTRY_NO_GP art_quick_test_suspend
207819428ad0cc3494714470328fb6c74fa3e92a187bAlexey Frunze    SETUP_SAVE_EVERYTHING_FRAME RUNTIME_SAVE_EVERYTHING_FOR_SUSPEND_CHECK_METHOD_OFFSET
207919428ad0cc3494714470328fb6c74fa3e92a187bAlexey Frunze                                                     # save everything for stack crawl
2080590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la     $t9, artTestSuspendFromCode
2081952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    jalr   $t9                                       # (Thread*)
20827fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    move   $a0, rSELF
2083fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    RESTORE_SAVE_EVERYTHING_FRAME
2084952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    jalr   $zero, $ra
2085952dbb19cd094b8bfb01dbb33e0878db429e499aVladimir Marko    nop
2086d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_test_suspend
20875bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
20885bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
20895bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * Called by managed code that is attempting to call a method on a proxy class. On entry
2090590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic     * a0 holds the proxy method; a1, a2 and a3 may contain arguments.
20915bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
20925fa60c3db4208df407113b5a69d295a9c93d53b1Jeff Hao    .extern artQuickProxyInvokeHandler
2093d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoENTRY art_quick_proxy_invoke_handler
2094fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_A0
2095735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    move    $a2, rSELF                  # pass Thread::Current
2096590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la      $t9, artQuickProxyInvokeHandler
2097590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr    $t9                         # (Method* proxy method, receiver, Thread*, SP)
2098735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu   $a3, $sp, ARG_SLOT_SIZE     # pass $sp (remove arg slots)
20991b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lw      $t7, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
2100fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    RESTORE_SAVE_REFS_AND_ARGS_FRAME
21011b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    bnez    $t7, 1f
2102e34652f15f32666323052a6718a63248244f1e66Duane Sand    # don't care if $v0 and/or $v1 are modified, when exception branch taken
2103e34652f15f32666323052a6718a63248244f1e66Duane Sand    MTD     $v0, $v1, $f0, $f1          # move float value to return value
21048d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr    $zero, $ra
2105e34652f15f32666323052a6718a63248244f1e66Duane Sand    nop
21065bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee1:
21075bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    DELIVER_PENDING_EXCEPTION
2108d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_proxy_invoke_handler
21095bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
211088474b416eb257078e590bf9bc7957cee604a186Jeff Hao    /*
211159028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic     * Called to resolve an imt conflict.
211259028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic     * a0 is the conflict ArtMethod.
21131b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze     * t7 is a hidden argument that holds the target interface method's dex method index.
211459028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic     *
2115279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze     * Note that this stub writes to v0-v1, a0, t2-t9, f0-f7.
211688474b416eb257078e590bf9bc7957cee604a186Jeff Hao     */
2117279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .extern artLookupResolvedMethod
2118279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .extern __atomic_load_8         # For int64_t std::atomic::load(std::memory_order).
211913738bf7c769638b7922cb2477471ad382632bc2Douglas LeungENTRY art_quick_imt_conflict_trampoline
2120279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    SETUP_SAVE_REFS_AND_ARGS_FRAME_REGISTERS_ONLY /* save_s4_thru_s8 */ 0
2121279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze
2122279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $t8, FRAME_SIZE_SAVE_REFS_AND_ARGS($sp)  # $t8 = referrer.
21235122e6ba34d46851cd89f2ad55bf6bb067e038d6Vladimir Marko    // If the method is obsolete, just go through the dex cache miss slow path.
21245122e6ba34d46851cd89f2ad55bf6bb067e038d6Vladimir Marko    // The obsolete flag is set with suspended threads, so we do not need an acquire operation here.
21255122e6ba34d46851cd89f2ad55bf6bb067e038d6Vladimir Marko    lw      $t9, ART_METHOD_ACCESS_FLAGS_OFFSET($t8)  # $t9 = access flags.
21265122e6ba34d46851cd89f2ad55bf6bb067e038d6Vladimir Marko    sll     $t9, $t9, 31 - ACC_OBSOLETE_METHOD_SHIFT  # Move obsolete method bit to sign bit.
21275122e6ba34d46851cd89f2ad55bf6bb067e038d6Vladimir Marko    bltz    $t9, .Limt_conflict_trampoline_dex_cache_miss
21285122e6ba34d46851cd89f2ad55bf6bb067e038d6Vladimir Marko    lw      $t8, ART_METHOD_DECLARING_CLASS_OFFSET($t8)  # $t8 = declaring class (no read barrier).
21295122e6ba34d46851cd89f2ad55bf6bb067e038d6Vladimir Marko    lw      $t8, MIRROR_CLASS_DEX_CACHE_OFFSET($t8)  # $t8 = dex cache (without read barrier).
21305122e6ba34d46851cd89f2ad55bf6bb067e038d6Vladimir Marko    UNPOISON_HEAP_REF $t8
2131279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    la      $t9, __atomic_load_8
2132279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    addiu   $sp, $sp, -ARG_SLOT_SIZE                # Reserve argument slots on the stack.
2133279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_adjust_cfa_offset ARG_SLOT_SIZE
21345122e6ba34d46851cd89f2ad55bf6bb067e038d6Vladimir Marko    lw      $t8, MIRROR_DEX_CACHE_RESOLVED_METHODS_OFFSET($t8)  # $t8 = dex cache methods array.
2135279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze
2136279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    move    $s2, $t7                                # $s2 = method index (callee-saved).
2137279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $s3, ART_METHOD_JNI_OFFSET_32($a0)      # $s3 = ImtConflictTable (callee-saved).
2138279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze
2139279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    sll     $t7, $t7, 32 - METHOD_DEX_CACHE_HASH_BITS  # $t7 = slot index in top bits, zeroes below.
2140279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    srl     $t7, $t7, 32 - METHOD_DEX_CACHE_HASH_BITS - (POINTER_SIZE_SHIFT + 1)
2141279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze                                                    # $t7 = slot offset.
2142279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze
2143279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    li      $a1, STD_MEMORY_ORDER_RELAXED           # $a1 = std::memory_order_relaxed.
2144279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    jalr    $t9                                     # [$v0, $v1] = __atomic_load_8($a0, $a1).
2145279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    addu    $a0, $t8, $t7                           # $a0 = DexCache method slot address.
2146279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze
2147279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    bne     $v1, $s2, .Limt_conflict_trampoline_dex_cache_miss  # Branch if method index miss.
2148279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    addiu   $sp, $sp, ARG_SLOT_SIZE                 # Remove argument slots from the stack.
2149279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_adjust_cfa_offset -ARG_SLOT_SIZE
215059028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic
215159028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic.Limt_table_iterate:
2152279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $t8, 0($s3)                             # Load next entry in ImtConflictTable.
215359028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic    # Branch if found.
2154279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    beq     $t8, $v0, .Limt_table_found
215559028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic    nop
215659028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic    # If the entry is null, the interface method is not in the ImtConflictTable.
21571b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    beqz    $t8, .Lconflict_trampoline
215859028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic    nop
215959028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic    # Iterate over the entries of the ImtConflictTable.
216059028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic    b       .Limt_table_iterate
2161279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    addiu   $s3, $s3, 2 * __SIZEOF_POINTER__        # Iterate to the next entry.
216259028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic
216359028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic.Limt_table_found:
216459028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic    # We successfully hit an entry in the table. Load the target method and jump to it.
2165279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_remember_state
2166279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $a0, __SIZEOF_POINTER__($s3)
216759028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic    lw      $t9, ART_METHOD_QUICK_CODE_OFFSET_32($a0)
2168279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    RESTORE_SAVE_REFS_AND_ARGS_FRAME /* restore_s4_thru_s8 */ 0, /* remove_arg_slots */ 0
21691b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    jalr    $zero, $t9
217059028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic    nop
2171279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_restore_state
217259028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic
217359028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic.Lconflict_trampoline:
217459028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic    # Call the runtime stub to populate the ImtConflictTable and jump to the resolved method.
2175279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_remember_state
2176279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    RESTORE_SAVE_REFS_AND_ARGS_FRAME_GP             # Restore clobbered $gp.
2177279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    RESTORE_SAVE_REFS_AND_ARGS_FRAME_A1             # Restore this.
2178279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    move    $a0, $v0                                # Load interface method.
2179279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    INVOKE_TRAMPOLINE_BODY artInvokeInterfaceTrampoline, /* save_s4_thru_s8_only */ 1
2180279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_restore_state
2181279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze
2182279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze.Limt_conflict_trampoline_dex_cache_miss:
2183279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    # We're not creating a proper runtime method frame here,
2184279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    # artLookupResolvedMethod() is not allowed to walk the stack.
2185279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    RESTORE_SAVE_REFS_AND_ARGS_FRAME_GP             # Restore clobbered $gp.
2186279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    lw      $a1, FRAME_SIZE_SAVE_REFS_AND_ARGS($sp)  # $a1 = referrer.
2187279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    la      $t9, artLookupResolvedMethod
2188279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    addiu   $sp, $sp, -ARG_SLOT_SIZE                # Reserve argument slots on the stack.
2189279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_adjust_cfa_offset ARG_SLOT_SIZE
2190279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    jalr    $t9                                     # (uint32_t method_index, ArtMethod* referrer).
2191279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    move    $a0, $s2                                # $a0 = method index.
2192279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze
2193279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    # If the method wasn't resolved, skip the lookup and go to artInvokeInterfaceTrampoline().
2194279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    beqz    $v0, .Lconflict_trampoline
2195279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    addiu   $sp, $sp, ARG_SLOT_SIZE                 # Remove argument slots from the stack.
2196279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    .cfi_adjust_cfa_offset -ARG_SLOT_SIZE
2197279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze
2198279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    b       .Limt_table_iterate
2199279cfba1f6086c25d6737471bc4f66ae79f4e681Alexey Frunze    nop
220088474b416eb257078e590bf9bc7957cee604a186Jeff HaoEND art_quick_imt_conflict_trampoline
220188474b416eb257078e590bf9bc7957cee604a186Jeff Hao
2202468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    .extern artQuickResolutionTrampoline
2203468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_resolution_trampoline
2204fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_AND_ARGS_FRAME
2205735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    move    $a2, rSELF                    # pass Thread::Current
2206590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la      $t9, artQuickResolutionTrampoline
2207590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr    $t9                           # (Method* called, receiver, Thread*, SP)
2208735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu   $a3, $sp, ARG_SLOT_SIZE       # pass $sp (remove arg slots)
2209468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    beqz    $v0, 1f
2210735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw      $a0, ARG_SLOT_SIZE($sp)       # load resolved method to $a0
2211fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    RESTORE_SAVE_REFS_AND_ARGS_FRAME
221265d1b22d0b02fb0111f69013163c8170e68392f1Ian Rogers    move    $t9, $v0               # code pointer must be in $t9 to generate the global pointer
2213f96e8bdf47cfcbecd8ad8ebceb765e5a257ca143Douglas Leung    jalr    $zero, $t9             # tail call to method
22141984152ac92aad244ae15184d12f9ceade686b7bMathieu Chartier    nop
2215468532ea115657709bc32ee498e701a4c71762d4Ian Rogers1:
2216fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    RESTORE_SAVE_REFS_AND_ARGS_FRAME
2217468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    DELIVER_PENDING_EXCEPTION
2218468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_resolution_trampoline
2219468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
2220735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .extern artQuickGenericJniTrampoline
2221735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    .extern artQuickGenericJniEndTrampoline
2222735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas LeungENTRY art_quick_generic_jni_trampoline
2223fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_A0
2224735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    move    $s8, $sp               # save $sp to $s8
2225735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    move    $s3, $gp               # save $gp to $s3
2226735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung
2227735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    # prepare for call to artQuickGenericJniTrampoline(Thread*, SP)
2228735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    move    $a0, rSELF                     # pass Thread::Current
2229735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu   $a1, $sp, ARG_SLOT_SIZE        # save $sp (remove arg slots)
2230590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la      $t9, artQuickGenericJniTrampoline
2231590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr    $t9                            # (Thread*, SP)
2232735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu   $sp, $sp, -5120                # reserve space on the stack
2233735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung
2234735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    # The C call will have registered the complete save-frame on success.
2235735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    # The result of the call is:
2236735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    # v0: ptr to native code, 0 on error.
2237735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    # v1: ptr to the bottom of the used area of the alloca, can restore stack till here.
22381b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    beq     $v0, $zero, 2f         # check entry error
2239735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    move    $t9, $v0               # save the code ptr
2240735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    move    $sp, $v1               # release part of the alloca
2241735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung
2242735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    # Load parameters from stack into registers
2243735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw      $a0,   0($sp)
2244735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw      $a1,   4($sp)
2245735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw      $a2,   8($sp)
22461b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lw      $a3,  12($sp)
22471b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze
22481b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    # artQuickGenericJniTrampoline sets bit 0 of the native code address to 1
22491b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    # when the first two arguments are both single precision floats. This lets
22501b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    # us extract them properly from the stack and load into floating point
22511b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    # registers.
22521b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    MTD     $a0, $a1, $f12, $f13
22531b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    andi    $t0, $t9, 1
22541b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    xor     $t9, $t9, $t0
22551b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    bnez    $t0, 1f
22561b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    mtc1    $a1, $f14
22571b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    MTD     $a2, $a3, $f14, $f15
2258735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung
22591b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze1:
2260735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    jalr    $t9                    # native call
22611b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    nop
2262735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu   $sp, $sp, 16           # remove arg slots
2263735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung
2264735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    move    $gp, $s3               # restore $gp from $s3
2265735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung
2266735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    # result sign extension is handled in C code
2267735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    # prepare for call to artQuickGenericJniEndTrampoline(Thread*, result, result_f)
2268735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    move    $a0, rSELF             # pass Thread::Current
2269735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    move    $a2, $v0               # pass result
2270735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    move    $a3, $v1
2271715f43e1553330bc804cea2951be195473dc343dChris Larsen    addiu   $sp, $sp, -32          # reserve arg slots
2272590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la      $t9, artQuickGenericJniEndTrampoline
2273590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr    $t9
2274735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    s.d     $f0, 16($sp)           # pass result_f
2275735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung
2276735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    lw      $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
22771b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    bne     $t0, $zero, 2f         # check for pending exceptions
2278126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray
2279735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    move    $sp, $s8               # tear down the alloca
2280735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung
22811b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    # tear down the callee-save frame
2282fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    RESTORE_SAVE_REFS_AND_ARGS_FRAME
2283735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung
2284e34652f15f32666323052a6718a63248244f1e66Duane Sand    MTD     $v0, $v1, $f0, $f1     # move float value to return value
22858d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr    $zero, $ra
2286e34652f15f32666323052a6718a63248244f1e66Duane Sand    nop
2287735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung
22881b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze2:
22892196c651ecc77e49992c6c329dfce45f78ff46cbVladimir Marko    lw      $t0, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF)
22902196c651ecc77e49992c6c329dfce45f78ff46cbVladimir Marko    addiu   $sp, $t0, -1  // Remove the GenericJNI tag.
2291c61c0761150340263160b568d8a952e9a3d80d56Alexey Frunze    move    $gp, $s3               # restore $gp from $s3
2292126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray    # This will create a new save-all frame, required by the runtime.
2293735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    DELIVER_PENDING_EXCEPTION
2294735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas LeungEND art_quick_generic_jni_trampoline
22952da882315a61072664f7ce3c212307342e907207Andreas Gampe
2296468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    .extern artQuickToInterpreterBridge
2297468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_to_interpreter_bridge
2298fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_AND_ARGS_FRAME
2299735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    move    $a1, rSELF                          # pass Thread::Current
2300590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la      $t9, artQuickToInterpreterBridge
2301590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    jalr    $t9                                 # (Method* method, Thread*, SP)
2302735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung    addiu   $a2, $sp, ARG_SLOT_SIZE             # pass $sp (remove arg slots)
23031b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    lw      $t7, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
2304fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    RESTORE_SAVE_REFS_AND_ARGS_FRAME
23051b8464d17c2266763714ae18be7c4dc26e28bf61Alexey Frunze    bnez    $t7, 1f
2306e34652f15f32666323052a6718a63248244f1e66Duane Sand    # don't care if $v0 and/or $v1 are modified, when exception branch taken
2307e34652f15f32666323052a6718a63248244f1e66Duane Sand    MTD     $v0, $v1, $f0, $f1                  # move float value to return value
23088d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe    jalr    $zero, $ra
2309e34652f15f32666323052a6718a63248244f1e66Duane Sand    nop
23107db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers1:
23117db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers    DELIVER_PENDING_EXCEPTION
2312468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_to_interpreter_bridge
23137db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers
2314db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex Light    .extern artInvokeObsoleteMethod
2315db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex LightENTRY art_invoke_obsolete_method_stub
2316db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex Light    SETUP_SAVE_ALL_CALLEE_SAVES_FRAME
2317db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex Light    la      $t9, artInvokeObsoleteMethod
2318db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex Light    jalr    $t9                                 # (Method* method, Thread* self)
2319db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex Light    move    $a1, rSELF                          # pass Thread::Current
2320db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex LightEND art_invoke_obsolete_method_stub
2321db01a091aefbd78b56777f4c2e8c5e3f2d8c2712Alex Light
23225bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
2323725a957985171d712d5c048cc3d00ff14968784bjeffhao     * Routine that intercepts method calls and returns.
23245bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
2325d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao    .extern artInstrumentationMethodEntryFromCode
2326d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao    .extern artInstrumentationMethodExitFromCode
2327468532ea115657709bc32ee498e701a4c71762d4Ian RogersENTRY art_quick_instrumentation_entry
2328fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    SETUP_SAVE_REFS_AND_ARGS_FRAME
232960454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    sw      $a0, 28($sp)    # save arg0 in free arg slot
233060454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    addiu   $a3, $sp, ARG_SLOT_SIZE     # Pass $sp.
233160454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    la      $t9, artInstrumentationMethodEntryFromCode
233260454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    jalr    $t9             # (Method*, Object*, Thread*, SP)
233360454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    move    $a2, rSELF      # pass Thread::Current
233460454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    beqz    $v0, .Ldeliver_instrumentation_entry_exception
233560454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    move    $t9, $v0        # $t9 holds reference to code
233660454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    lw      $a0, 28($sp)    # restore arg0 from free arg slot
2337fd36f1f927c138575184a1f4c7ea4e7abb3e2dbfVladimir Marko    RESTORE_SAVE_REFS_AND_ARGS_FRAME
233860454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    la      $ra, art_quick_instrumentation_exit
233960454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    jalr    $zero, $t9      # call method, returning to art_quick_instrumentation_exit
234062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    nop
234160454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze.Ldeliver_instrumentation_entry_exception:
234260454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    RESTORE_SAVE_REFS_AND_ARGS_FRAME
234360454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    DELIVER_PENDING_EXCEPTION
2344468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_instrumentation_entry
2345735b8559d6dd26c610d4b97d72f25a092d9c8947Douglas Leung
234660454cb6094f33ea6b2194f46387b30073b91cb0Alexey FrunzeENTRY_NO_GP art_quick_instrumentation_exit
234760454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    move    $ra, $zero      # RA points here, so clobber with 0 for later checks.
234860454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    SETUP_SAVE_EVERYTHING_FRAME  # Allocates ARG_SLOT_SIZE bytes at the bottom of the stack.
234960454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    move    $s2, $gp             # Preserve $gp across the call for exception delivery.
235060454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze
235160454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    addiu   $a3, $sp, ARG_SLOT_SIZE+16  # Pass fpr_res pointer ($f0 in SAVE_EVERYTHING_FRAME).
235260454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    addiu   $a2, $sp, ARG_SLOT_SIZE+148 # Pass gpr_res pointer ($v0 in SAVE_EVERYTHING_FRAME).
235360454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    addiu   $a1, $sp, ARG_SLOT_SIZE     # Pass $sp.
235460454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    la      $t9, artInstrumentationMethodExitFromCode
235560454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    jalr    $t9                         # (Thread*, SP, gpr_res*, fpr_res*)
235660454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    move    $a0, rSELF                  # Pass Thread::Current.
235760454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze
235860454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    beqz    $v0, .Ldo_deliver_instrumentation_exception
235960454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    move    $gp, $s2        # Deliver exception if we got nullptr as function.
236060454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    bnez    $v1, .Ldeoptimize
236160454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze
236260454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    # Normal return.
236360454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    sw      $v0, (ARG_SLOT_SIZE+FRAME_SIZE_SAVE_EVERYTHING-4)($sp)  # Set return pc.
236460454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    RESTORE_SAVE_EVERYTHING_FRAME
236560454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    jalr    $zero, $ra
236625e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic    nop
236725e4d1ea98fedebf49ceee40ea67ec93e2407c53Goran Jakovljevic.Ldo_deliver_instrumentation_exception:
236860454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    DELIVER_PENDING_EXCEPTION_FRAME_READY
236960454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze.Ldeoptimize:
237060454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    b       art_quick_deoptimize
237160454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    sw      $v1, (ARG_SLOT_SIZE+FRAME_SIZE_SAVE_EVERYTHING-4)($sp)
237260454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze                            # Fake a call from instrumentation return pc.
2373468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND art_quick_instrumentation_exit
23745bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
237512051ea86ec27703b07b3d5c2cd4604b20f71810jeffhao    /*
237662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers     * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization
237762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers     * will long jump to the upcall with a special exception of -1.
237812051ea86ec27703b07b3d5c2cd4604b20f71810jeffhao     */
2379d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff Hao    .extern artDeoptimize
238060454cb6094f33ea6b2194f46387b30073b91cb0Alexey FrunzeENTRY_NO_GP_CUSTOM_CFA art_quick_deoptimize, ARG_SLOT_SIZE+FRAME_SIZE_SAVE_EVERYTHING
238160454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    # SETUP_SAVE_EVERYTHING_FRAME has been done by art_quick_instrumentation_exit.
238260454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 31, ARG_SLOT_SIZE+252
238360454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 30, ARG_SLOT_SIZE+248
238460454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 28, ARG_SLOT_SIZE+244
238560454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 25, ARG_SLOT_SIZE+240
238660454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 24, ARG_SLOT_SIZE+236
238760454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 23, ARG_SLOT_SIZE+232
238860454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 22, ARG_SLOT_SIZE+228
238960454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 21, ARG_SLOT_SIZE+224
239060454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 20, ARG_SLOT_SIZE+220
239160454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 19, ARG_SLOT_SIZE+216
239260454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 18, ARG_SLOT_SIZE+212
239360454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 17, ARG_SLOT_SIZE+208
239460454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 16, ARG_SLOT_SIZE+204
239560454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 15, ARG_SLOT_SIZE+200
239660454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 14, ARG_SLOT_SIZE+196
239760454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 13, ARG_SLOT_SIZE+192
239860454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 12, ARG_SLOT_SIZE+188
239960454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 11, ARG_SLOT_SIZE+184
240060454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 10, ARG_SLOT_SIZE+180
240160454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 9, ARG_SLOT_SIZE+176
240260454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 8, ARG_SLOT_SIZE+172
240360454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 7, ARG_SLOT_SIZE+168
240460454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 6, ARG_SLOT_SIZE+164
240560454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 5, ARG_SLOT_SIZE+160
240660454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 4, ARG_SLOT_SIZE+156
240760454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 3, ARG_SLOT_SIZE+152
240860454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 2, ARG_SLOT_SIZE+148
240960454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    .cfi_rel_offset 1, ARG_SLOT_SIZE+144
241060454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze
241160454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    la      $t9, artDeoptimize
241260454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    jalr    $t9             # (Thread*)
241360454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    move    $a0, rSELF      # pass Thread::current
241460454cb6094f33ea6b2194f46387b30073b91cb0Alexey Frunze    break
2415d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_deoptimize
241612051ea86ec27703b07b3d5c2cd4604b20f71810jeffhao
24175bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
24180747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz     * Compiled code has requested that we deoptimize into the interpreter. The deoptimization
24190747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz     * will long jump to the upcall with a special exception of -1.
24200747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz     */
24210747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz    .extern artDeoptimizeFromCompiledCode
242260454cb6094f33ea6b2194f46387b30073b91cb0Alexey FrunzeENTRY_NO_GP art_quick_deoptimize_from_compiled_code
2423239d6eaff0cbb5c4c0139f7053a012758799f186Vladimir Marko    SETUP_SAVE_EVERYTHING_FRAME
2424590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic    la       $t9, artDeoptimizeFromCompiledCode
24254e92c3ce7ef354620a785553bbada554fca83a67Nicolas Geoffray    jalr     $t9                            # (DeoptimizationKind, Thread*)
24264e92c3ce7ef354620a785553bbada554fca83a67Nicolas Geoffray    move     $a1, rSELF                     # pass Thread::current
24270747466fca310eedea5fc49e37d54f240a0b3c0fSebastien HertzEND art_quick_deoptimize_from_compiled_code
24280747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz
24290747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz    /*
24305bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * Long integer shift.  This is different from the generic 32/64-bit
24315bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * binary operations because vAA/vBB are 64-bit but vCC (the shift
24325bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * distance) is 32-bit.  Also, Dalvik requires us to ignore all but the low
24335bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * 6 bits.
24345bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * On entry:
24357fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao     *   $a0: low word
24367fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao     *   $a1: high word
24377fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao     *   $a2: shift count
24385bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
24391d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersENTRY_NO_GP art_quick_shl_long
24405bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /* shl-long vAA, vBB, vCC */
24417fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    sll     $v0, $a0, $a2                    #  rlo<- alo << (shift&31)
24427fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    not     $v1, $a2                         #  rhi<- 31-shift  (shift is 5b)
24437fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    srl     $a0, 1
24447fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    srl     $a0, $v1                         #  alo<- alo >> (32-(shift&31))
24457fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    sll     $v1, $a1, $a2                    #  rhi<- ahi << (shift&31)
24467fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    andi    $a2, 0x20                        #  shift< shift & 0x20
2447e34652f15f32666323052a6718a63248244f1e66Duane Sand    beqz    $a2, 1f
2448e34652f15f32666323052a6718a63248244f1e66Duane Sand    or      $v1, $a0                         #  rhi<- rhi | alo
2449e34652f15f32666323052a6718a63248244f1e66Duane Sand
2450e34652f15f32666323052a6718a63248244f1e66Duane Sand    move    $v1, $v0                         #  rhi<- rlo (if shift&0x20)
2451e34652f15f32666323052a6718a63248244f1e66Duane Sand    move    $v0, $zero                       #  rlo<- 0 (if shift&0x20)
2452e34652f15f32666323052a6718a63248244f1e66Duane Sand
24538d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe1:  jalr    $zero, $ra
2454e34652f15f32666323052a6718a63248244f1e66Duane Sand    nop
2455d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_shl_long
24565bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
24575bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
24585bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * Long integer shift.  This is different from the generic 32/64-bit
24595bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * binary operations because vAA/vBB are 64-bit but vCC (the shift
24605bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * distance) is 32-bit.  Also, Dalvik requires us to ignore all but the low
24615bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * 6 bits.
24625bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * On entry:
24637fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao     *   $a0: low word
24647fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao     *   $a1: high word
24657fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao     *   $a2: shift count
24665bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
24671d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersENTRY_NO_GP art_quick_shr_long
24687fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    sra     $v1, $a1, $a2                    #  rhi<- ahi >> (shift&31)
24697fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    srl     $v0, $a0, $a2                    #  rlo<- alo >> (shift&31)
24707fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    sra     $a3, $a1, 31                     #  $a3<- sign(ah)
24717fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    not     $a0, $a2                         #  alo<- 31-shift (shift is 5b)
24727fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    sll     $a1, 1
24737fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    sll     $a1, $a0                         #  ahi<- ahi << (32-(shift&31))
24747fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    andi    $a2, 0x20                        #  shift & 0x20
2475475cfd8ff9dcc73d1a7502c9310efe0f1a30337fDouglas Leung    beqz    $a2, 1f
2476e34652f15f32666323052a6718a63248244f1e66Duane Sand    or      $v0, $a1                         #  rlo<- rlo | ahi
2477e34652f15f32666323052a6718a63248244f1e66Duane Sand
2478e34652f15f32666323052a6718a63248244f1e66Duane Sand    move    $v0, $v1                         #  rlo<- rhi (if shift&0x20)
2479e34652f15f32666323052a6718a63248244f1e66Duane Sand    move    $v1, $a3                         #  rhi<- sign(ahi) (if shift&0x20)
2480e34652f15f32666323052a6718a63248244f1e66Duane Sand
24818d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe1:  jalr    $zero, $ra
2482e34652f15f32666323052a6718a63248244f1e66Duane Sand    nop
2483d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_shr_long
24845bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee
24855bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /*
24865bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * Long integer shift.  This is different from the generic 32/64-bit
24875bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * binary operations because vAA/vBB are 64-bit but vCC (the shift
24885bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * distance) is 32-bit.  Also, Dalvik requires us to ignore all but the low
24895bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * 6 bits.
24905bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     * On entry:
2491590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic     *   $a0: low word
2492590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic     *   $a1: high word
2493590b1362b64d7feeb688d787c1d140d9b7ca78b1Goran Jakovljevic     *   $a2: shift count
24945bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee     */
24955bc5a7b9d9adcfb50e18bd3776d3875ad7a4ae8cbuzbee    /* ushr-long vAA, vBB, vCC */
24961d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersENTRY_NO_GP art_quick_ushr_long
2497fc6a30e2fa8f0d44e6c95bbeb5deca4b499f67cejeffhao    srl     $v1, $a1, $a2                    #  rhi<- ahi >> (shift&31)
24987fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    srl     $v0, $a0, $a2                    #  rlo<- alo >> (shift&31)
24997fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    not     $a0, $a2                         #  alo<- 31-shift (shift is 5b)
25007fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    sll     $a1, 1
25017fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    sll     $a1, $a0                         #  ahi<- ahi << (32-(shift&31))
25027fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao    andi    $a2, 0x20                        #  shift & 0x20
2503e34652f15f32666323052a6718a63248244f1e66Duane Sand    beqz    $a2, 1f
2504e34652f15f32666323052a6718a63248244f1e66Duane Sand    or      $v0, $a1                         #  rlo<- rlo | ahi
2505e34652f15f32666323052a6718a63248244f1e66Duane Sand
2506e34652f15f32666323052a6718a63248244f1e66Duane Sand    move    $v0, $v1                         #  rlo<- rhi (if shift&0x20)
2507e34652f15f32666323052a6718a63248244f1e66Duane Sand    move    $v1, $zero                       #  rhi<- 0 (if shift&0x20)
2508e34652f15f32666323052a6718a63248244f1e66Duane Sand
25098d36591d93920e7b7830c3ffee3759b561f5339eAndreas Gampe1:  jalr    $zero, $ra
2510e34652f15f32666323052a6718a63248244f1e66Duane Sand    nop
2511d4c3f7d4e850049b3c1019e451b18b05443b0f28Jeff HaoEND art_quick_ushr_long
25127fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao
2513cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* java.lang.String.indexOf(int ch, int fromIndex=0) */
2514cf283daf579e9eda586f312c3fc89444601e2525Chris LarsenENTRY_NO_GP art_quick_indexof
2515cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* $a0 holds address of "this" */
2516cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* $a1 holds "ch" */
2517cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* $a2 holds "fromIndex" */
2518f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#if (STRING_COMPRESSION_FEATURE)
2519f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lw    $a3, MIRROR_STRING_COUNT_OFFSET($a0)    # 'count' field of this
2520f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#else
2521f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lw    $t0, MIRROR_STRING_COUNT_OFFSET($a0)    # this.length()
2522f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#endif
2523f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    slt   $t1, $a2, $zero # if fromIndex < 0
2524cdb23d6f4d4049f6f26b0ed629fcc5018bfe3a57Goran Jakovljevic#if defined(_MIPS_ARCH_MIPS32R6)
2525f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    seleqz $a2, $a2, $t1  #     fromIndex = 0;
2526cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen#else
2527f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    movn   $a2, $zero, $t1 #    fromIndex = 0;
2528cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen#endif
2529cdb23d6f4d4049f6f26b0ed629fcc5018bfe3a57Goran Jakovljevic
2530f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#if (STRING_COMPRESSION_FEATURE)
2531f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    srl   $t0, $a3, 1     # $a3 holds count (with flag) and $t0 holds actual length
2532f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#endif
2533f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    subu  $t0, $t0, $a2   # this.length() - fromIndex
2534f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    blez  $t0, 6f         # if this.length()-fromIndex <= 0
2535f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    li    $v0, -1         #     return -1;
2536f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic
2537f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#if (STRING_COMPRESSION_FEATURE)
2538f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    sll   $a3, $a3, 31    # Extract compression flag.
2539f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    beqz  $a3, .Lstring_indexof_compressed
2540f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    move  $t2, $a0        # Save a copy in $t2 to later compute result (in branch delay slot).
2541f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#endif
2542f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    sll   $v0, $a2, 1     # $a0 += $a2 * 2
2543f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    addu  $a0, $a0, $v0   #  "  ditto  "
2544f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    move  $v0, $a2        # Set i to fromIndex.
2545cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen
2546cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen1:
2547f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lhu   $t3, MIRROR_STRING_VALUE_OFFSET($a0)    # if this.charAt(i) == ch
2548f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    beq   $t3, $a1, 6f                            #     return i;
2549f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    addu  $a0, $a0, 2     # i++
2550f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    subu  $t0, $t0, 1     # this.length() - i
2551f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    bnez  $t0, 1b         # while this.length() - i > 0
2552f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    addu  $v0, $v0, 1     # i++
2553cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen
2554f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    li    $v0, -1         # if this.length() - i <= 0
2555f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic                          #     return -1;
2556cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen
2557cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen6:
2558f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    j     $ra
2559f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    nop
2560f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic
2561f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#if (STRING_COMPRESSION_FEATURE)
2562f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_indexof_compressed:
2563f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    addu  $a0, $a0, $a2   # $a0 += $a2
2564f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic
2565f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_indexof_compressed_loop:
2566f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lbu   $t3, MIRROR_STRING_VALUE_OFFSET($a0)
2567f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    beq   $t3, $a1, .Lstring_indexof_compressed_matched
2568f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    subu  $t0, $t0, 1
2569f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    bgtz  $t0, .Lstring_indexof_compressed_loop
2570f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    addu  $a0, $a0, 1
2571f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic
2572f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_indexof_nomatch:
2573f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    jalr  $zero, $ra
2574f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    li    $v0, -1         # return -1;
2575f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic
2576f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_indexof_compressed_matched:
2577f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    jalr  $zero, $ra
2578f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    subu  $v0, $a0, $t2   # return (current - start);
2579f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#endif
2580cf283daf579e9eda586f312c3fc89444601e2525Chris LarsenEND art_quick_indexof
2581cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen
2582cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* java.lang.String.compareTo(String anotherString) */
2583cf283daf579e9eda586f312c3fc89444601e2525Chris LarsenENTRY_NO_GP art_quick_string_compareto
2584cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* $a0 holds address of "this" */
2585cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen/* $a1 holds address of "anotherString" */
2586f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    beq    $a0, $a1, .Lstring_compareto_length_diff   # this and anotherString are the same object
2587f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    move   $a3, $a2                                   # trick to return 0 (it returns a2 - a3)
2588f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic
2589f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#if (STRING_COMPRESSION_FEATURE)
2590f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lw     $t0, MIRROR_STRING_COUNT_OFFSET($a0)   # 'count' field of this
2591f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lw     $t1, MIRROR_STRING_COUNT_OFFSET($a1)   # 'count' field of anotherString
2592f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    sra    $a2, $t0, 1                            # this.length()
2593f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    sra    $a3, $t1, 1                            # anotherString.length()
2594f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#else
2595f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lw     $a2, MIRROR_STRING_COUNT_OFFSET($a0)   # this.length()
2596f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lw     $a3, MIRROR_STRING_COUNT_OFFSET($a1)   # anotherString.length()
2597f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#endif
2598cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen
2599f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    MINu   $t2, $a2, $a3
2600f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    # $t2 now holds min(this.length(),anotherString.length())
2601cf283daf579e9eda586f312c3fc89444601e2525Chris Larsen
2602f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    # while min(this.length(),anotherString.length())-i != 0
2603f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    beqz   $t2, .Lstring_compareto_length_diff # if $t2==0
2604f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    nop                                        #     return (this.length() - anotherString.length())
2605f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic
2606f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#if (STRING_COMPRESSION_FEATURE)
2607f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    # Differ cases:
2608f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    sll    $t3, $t0, 31
2609f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    beqz   $t3, .Lstring_compareto_this_is_compressed
2610f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    sll    $t3, $t1, 31                           # In branch delay slot.
2611f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    beqz   $t3, .Lstring_compareto_that_is_compressed
2612f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    nop
2613f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    b      .Lstring_compareto_both_not_compressed
2614f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    nop
2615f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic
2616f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_this_is_compressed:
2617f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    beqz   $t3, .Lstring_compareto_both_compressed
2618f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    nop
2619f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    /* If (this->IsCompressed() && that->IsCompressed() == false) */
2620f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_loop_comparison_this_compressed:
2621f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lbu    $t0, MIRROR_STRING_VALUE_OFFSET($a0)
2622f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lhu    $t1, MIRROR_STRING_VALUE_OFFSET($a1)
2623f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    bne    $t0, $t1, .Lstring_compareto_char_diff
2624f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    addiu  $a0, $a0, 1    # point at this.charAt(i++) - compressed
2625f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    subu   $t2, $t2, 1    # new value of min(this.length(),anotherString.length())-i
2626f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    bnez   $t2, .Lstring_compareto_loop_comparison_this_compressed
2627f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    addiu  $a1, $a1, 2    # point at anotherString.charAt(i++) - uncompressed
2628f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    jalr   $zero, $ra
2629f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    subu   $v0, $a2, $a3  # return (this.length() - anotherString.length())
2630f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic
2631f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_that_is_compressed:
2632f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lhu    $t0, MIRROR_STRING_VALUE_OFFSET($a0)
2633f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lbu    $t1, MIRROR_STRING_VALUE_OFFSET($a1)
2634f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    bne    $t0, $t1, .Lstring_compareto_char_diff
2635f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    addiu  $a0, $a0, 2    # point at this.charAt(i++) - uncompressed
2636f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    subu   $t2, $t2, 1    # new value of min(this.length(),anotherString.length())-i
2637f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    bnez   $t2, .Lstring_compareto_that_is_compressed
2638f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    addiu  $a1, $a1, 1    # point at anotherString.charAt(i++) - compressed
2639f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    jalr   $zero, $ra
2640f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    subu   $v0, $a2, $a3  # return (this.length() - anotherString.length())
2641f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic
2642f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_both_compressed:
2643f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lbu    $t0, MIRROR_STRING_VALUE_OFFSET($a0)
2644f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lbu    $t1, MIRROR_STRING_VALUE_OFFSET($a1)
2645f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    bne    $t0, $t1, .Lstring_compareto_char_diff
2646f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    addiu  $a0, $a0, 1    # point at this.charAt(i++) - compressed
2647f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    subu   $t2, $t2, 1    # new value of min(this.length(),anotherString.length())-i
2648f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    bnez   $t2, .Lstring_compareto_both_compressed
2649f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    addiu  $a1, $a1, 1    # point at anotherString.charAt(i++) - compressed
2650f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    jalr   $zero, $ra
2651f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    subu   $v0, $a2, $a3  # return (this.length() - anotherString.length())
2652f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic#endif
2653f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic
2654f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_both_not_compressed:
2655f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lhu    $t0, MIRROR_STRING_VALUE_OFFSET($a0)   # while this.charAt(i) == anotherString.charAt(i)
2656f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    lhu    $t1, MIRROR_STRING_VALUE_OFFSET($a1)
2657f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    bne    $t0, $t1, .Lstring_compareto_char_diff # if this.charAt(i) != anotherString.charAt(i)
2658f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic                          #     return (this.charAt(i) - anotherString.charAt(i))
2659f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    addiu  $a0, $a0, 2    # point at this.charAt(i++)
2660f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    subu   $t2, $t2, 1    # new value of min(this.length(),anotherString.length())-i
2661f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    bnez   $t2, .Lstring_compareto_both_not_compressed
2662f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    addiu  $a1, $a1, 2    # point at anotherString.charAt(i++)
2663f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic
2664f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_length_diff:
2665f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    jalr   $zero, $ra
2666f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    subu   $v0, $a2, $a3  # return (this.length() - anotherString.length())
2667f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic
2668f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic.Lstring_compareto_char_diff:
2669f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    jalr   $zero, $ra
2670f94fa81e20d00929ef52707cd577353b95d40284Goran Jakovljevic    subu   $v0, $t0, $t1  # return (this.charAt(i) - anotherString.charAt(i))
2671cf283daf579e9eda586f312c3fc89444601e2525Chris LarsenEND art_quick_string_compareto
2672ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson
26731595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    /*
26741595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze     * Create a function `name` calling the ReadBarrier::Mark routine,
26751595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze     * getting its argument and returning its result through register
26761595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze     * `reg`, saving and restoring all caller-save registers.
26771595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze     */
26781595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze.macro READ_BARRIER_MARK_REG name, reg
26791595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeENTRY \name
2680a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    // Null check so that we can load the lock word.
2681a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    bnez    \reg, .Lnot_null_\name
2682a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    nop
2683a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze.Lret_rb_\name:
2684a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    jalr    $zero, $ra
2685a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    nop
2686a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze.Lnot_null_\name:
2687a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    // Check lock word for mark bit, if marked return.
2688a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    lw      $t9, MIRROR_OBJECT_LOCK_WORD_OFFSET(\reg)
2689a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    .set push
2690a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    .set noat
2691a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    sll     $at, $t9, 31 - LOCK_WORD_MARK_BIT_SHIFT     # Move mark bit to sign bit.
2692a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    bltz    $at, .Lret_rb_\name
2693a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze#if (LOCK_WORD_STATE_SHIFT != 30) || (LOCK_WORD_STATE_FORWARDING_ADDRESS != 3)
2694a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    // The below code depends on the lock word state being in the highest bits
2695a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    // and the "forwarding address" state having all bits set.
2696a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze#error "Unexpected lock word state shift or forwarding address state value."
2697a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze#endif
2698a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    // Test that both the forwarding state bits are 1.
2699a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    sll     $at, $t9, 1
2700a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    and     $at, $at, $t9                               # Sign bit = 1 IFF both bits are 1.
2701a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    bltz    $at, .Lret_forwarding_address\name
2702a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    nop
2703a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    .set pop
2704a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze
2705a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    addiu   $sp, $sp, -160      # Includes 16 bytes of space for argument registers a0-a3.
27061595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_adjust_cfa_offset 160
27071595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze
27081595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $ra, 156($sp)
27091595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 31, 156
27101595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $t8, 152($sp)
27111595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 24, 152
27121595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $t7, 148($sp)
27131595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 15, 148
27141595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $t6, 144($sp)
27151595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 14, 144
27161595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $t5, 140($sp)
27171595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 13, 140
27181595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $t4, 136($sp)
27191595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 12, 136
27201595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $t3, 132($sp)
27211595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 11, 132
27221595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $t2, 128($sp)
27231595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 10, 128
27241595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $t1, 124($sp)
27251595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 9, 124
27261595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $t0, 120($sp)
27271595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 8, 120
27281595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $a3, 116($sp)
27291595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 7, 116
27301595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $a2, 112($sp)
27311595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 6, 112
27321595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $a1, 108($sp)
27331595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 5, 108
27341595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $a0, 104($sp)
27351595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 4, 104
27361595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $v1, 100($sp)
27371595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 3, 100
27381595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sw      $v0, 96($sp)
27391595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_rel_offset 2, 96
27401595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze
27411595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    la      $t9, artReadBarrierMark
27421595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze
27431595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sdc1    $f18, 88($sp)
27441595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sdc1    $f16, 80($sp)
27451595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sdc1    $f14, 72($sp)
27461595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sdc1    $f12, 64($sp)
27471595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sdc1    $f10, 56($sp)
27481595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sdc1    $f8,  48($sp)
27491595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sdc1    $f6,  40($sp)
27501595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sdc1    $f4,  32($sp)
27511595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sdc1    $f2,  24($sp)
27521595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze
27531595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .ifnc \reg, $a0
27541595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze      move  $a0, \reg           # pass obj from `reg` in a0
27551595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .endif
27561595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    jalr    $t9                 # v0 <- artReadBarrierMark(obj)
27571595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    sdc1    $f0,  16($sp)       # in delay slot
27581595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze
27591595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $ra, 156($sp)
27601595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 31
27611595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $t8, 152($sp)
27621595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 24
27631595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $t7, 148($sp)
27641595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 15
27651595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $t6, 144($sp)
27661595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 14
27671595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $t5, 140($sp)
27681595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 13
27691595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $t4, 136($sp)
27701595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 12
27711595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $t3, 132($sp)
27721595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 11
27731595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $t2, 128($sp)
27741595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 10
27751595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $t1, 124($sp)
27761595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 9
27771595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $t0, 120($sp)
27781595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 8
27791595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $a3, 116($sp)
27801595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 7
27811595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $a2, 112($sp)
27821595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 6
27831595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $a1, 108($sp)
27841595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 5
27851595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $a0, 104($sp)
27861595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 4
27871595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    lw      $v1, 100($sp)
27881595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_restore 3
27891595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze
27901595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .ifnc \reg, $v0
27911595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze      move  \reg, $v0           # `reg` <- v0
27921595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze      lw    $v0, 96($sp)
27931595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze      .cfi_restore 2
27941595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .endif
27951595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze
27961595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    ldc1    $f18, 88($sp)
27971595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    ldc1    $f16, 80($sp)
27981595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    ldc1    $f14, 72($sp)
27991595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    ldc1    $f12, 64($sp)
28001595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    ldc1    $f10, 56($sp)
28011595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    ldc1    $f8,  48($sp)
28021595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    ldc1    $f6,  40($sp)
28031595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    ldc1    $f4,  32($sp)
28041595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    ldc1    $f2,  24($sp)
28051595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    ldc1    $f0,  16($sp)
28061595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze
28071595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    jalr    $zero, $ra
28081595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    addiu   $sp, $sp, 160
28091595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze    .cfi_adjust_cfa_offset -160
2810a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze
2811a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze.Lret_forwarding_address\name:
2812a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    jalr    $zero, $ra
2813a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    // Shift left by the forwarding address shift. This clears out the state bits since they are
2814a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    // in the top 2 bits of the lock word.
2815a3cb132792e998d64b917d36052b715f0076820bAlexey Frunze    sll     \reg, $t9, LOCK_WORD_STATE_FORWARDING_ADDRESS_SHIFT
28161595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeEND \name
28171595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze.endm
28181595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze
28191595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// Note that art_quick_read_barrier_mark_regXX corresponds to register XX+1.
28201595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// ZERO (register 0) is reserved.
28211595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// AT (register 1) is reserved as a temporary/scratch register.
28221595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg01, $v0
28231595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg02, $v1
28241595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg03, $a0
28251595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg04, $a1
28261595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg05, $a2
28271595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg06, $a3
28281595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg07, $t0
28291595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg08, $t1
28301595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg09, $t2
28311595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg10, $t3
28321595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg11, $t4
28331595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg12, $t5
28341595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg13, $t6
28351595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg14, $t7
28361595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// S0 and S1 (registers 16 and 17) are reserved as suspended and thread registers.
28371595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg17, $s2
28381595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg18, $s3
28391595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg19, $s4
28401595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg20, $s5
28411595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg21, $s6
28421595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg22, $s7
28431595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// T8 and T9 (registers 24 and 25) are reserved as temporary/scratch registers.
28441595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// K0, K1, GP, SP (registers 26 - 29) are reserved.
28451595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey FrunzeREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg29, $s8
28461595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze// RA (register 31) is reserved.
28471595815c2a914a78df7dfb6f0082f47d4e82bb36Alexey Frunze
28484147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// Caller code:
28494147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// Short constant offset/index:
28504147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// R2:                           | R6:
28514147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  lw      $t9, pReadBarrierMarkReg00
28524147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  beqz    $t9, skip_call       |  beqzc   $t9, skip_call
28534147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  addiu   $t9, $t9, thunk_disp |  nop
28544147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  jalr    $t9                  |  jialc   $t9, thunk_disp
28554147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  nop                          |
28564147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// skip_call:                    | skip_call:
28574147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  lw      `out`, ofs(`obj`)    |  lw      `out`, ofs(`obj`)
28584147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// [subu    `out`, $zero, `out`] | [subu    `out`, $zero, `out`]  # Unpoison reference.
28594147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.macro BRB_FIELD_SHORT_OFFSET_ENTRY obj
28604147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze1:
28614147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    # Explicit null check. May be redundant (for array elements or when the field
28624147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    # offset is larger than the page size, 4KB).
28634147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    # $ra will be adjusted to point to lw's stack map when throwing NPE.
28644147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    beqz    \obj, .Lintrospection_throw_npe
28654147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#if defined(_MIPS_ARCH_MIPS32R6)
28664147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lapc    $gp, .Lintrospection_exits                  # $gp = address of .Lintrospection_exits.
28674147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#else
28684147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    addiu   $gp, $t9, (.Lintrospection_exits - 1b)      # $gp = address of .Lintrospection_exits.
28694147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#endif
28704147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .set push
28714147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .set noat
28724147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $at, MIRROR_OBJECT_LOCK_WORD_OFFSET(\obj)
28734147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sll     $at, $at, 31 - LOCK_WORD_READ_BARRIER_STATE_SHIFT   # Move barrier state bit
28744147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze                                                                # to sign bit.
28754147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    bltz    $at, .Lintrospection_field_array            # If gray, load reference, mark.
28764147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    move    $t8, \obj                                   # Move `obj` to $t8 for common code.
28774147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .set pop
28784147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    jalr    $zero, $ra                                  # Otherwise, load-load barrier and return.
28794147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sync
28804147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.endm
28814147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
28824147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// Caller code (R2):
28834147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// Long constant offset/index:   | Variable index:
28844147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  lw      $t9, pReadBarrierMarkReg00
28854147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  lui     $t8, ofs_hi          |  sll     $t8, `index`, 2
28864147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  beqz    $t9, skip_call       |  beqz    $t9, skip_call
28874147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  addiu   $t9, $t9, thunk_disp |  addiu   $t9, $t9, thunk_disp
28884147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  jalr    $t9                  |  jalr    $t9
28894147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// skip_call:                    | skip_call:
28904147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  addu    $t8, $t8, `obj`      |  addu    $t8, $t8, `obj`
28914147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  lw      `out`, ofs_lo($t8)   |  lw      `out`, ofs($t8)
28924147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// [subu    `out`, $zero, `out`] | [subu    `out`, $zero, `out`]  # Unpoison reference.
28934147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//
28944147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// Caller code (R6):
28954147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// Long constant offset/index:   | Variable index:
28964147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  lw      $t9, pReadBarrierMarkReg00
28974147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  beqz    $t9, skip_call       |  beqz    $t9, skip_call
28984147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  aui     $t8, `obj`, ofs_hi   |  lsa     $t8, `index`, `obj`, 2
28994147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  jialc   $t9, thunk_disp      |  jialc   $t9, thunk_disp
29004147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// skip_call:                    | skip_call:
29014147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze//  lw      `out`, ofs_lo($t8)   |  lw      `out`, ofs($t8)
29024147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze// [subu    `out`, $zero, `out`] | [subu    `out`, $zero, `out`]  # Unpoison reference.
29034147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.macro BRB_FIELD_LONG_OFFSET_ENTRY obj
29044147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze1:
29054147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    # No explicit null check for variable indices or large constant indices/offsets
29064147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    # as it must have been done earlier.
29074147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#if defined(_MIPS_ARCH_MIPS32R6)
29084147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lapc    $gp, .Lintrospection_exits                  # $gp = address of .Lintrospection_exits.
29094147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#else
29104147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    addiu   $gp, $t9, (.Lintrospection_exits - 1b)      # $gp = address of .Lintrospection_exits.
29114147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#endif
29124147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .set push
29134147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .set noat
29144147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $at, MIRROR_OBJECT_LOCK_WORD_OFFSET(\obj)
29154147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sll     $at, $at, 31 - LOCK_WORD_READ_BARRIER_STATE_SHIFT   # Move barrier state bit
29164147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze                                                                # to sign bit.
29174147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    bltz    $at, .Lintrospection_field_array            # If gray, load reference, mark.
29184147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    nop
29194147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .set pop
29204147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    jalr    $zero, $ra                                  # Otherwise, load-load barrier and return.
29214147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sync
29224147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    break                                               # Padding to 8 instructions.
29234147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.endm
29244147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
29254147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.macro BRB_GC_ROOT_ENTRY root
29264147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze1:
29274147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#if defined(_MIPS_ARCH_MIPS32R6)
29284147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lapc    $gp, .Lintrospection_exit_\root             # $gp = exit point address.
29294147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#else
29304147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    addiu   $gp, $t9, (.Lintrospection_exit_\root - 1b)  # $gp = exit point address.
29314147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#endif
29324147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    bnez    \root, .Lintrospection_common
29334147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    move    $t8, \root                                  # Move reference to $t8 for common code.
29344147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    jalr    $zero, $ra                                  # Return if null.
29354147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    # The next instruction (from the following BRB_GC_ROOT_ENTRY) fills the delay slot.
29364147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    # This instruction has no effect (actual NOP for the last entry; otherwise changes $gp,
29374147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    # which is unused after that anyway).
29384147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.endm
29394147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
29404147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.macro BRB_FIELD_EXIT out
29414147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_exit_\out:
29424147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    jalr    $zero, $ra
29434147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    move    \out, $t8                                   # Return reference in expected register.
29444147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.endm
29454147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
29464147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.macro BRB_FIELD_EXIT_BREAK
29474147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    break
29484147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    break
29494147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.endm
29504147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
29514147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey FrunzeENTRY_NO_GP art_quick_read_barrier_mark_introspection
29524147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    # Entry points for offsets/indices not fitting into int16_t and for variable indices.
29534147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $v0
29544147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $v1
29554147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $a0
29564147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $a1
29574147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $a2
29584147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $a3
29594147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $t0
29604147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $t1
29614147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $t2
29624147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $t3
29634147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $t4
29644147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $t5
29654147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $t6
29664147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $t7
29674147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $s2
29684147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $s3
29694147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $s4
29704147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $s5
29714147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $s6
29724147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $s7
29734147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_LONG_OFFSET_ENTRY $s8
29744147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
29754147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    # Entry points for offsets/indices fitting into int16_t.
29764147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $v0
29774147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $v1
29784147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $a0
29794147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $a1
29804147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $a2
29814147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $a3
29824147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $t0
29834147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $t1
29844147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $t2
29854147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $t3
29864147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $t4
29874147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $t5
29884147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $t6
29894147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $t7
29904147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $s2
29914147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $s3
29924147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $s4
29934147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $s5
29944147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $s6
29954147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $s7
29964147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_SHORT_OFFSET_ENTRY $s8
29974147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
29984147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .global art_quick_read_barrier_mark_introspection_gc_roots
29994147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunzeart_quick_read_barrier_mark_introspection_gc_roots:
30004147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    # Entry points for GC roots.
30014147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $v0
30024147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $v1
30034147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $a0
30044147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $a1
30054147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $a2
30064147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $a3
30074147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $t0
30084147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $t1
30094147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $t2
30104147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $t3
30114147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $t4
30124147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $t5
30134147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $t6
30144147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $t7
30154147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $s2
30164147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $s3
30174147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $s4
30184147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $s5
30194147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $s6
30204147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $s7
30214147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_GC_ROOT_ENTRY $s8
30224147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .global art_quick_read_barrier_mark_introspection_end_of_entries
30234147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunzeart_quick_read_barrier_mark_introspection_end_of_entries:
30244147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    nop                         # Fill the delay slot of the last BRB_GC_ROOT_ENTRY.
30254147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30264147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_throw_npe:
30274147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    b       art_quick_throw_null_pointer_exception
30284147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    addiu   $ra, $ra, 4         # Skip lw, make $ra point to lw's stack map.
30294147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30304147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .set push
30314147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .set noat
30324147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30334147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // Fields and array elements.
30344147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30354147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_field_array:
30364147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // Get the field/element address using $t8 and the offset from the lw instruction.
30374147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lh      $at, 0($ra)         # $ra points to lw: $at = field/element offset.
30384147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    addiu   $ra, $ra, 4 + HEAP_POISON_INSTR_SIZE  # Skip lw(+subu).
30394147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    addu    $t8, $t8, $at       # $t8 = field/element address.
30404147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30414147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // Calculate the address of the exit point, store it in $gp and load the reference into $t8.
30424147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lb      $at, (-HEAP_POISON_INSTR_SIZE - 2)($ra)   # $ra-HEAP_POISON_INSTR_SIZE-4 points to
30434147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze                                                      # "lw `out`, ...".
30444147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    andi    $at, $at, 31        # Extract `out` from lw.
30454147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sll     $at, $at, 3         # Multiply `out` by the exit point size (BRB_FIELD_EXIT* macros).
30464147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30474147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $t8, 0($t8)         # $t8 = reference.
30484147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    UNPOISON_HEAP_REF $t8
30494147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30504147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // Return if null reference.
30514147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    bnez    $t8, .Lintrospection_common
30524147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    addu    $gp, $gp, $at       # $gp = address of the exit point.
30534147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30544147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // Early return through the exit point.
30554147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_return_early:
30564147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    jalr    $zero, $gp          # Move $t8 to `out` and return.
30574147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    nop
30584147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30594147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // Code common for GC roots, fields and array elements.
30604147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30614147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_common:
30624147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // Check lock word for mark bit, if marked return.
30634147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $t9, MIRROR_OBJECT_LOCK_WORD_OFFSET($t8)
30644147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sll     $at, $t9, 31 - LOCK_WORD_MARK_BIT_SHIFT     # Move mark bit to sign bit.
30654147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    bltz    $at, .Lintrospection_return_early
30664147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#if (LOCK_WORD_STATE_SHIFT != 30) || (LOCK_WORD_STATE_FORWARDING_ADDRESS != 3)
30674147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // The below code depends on the lock word state being in the highest bits
30684147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // and the "forwarding address" state having all bits set.
30694147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#error "Unexpected lock word state shift or forwarding address state value."
30704147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze#endif
30714147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // Test that both the forwarding state bits are 1.
30724147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sll     $at, $t9, 1
30734147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    and     $at, $at, $t9                               # Sign bit = 1 IFF both bits are 1.
30744147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    bgez    $at, .Lintrospection_mark
30754147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    nop
30764147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30774147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .set pop
30784147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30794147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // Shift left by the forwarding address shift. This clears out the state bits since they are
30804147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // in the top 2 bits of the lock word.
30814147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    jalr    $zero, $gp          # Move $t8 to `out` and return.
30824147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sll     $t8, $t9, LOCK_WORD_STATE_FORWARDING_ADDRESS_SHIFT
30834147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30844147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_mark:
30854147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // Partially set up the stack frame preserving only $ra.
30864147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    addiu   $sp, $sp, -160      # Includes 16 bytes of space for argument registers $a0-$a3.
30874147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_adjust_cfa_offset 160
30884147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $ra, 156($sp)
30894147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 31, 156
30904147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30914147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // Set up $gp, clobbering $ra and using the branch delay slot for a useful instruction.
30924147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    bal     1f
30934147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $gp, 152($sp)       # Preserve the exit point address.
30944147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze1:
30954147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cpload $ra
30964147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
30974147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // Finalize the stack frame and call.
30984147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $t7, 148($sp)
30994147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 15, 148
31004147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $t6, 144($sp)
31014147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 14, 144
31024147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $t5, 140($sp)
31034147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 13, 140
31044147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $t4, 136($sp)
31054147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 12, 136
31064147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $t3, 132($sp)
31074147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 11, 132
31084147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $t2, 128($sp)
31094147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 10, 128
31104147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $t1, 124($sp)
31114147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 9, 124
31124147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $t0, 120($sp)
31134147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 8, 120
31144147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $a3, 116($sp)
31154147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 7, 116
31164147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $a2, 112($sp)
31174147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 6, 112
31184147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $a1, 108($sp)
31194147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 5, 108
31204147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $a0, 104($sp)
31214147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 4, 104
31224147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $v1, 100($sp)
31234147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 3, 100
31244147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sw      $v0, 96($sp)
31254147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_rel_offset 2, 96
31264147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
31274147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    la      $t9, artReadBarrierMark
31284147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
31294147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sdc1    $f18, 88($sp)
31304147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sdc1    $f16, 80($sp)
31314147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sdc1    $f14, 72($sp)
31324147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sdc1    $f12, 64($sp)
31334147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sdc1    $f10, 56($sp)
31344147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sdc1    $f8,  48($sp)
31354147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sdc1    $f6,  40($sp)
31364147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sdc1    $f4,  32($sp)
31374147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sdc1    $f2,  24($sp)
31384147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    sdc1    $f0,  16($sp)
31394147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
31404147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    jalr    $t9                 # $v0 <- artReadBarrierMark(reference)
31414147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    move    $a0, $t8            # Pass reference in $a0.
31424147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    move    $t8, $v0
31434147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
31444147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $ra, 156($sp)
31454147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 31
31464147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $gp, 152($sp)       # $gp = address of the exit point.
31474147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $t7, 148($sp)
31484147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 15
31494147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $t6, 144($sp)
31504147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 14
31514147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $t5, 140($sp)
31524147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 13
31534147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $t4, 136($sp)
31544147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 12
31554147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $t3, 132($sp)
31564147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 11
31574147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $t2, 128($sp)
31584147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 10
31594147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $t1, 124($sp)
31604147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 9
31614147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $t0, 120($sp)
31624147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 8
31634147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $a3, 116($sp)
31644147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 7
31654147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $a2, 112($sp)
31664147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 6
31674147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $a1, 108($sp)
31684147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 5
31694147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $a0, 104($sp)
31704147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 4
31714147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $v1, 100($sp)
31724147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 3
31734147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    lw      $v0, 96($sp)
31744147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_restore 2
31754147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
31764147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    ldc1    $f18, 88($sp)
31774147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    ldc1    $f16, 80($sp)
31784147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    ldc1    $f14, 72($sp)
31794147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    ldc1    $f12, 64($sp)
31804147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    ldc1    $f10, 56($sp)
31814147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    ldc1    $f8,  48($sp)
31824147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    ldc1    $f6,  40($sp)
31834147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    ldc1    $f4,  32($sp)
31844147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    ldc1    $f2,  24($sp)
31854147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    ldc1    $f0,  16($sp)
31864147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
31874147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    // Return through the exit point.
31884147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    jalr    $zero, $gp          # Move $t8 to `out` and return.
31894147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    addiu   $sp, $sp, 160
31904147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    .cfi_adjust_cfa_offset -160
31914147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
31924147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze.Lintrospection_exits:
31934147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT_BREAK
31944147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT_BREAK
31954147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $v0
31964147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $v1
31974147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $a0
31984147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $a1
31994147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $a2
32004147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $a3
32014147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $t0
32024147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $t1
32034147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $t2
32044147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $t3
32054147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $t4
32064147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $t5
32074147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $t6
32084147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $t7
32094147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT_BREAK
32104147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT_BREAK
32114147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $s2
32124147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $s3
32134147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $s4
32144147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $s5
32154147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $s6
32164147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $s7
32174147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT_BREAK
32184147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT_BREAK
32194147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT_BREAK
32204147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT_BREAK
32214147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT_BREAK
32224147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT_BREAK
32234147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT $s8
32244147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze    BRB_FIELD_EXIT_BREAK
32254147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey FrunzeEND art_quick_read_barrier_mark_introspection
32264147fcc43c2ee019a06e55384985e3eaf82dcb8cAlexey Frunze
3227ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.extern artInvokePolymorphic
3228ac141397dc29189ad2b2df41f8d4312246beec60Orion HodsonENTRY art_quick_invoke_polymorphic
3229ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    SETUP_SAVE_REFS_AND_ARGS_FRAME
3230ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    move  $a2, rSELF                          # Make $a2 an alias for the current Thread.
3231c480b9853ac7be67581cd26c49c2ed7426ae68a4Alexey Frunze    addiu $a3, $sp, ARG_SLOT_SIZE             # Make $a3 a pointer to the saved frame context.
3232ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    sw    $zero, 20($sp)                      # Initialize JValue result.
3233ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    sw    $zero, 16($sp)
3234ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    la    $t9, artInvokePolymorphic
323543f0cdbe3281cd5c9a33d5472b1538e5617f6691Orion Hodson    jalr  $t9                                 # artInvokePolymorphic(result, receiver, Thread*, context)
3236c480b9853ac7be67581cd26c49c2ed7426ae68a4Alexey Frunze    addiu $a0, $sp, 16                        # Make $a0 a pointer to the JValue result
3237ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.macro MATCH_RETURN_TYPE c, handler
3238ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    li    $t0, \c
3239ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    beq   $v0, $t0, \handler
3240ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.endm
3241ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    MATCH_RETURN_TYPE 'V', .Lcleanup_and_return
3242ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    MATCH_RETURN_TYPE 'L', .Lstore_int_result
3243ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    MATCH_RETURN_TYPE 'I', .Lstore_int_result
3244ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    MATCH_RETURN_TYPE 'J', .Lstore_long_result
3245ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    MATCH_RETURN_TYPE 'B', .Lstore_int_result
3246ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    MATCH_RETURN_TYPE 'C', .Lstore_char_result
3247ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    MATCH_RETURN_TYPE 'D', .Lstore_double_result
3248ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    MATCH_RETURN_TYPE 'F', .Lstore_float_result
3249ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    MATCH_RETURN_TYPE 'S', .Lstore_int_result
3250c480b9853ac7be67581cd26c49c2ed7426ae68a4Alexey Frunze    MATCH_RETURN_TYPE 'Z', .Lstore_boolean_result
3251ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.purgem MATCH_RETURN_TYPE
3252ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    nop
3253ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    b .Lcleanup_and_return
3254ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    nop
3255ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lstore_boolean_result:
3256ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    b .Lcleanup_and_return
3257c480b9853ac7be67581cd26c49c2ed7426ae68a4Alexey Frunze    lbu   $v0, 16($sp)                        # Move byte from JValue result to return value register.
3258ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lstore_char_result:
3259ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    b .Lcleanup_and_return
3260c480b9853ac7be67581cd26c49c2ed7426ae68a4Alexey Frunze    lhu   $v0, 16($sp)                        # Move char from JValue result to return value register.
3261ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lstore_double_result:
3262ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lstore_float_result:
3263715f43e1553330bc804cea2951be195473dc343dChris Larsen    CHECK_ALIGNMENT $sp, $t0
3264715f43e1553330bc804cea2951be195473dc343dChris Larsen    ldc1  $f0, 16($sp)                        # Move double/float from JValue result to return value register.
3265ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    b .Lcleanup_and_return
3266ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    nop
3267ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lstore_long_result:
3268ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    lw    $v1, 20($sp)                        # Move upper bits from JValue result to return value register.
3269ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    // Fall-through for lower bits.
3270ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lstore_int_result:
3271ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    lw    $v0, 16($sp)                        # Move lower bits from JValue result to return value register.
3272ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    // Fall-through to clean up and return.
3273ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson.Lcleanup_and_return:
3274ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    lw    $t7, THREAD_EXCEPTION_OFFSET(rSELF) # Load Thread::Current()->exception_
3275ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    RESTORE_SAVE_REFS_AND_ARGS_FRAME
3276ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    bnez  $t7, 1f                             # Success if no exception is pending.
3277ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    nop
3278ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    jalr  $zero, $ra
3279ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    nop
3280ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson1:
3281ac141397dc29189ad2b2df41f8d4312246beec60Orion Hodson    DELIVER_PENDING_EXCEPTION
3282ac141397dc29189ad2b2df41f8d4312246beec60Orion HodsonEND art_quick_invoke_polymorphic
3283