xref: /aosp_15_r20/art/runtime/arch/riscv64/jni_entrypoints_riscv64.S (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker/*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker#include "asm_support_riscv64.S"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker
20*795d594fSAndroid Build Coastguard Worker.macro JNI_SAVE_MANAGED_ARGS_TRAMPOLINE name, cxx_name, arg1 = "none"
21*795d594fSAndroid Build Coastguard Worker    .extern \cxx_name
22*795d594fSAndroid Build Coastguard WorkerENTRY \name
23*795d594fSAndroid Build Coastguard Worker    // Save args and RA.
24*795d594fSAndroid Build Coastguard Worker    SAVE_ALL_ARGS_INCREASE_FRAME /*padding*/ 8 + /*RA*/ 8
25*795d594fSAndroid Build Coastguard Worker    SAVE_GPR ra, (ALL_ARGS_SIZE + /*padding*/ 8)
26*795d594fSAndroid Build Coastguard Worker    // Call `cxx_name()`.
27*795d594fSAndroid Build Coastguard Worker    .ifnc \arg1, none
28*795d594fSAndroid Build Coastguard Worker        mv    a0, \arg1
29*795d594fSAndroid Build Coastguard Worker    .endif
30*795d594fSAndroid Build Coastguard Worker    call   \cxx_name
31*795d594fSAndroid Build Coastguard Worker    // Restore RA and args and return.
32*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR ra, (ALL_ARGS_SIZE + /*padding*/ 8)
33*795d594fSAndroid Build Coastguard Worker    RESTORE_ALL_ARGS_DECREASE_FRAME /*padding*/ 8 + /*RA*/ 8
34*795d594fSAndroid Build Coastguard Worker    ret
35*795d594fSAndroid Build Coastguard WorkerEND \name
36*795d594fSAndroid Build Coastguard Worker.endm
37*795d594fSAndroid Build Coastguard Worker
38*795d594fSAndroid Build Coastguard Worker
39*795d594fSAndroid Build Coastguard Worker.macro JNI_SAVE_RETURN_VALUE_TRAMPOLINE name, cxx_name, arg1, arg2 = "none"
40*795d594fSAndroid Build Coastguard Worker    .extern \cxx_name
41*795d594fSAndroid Build Coastguard WorkerENTRY \name
42*795d594fSAndroid Build Coastguard Worker    // Save return registers and return address.
43*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME 32
44*795d594fSAndroid Build Coastguard Worker    sd    a0, 0(sp)
45*795d594fSAndroid Build Coastguard Worker    fsd   fa0, 8(sp)
46*795d594fSAndroid Build Coastguard Worker    SAVE_GPR ra, 24
47*795d594fSAndroid Build Coastguard Worker    // Call `cxx_name()`.
48*795d594fSAndroid Build Coastguard Worker    mv    a0, \arg1
49*795d594fSAndroid Build Coastguard Worker    .ifnc \arg2, none
50*795d594fSAndroid Build Coastguard Worker        mv    a1, \arg2
51*795d594fSAndroid Build Coastguard Worker    .endif
52*795d594fSAndroid Build Coastguard Worker    call  \cxx_name
53*795d594fSAndroid Build Coastguard Worker    // Restore result registers and return.
54*795d594fSAndroid Build Coastguard Worker    ld    a0, 0(sp)
55*795d594fSAndroid Build Coastguard Worker    fld   fa0, 8(sp)
56*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR ra, 24
57*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME 32
58*795d594fSAndroid Build Coastguard Worker    ret
59*795d594fSAndroid Build Coastguard WorkerEND \name
60*795d594fSAndroid Build Coastguard Worker.endm
61*795d594fSAndroid Build Coastguard Worker
62*795d594fSAndroid Build Coastguard Worker
63*795d594fSAndroid Build Coastguard Worker// JNI dlsym lookup stub for @CriticalNative.
64*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_dlsym_lookup_critical_stub
65*795d594fSAndroid Build Coastguard Worker    // The hidden arg holding the tagged method is t0 (loaded by compiled JNI stub, compiled
66*795d594fSAndroid Build Coastguard Worker    // managed code, or `art_quick_generic_jni_trampoline`). Bit 0 set means generic JNI.
67*795d594fSAndroid Build Coastguard Worker    // For generic JNI we already have a managed frame, so we reuse the art_jni_dlsym_lookup_stub.
68*795d594fSAndroid Build Coastguard Worker    // Note: 'bnez' doesn't always have enough range (+/-4KB) to reach art_jni_dlsym_lookup_stub so
69*795d594fSAndroid Build Coastguard Worker    // 'tail' is used instead.
70*795d594fSAndroid Build Coastguard Worker    andi  t6, t0, 1
71*795d594fSAndroid Build Coastguard Worker    beqz  t6, .Lcritical_not_generic_jni
72*795d594fSAndroid Build Coastguard Worker    tail  art_jni_dlsym_lookup_stub
73*795d594fSAndroid Build Coastguard Worker
74*795d594fSAndroid Build Coastguard Worker.Lcritical_not_generic_jni:
75*795d594fSAndroid Build Coastguard Worker    // Save args, the hidden arg and caller PC. No CFI needed for args and the hidden arg.
76*795d594fSAndroid Build Coastguard Worker    SAVE_ALL_ARGS_INCREASE_FRAME 2*8
77*795d594fSAndroid Build Coastguard Worker    SAVE_GPR t0, (ALL_ARGS_SIZE + 0)
78*795d594fSAndroid Build Coastguard Worker    SAVE_GPR ra, (ALL_ARGS_SIZE + 8)
79*795d594fSAndroid Build Coastguard Worker
80*795d594fSAndroid Build Coastguard Worker    // Call artCriticalNativeFrameSize(method, caller_pc)
81*795d594fSAndroid Build Coastguard Worker    mv    a0, t0  // a0 := method (from hidden arg)
82*795d594fSAndroid Build Coastguard Worker    mv    a1, ra  // a1 := caller_pc
83*795d594fSAndroid Build Coastguard Worker    call  artCriticalNativeFrameSize
84*795d594fSAndroid Build Coastguard Worker
85*795d594fSAndroid Build Coastguard Worker    // Move frame size to T2.
86*795d594fSAndroid Build Coastguard Worker    mv    t2, a0
87*795d594fSAndroid Build Coastguard Worker
88*795d594fSAndroid Build Coastguard Worker    // Restore args, the hidden arg and caller PC.
89*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR t0, (ALL_ARGS_SIZE + 0)
90*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR ra, (ALL_ARGS_SIZE + 8)
91*795d594fSAndroid Build Coastguard Worker    RESTORE_ALL_ARGS_DECREASE_FRAME 2*8
92*795d594fSAndroid Build Coastguard Worker
93*795d594fSAndroid Build Coastguard Worker    // Reserve space for a SaveRefsAndArgs managed frame, either for the actual runtime
94*795d594fSAndroid Build Coastguard Worker    // method or for a GenericJNI frame which is similar but has a native method and a tag.
95*795d594fSAndroid Build Coastguard Worker    // Add space for RA and padding to keep the stack 16-byte aligned.
96*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME (FRAME_SIZE_SAVE_REFS_AND_ARGS + 16)
97*795d594fSAndroid Build Coastguard Worker
98*795d594fSAndroid Build Coastguard Worker    // Prepare the return address for managed stack walk of the SaveRefsAndArgs frame.
99*795d594fSAndroid Build Coastguard Worker    // If we're coming from JNI stub with tail call, it is RA. If we're coming from
100*795d594fSAndroid Build Coastguard Worker    // JNI stub that saved the return address, it will be the last value we copy below.
101*795d594fSAndroid Build Coastguard Worker    // If we're coming directly from compiled code, it is RA, set further down.
102*795d594fSAndroid Build Coastguard Worker    mv    t4, ra
103*795d594fSAndroid Build Coastguard Worker
104*795d594fSAndroid Build Coastguard Worker    // Move the stack args if any. Calculate the base address of the managed frame in the process.
105*795d594fSAndroid Build Coastguard Worker    addi  t1, sp, 16
106*795d594fSAndroid Build Coastguard Worker    beqz  t2, .Lcritical_skip_copy_args
107*795d594fSAndroid Build Coastguard Worker.Lcritical_copy_args_loop:
108*795d594fSAndroid Build Coastguard Worker    ld    t3, FRAME_SIZE_SAVE_REFS_AND_ARGS+0(t1)
109*795d594fSAndroid Build Coastguard Worker    ld    t4, FRAME_SIZE_SAVE_REFS_AND_ARGS+8(t1)
110*795d594fSAndroid Build Coastguard Worker    addi  t2, t2, -16
111*795d594fSAndroid Build Coastguard Worker    sd    t3, 0-16(t1)
112*795d594fSAndroid Build Coastguard Worker    sd    t4, 8-16(t1)
113*795d594fSAndroid Build Coastguard Worker    addi  t1, t1, 16
114*795d594fSAndroid Build Coastguard Worker    bnez  t2, .Lcritical_copy_args_loop
115*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_copy_args:
116*795d594fSAndroid Build Coastguard Worker
117*795d594fSAndroid Build Coastguard Worker    // Spill registers for the SaveRefsAndArgs frame above the stack args.
118*795d594fSAndroid Build Coastguard Worker    // Note that the runtime shall not examine the args here, otherwise we would have to
119*795d594fSAndroid Build Coastguard Worker    // move them in registers and stack to account for the difference between managed and
120*795d594fSAndroid Build Coastguard Worker    // native ABIs. Do not update CFI while we hold the frame address in T1 and the values
121*795d594fSAndroid Build Coastguard Worker    // in registers are unchanged.
122*795d594fSAndroid Build Coastguard Worker    // stack slot (0*8)(t1) is for ArtMethod*
123*795d594fSAndroid Build Coastguard Worker    fsd   fa0, (1*8)(t1)
124*795d594fSAndroid Build Coastguard Worker    fsd   fa1, (2*8)(t1)
125*795d594fSAndroid Build Coastguard Worker    fsd   fa2, (3*8)(t1)
126*795d594fSAndroid Build Coastguard Worker    fsd   fa3, (4*8)(t1)
127*795d594fSAndroid Build Coastguard Worker    fsd   fa4, (5*8)(t1)
128*795d594fSAndroid Build Coastguard Worker    fsd   fa5, (6*8)(t1)
129*795d594fSAndroid Build Coastguard Worker    fsd   fa6, (7*8)(t1)
130*795d594fSAndroid Build Coastguard Worker    fsd   fa7, (8*8)(t1)
131*795d594fSAndroid Build Coastguard Worker    sd    fp,  (9*8)(t1)   // x8, frame pointer
132*795d594fSAndroid Build Coastguard Worker    // s1 (x9) is the ART thread register
133*795d594fSAndroid Build Coastguard Worker    // a0 (x10) is the method pointer
134*795d594fSAndroid Build Coastguard Worker    sd    a1,  (10*8)(t1)  // x11
135*795d594fSAndroid Build Coastguard Worker    sd    a2,  (11*8)(t1)  // x12
136*795d594fSAndroid Build Coastguard Worker    sd    a3,  (12*8)(t1)  // x13
137*795d594fSAndroid Build Coastguard Worker    sd    a4,  (13*8)(t1)  // x14
138*795d594fSAndroid Build Coastguard Worker    sd    a5,  (14*8)(t1)  // x15
139*795d594fSAndroid Build Coastguard Worker    sd    a6,  (15*8)(t1)  // x16
140*795d594fSAndroid Build Coastguard Worker    sd    a7,  (16*8)(t1)  // x17
141*795d594fSAndroid Build Coastguard Worker    sd    s2,  (17*8)(t1)  // x18
142*795d594fSAndroid Build Coastguard Worker    sd    s3,  (18*8)(t1)  // x19
143*795d594fSAndroid Build Coastguard Worker    sd    s4,  (19*8)(t1)  // x20
144*795d594fSAndroid Build Coastguard Worker    sd    s5,  (20*8)(t1)  // x21
145*795d594fSAndroid Build Coastguard Worker    sd    s6,  (21*8)(t1)  // x22
146*795d594fSAndroid Build Coastguard Worker    sd    s7,  (22*8)(t1)  // x23
147*795d594fSAndroid Build Coastguard Worker    sd    s8,  (23*8)(t1)  // x24
148*795d594fSAndroid Build Coastguard Worker    sd    s9,  (24*8)(t1)  // x25
149*795d594fSAndroid Build Coastguard Worker    sd    s10, (25*8)(t1)  // x26
150*795d594fSAndroid Build Coastguard Worker    sd    s11, (26*8)(t1)  // x27
151*795d594fSAndroid Build Coastguard Worker    sd    t4,  (27*8)(t1)  // t4: Save return address for tail call from JNI stub.
152*795d594fSAndroid Build Coastguard Worker    // (If there were any stack args, we're storing the value that's already there.
153*795d594fSAndroid Build Coastguard Worker    // For direct calls from compiled managed code, we shall overwrite this below.)
154*795d594fSAndroid Build Coastguard Worker
155*795d594fSAndroid Build Coastguard Worker    // Move the managed frame address to native callee-save register fp (x8) and update CFI.
156*795d594fSAndroid Build Coastguard Worker    mv    fp, t1
157*795d594fSAndroid Build Coastguard Worker    // Skip args FA0-FA7, A1-A7
158*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG  8, 8, (9*8)
159*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 18, 8, (17*8)
160*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 19, 8, (18*8)
161*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 20, 8, (19*8)
162*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 21, 8, (20*8)
163*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 22, 8, (21*8)
164*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 23, 8, (22*8)
165*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 24, 8, (23*8)
166*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 25, 8, (24*8)
167*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 26, 8, (25*8)
168*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 27, 8, (26*8)
169*795d594fSAndroid Build Coastguard Worker    // The saved return PC for managed stack walk is not necessarily our RA.
170*795d594fSAndroid Build Coastguard Worker
171*795d594fSAndroid Build Coastguard Worker    // Save our return PC below the managed frame.
172*795d594fSAndroid Build Coastguard Worker    sd    ra, -__SIZEOF_POINTER__(fp)
173*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 1, 8, -__SIZEOF_POINTER__
174*795d594fSAndroid Build Coastguard Worker
175*795d594fSAndroid Build Coastguard Worker    lw    t2, ART_METHOD_ACCESS_FLAGS_OFFSET(t0)  // Load access flags.
176*795d594fSAndroid Build Coastguard Worker    addi  t1, fp, 1        // Prepare managed SP tagged for a GenericJNI frame.
177*795d594fSAndroid Build Coastguard Worker    slliw t2, t2, 31 - ACCESS_FLAGS_METHOD_IS_NATIVE_BIT
178*795d594fSAndroid Build Coastguard Worker    bltz  t2, .Lcritical_skip_prepare_runtime_method
179*795d594fSAndroid Build Coastguard Worker
180*795d594fSAndroid Build Coastguard Worker    // When coming from a compiled method, the return PC for managed stack walk is RA.
181*795d594fSAndroid Build Coastguard Worker    // (When coming from a compiled stub, the correct return PC is already stored above.)
182*795d594fSAndroid Build Coastguard Worker    sd    ra, (FRAME_SIZE_SAVE_REFS_AND_ARGS - __SIZEOF_POINTER__)(fp)
183*795d594fSAndroid Build Coastguard Worker
184*795d594fSAndroid Build Coastguard Worker    // Replace the target method with the SaveRefsAndArgs runtime method.
185*795d594fSAndroid Build Coastguard Worker    LOAD_RUNTIME_INSTANCE t0
186*795d594fSAndroid Build Coastguard Worker    ld    t0, RUNTIME_SAVE_REFS_AND_ARGS_METHOD_OFFSET(t0)
187*795d594fSAndroid Build Coastguard Worker
188*795d594fSAndroid Build Coastguard Worker    mv    t1, fp           // Prepare untagged managed SP for the runtime method.
189*795d594fSAndroid Build Coastguard Worker
190*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_prepare_runtime_method:
191*795d594fSAndroid Build Coastguard Worker    // Store the method on the bottom of the managed frame.
192*795d594fSAndroid Build Coastguard Worker    sd    t0, (fp)
193*795d594fSAndroid Build Coastguard Worker
194*795d594fSAndroid Build Coastguard Worker    // Place (maybe tagged) managed SP in Thread::Current()->top_quick_frame.
195*795d594fSAndroid Build Coastguard Worker    sd    t1, THREAD_TOP_QUICK_FRAME_OFFSET(xSELF)
196*795d594fSAndroid Build Coastguard Worker
197*795d594fSAndroid Build Coastguard Worker    // Preserve the native arg register A0 in callee-save register S2 (x18) which was saved above.
198*795d594fSAndroid Build Coastguard Worker    mv    s2, a0
199*795d594fSAndroid Build Coastguard Worker
200*795d594fSAndroid Build Coastguard Worker    // Call artFindNativeMethodRunnable()
201*795d594fSAndroid Build Coastguard Worker    mv    a0, xSELF   // pass Thread::Current()
202*795d594fSAndroid Build Coastguard Worker    call  artFindNativeMethodRunnable
203*795d594fSAndroid Build Coastguard Worker
204*795d594fSAndroid Build Coastguard Worker    // Store result in scratch reg.
205*795d594fSAndroid Build Coastguard Worker    mv    t0, a0
206*795d594fSAndroid Build Coastguard Worker
207*795d594fSAndroid Build Coastguard Worker    // Restore the native arg register A0.
208*795d594fSAndroid Build Coastguard Worker    mv    a0, s2
209*795d594fSAndroid Build Coastguard Worker
210*795d594fSAndroid Build Coastguard Worker    // Restore our return PC.
211*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR_BASE fp, ra, -__SIZEOF_POINTER__
212*795d594fSAndroid Build Coastguard Worker
213*795d594fSAndroid Build Coastguard Worker    // Remember the end of out args before restoring FP.
214*795d594fSAndroid Build Coastguard Worker    addi  t1, fp, -16
215*795d594fSAndroid Build Coastguard Worker
216*795d594fSAndroid Build Coastguard Worker    // Restore arg registers.
217*795d594fSAndroid Build Coastguard Worker    fld   fa0, (1*8)(fp)
218*795d594fSAndroid Build Coastguard Worker    fld   fa1, (2*8)(fp)
219*795d594fSAndroid Build Coastguard Worker    fld   fa2, (3*8)(fp)
220*795d594fSAndroid Build Coastguard Worker    fld   fa3, (4*8)(fp)
221*795d594fSAndroid Build Coastguard Worker    fld   fa4, (5*8)(fp)
222*795d594fSAndroid Build Coastguard Worker    fld   fa5, (6*8)(fp)
223*795d594fSAndroid Build Coastguard Worker    fld   fa6, (7*8)(fp)
224*795d594fSAndroid Build Coastguard Worker    fld   fa7, (8*8)(fp)
225*795d594fSAndroid Build Coastguard Worker    // fp (x8) is restored last to keep CFI data valid until then.
226*795d594fSAndroid Build Coastguard Worker    // s1 (x9) is the ART thread register
227*795d594fSAndroid Build Coastguard Worker    // a0 (x10) is the method pointer
228*795d594fSAndroid Build Coastguard Worker    ld    a1,  (10*8)(fp)  // x11
229*795d594fSAndroid Build Coastguard Worker    ld    a2,  (11*8)(fp)  // x12
230*795d594fSAndroid Build Coastguard Worker    ld    a3,  (12*8)(fp)  // x13
231*795d594fSAndroid Build Coastguard Worker    ld    a4,  (13*8)(fp)  // x14
232*795d594fSAndroid Build Coastguard Worker    ld    a5,  (14*8)(fp)  // x15
233*795d594fSAndroid Build Coastguard Worker    ld    a6,  (15*8)(fp)  // x16
234*795d594fSAndroid Build Coastguard Worker    ld    a7,  (16*8)(fp)  // x17
235*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR_BASE fp, s2,  (17*8)  // x18
236*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR_BASE fp, s3,  (18*8)  // x19
237*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR_BASE fp, s4,  (19*8)  // x20
238*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR_BASE fp, s5,  (20*8)  // x21
239*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR_BASE fp, s6,  (21*8)  // x22
240*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR_BASE fp, s7,  (22*8)  // x23
241*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR_BASE fp, s8,  (23*8)  // x24
242*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR_BASE fp, s9,  (24*8)  // x25
243*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR_BASE fp, s10, (25*8)  // x26
244*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR_BASE fp, s11, (26*8)  // x27
245*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR_BASE fp, fp,  (9*8)   // fp (x8) is restored last
246*795d594fSAndroid Build Coastguard Worker
247*795d594fSAndroid Build Coastguard Worker    // Check for exception before moving args back to keep the return PC for managed stack walk.
248*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
249*795d594fSAndroid Build Coastguard Worker    beqz  t0, .Lcritical_deliver_exception
250*795d594fSAndroid Build Coastguard Worker
251*795d594fSAndroid Build Coastguard Worker    // Move stack args to their original place.
252*795d594fSAndroid Build Coastguard Worker    beq   t1, sp, .Lcritical_skip_copy_args_back
253*795d594fSAndroid Build Coastguard Worker    sub   t2, t1, sp
254*795d594fSAndroid Build Coastguard Worker.Lcritical_copy_args_back_loop:
255*795d594fSAndroid Build Coastguard Worker    ld    t3, 0-16(t1)
256*795d594fSAndroid Build Coastguard Worker    ld    t4, 8-16(t1)
257*795d594fSAndroid Build Coastguard Worker    addi  t2, t2, -16
258*795d594fSAndroid Build Coastguard Worker    sd    t3, FRAME_SIZE_SAVE_REFS_AND_ARGS+0(t1)
259*795d594fSAndroid Build Coastguard Worker    sd    t4, FRAME_SIZE_SAVE_REFS_AND_ARGS+8(t1)
260*795d594fSAndroid Build Coastguard Worker    addi  t1, t1, -16
261*795d594fSAndroid Build Coastguard Worker    bnez  t2, .Lcritical_copy_args_back_loop
262*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_copy_args_back:
263*795d594fSAndroid Build Coastguard Worker
264*795d594fSAndroid Build Coastguard Worker    // Remove the frame reservation.
265*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME (FRAME_SIZE_SAVE_REFS_AND_ARGS + 16)
266*795d594fSAndroid Build Coastguard Worker
267*795d594fSAndroid Build Coastguard Worker    // Do the tail call.
268*795d594fSAndroid Build Coastguard Worker    jr    t0
269*795d594fSAndroid Build Coastguard Worker
270*795d594fSAndroid Build Coastguard Worker.Lcritical_deliver_exception:
271*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_REFS_AND_ARGS + 16
272*795d594fSAndroid Build Coastguard Worker    // If this is called from a method that catches the exception, all callee-save registers need
273*795d594fSAndroid Build Coastguard Worker    // to be saved, so that the exception handling code can read them in case they contain live
274*795d594fSAndroid Build Coastguard Worker    // values later used by that method. This includes callee-save FP registers which are not
275*795d594fSAndroid Build Coastguard Worker    // saved in a SaveRefsAndArgs frame, so we cannot reuse the managed frame we have built above.
276*795d594fSAndroid Build Coastguard Worker    // That's why we checked for exception after restoring registers from that frame.
277*795d594fSAndroid Build Coastguard Worker    // We need to build a SaveAllCalleeSaves frame instead. Args are irrelevant at this
278*795d594fSAndroid Build Coastguard Worker    // point but keep the area allocated for stack args to keep CFA definition simple.
279*795d594fSAndroid Build Coastguard Worker#if FRAME_SIZE_SAVE_ALL_CALLEE_SAVES > FRAME_SIZE_SAVE_REFS_AND_ARGS
280*795d594fSAndroid Build Coastguard Worker#error "Expanding stack frame from kSaveRefsAndArgs to kSaveAllCalleeSaves is not implemented."
281*795d594fSAndroid Build Coastguard Worker#endif
282*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS - FRAME_SIZE_SAVE_ALL_CALLEE_SAVES
283*795d594fSAndroid Build Coastguard Worker
284*795d594fSAndroid Build Coastguard Worker    // Calculate the base address of the managed frame.
285*795d594fSAndroid Build Coastguard Worker    addi  t1, t1, 16 + FRAME_SIZE_SAVE_REFS_AND_ARGS - FRAME_SIZE_SAVE_ALL_CALLEE_SAVES
286*795d594fSAndroid Build Coastguard Worker
287*795d594fSAndroid Build Coastguard Worker    // Spill registers for the SaveAllCalleeSaves frame above the stack args area. Do not update
288*795d594fSAndroid Build Coastguard Worker    // CFI while we hold the frame address in T1 and the values in registers are unchanged.
289*795d594fSAndroid Build Coastguard Worker    // stack slot (0*8)(t1) is for ArtMethod*
290*795d594fSAndroid Build Coastguard Worker    // stack slot (1*8)(t1) is for padding
291*795d594fSAndroid Build Coastguard Worker    // FP callee-saves.
292*795d594fSAndroid Build Coastguard Worker    fsd   fs0,  (8*2)(t1)   // f8
293*795d594fSAndroid Build Coastguard Worker    fsd   fs1,  (8*3)(t1)   // f9
294*795d594fSAndroid Build Coastguard Worker    fsd   fs2,  (8*4)(t1)   // f18
295*795d594fSAndroid Build Coastguard Worker    fsd   fs3,  (8*5)(t1)   // f19
296*795d594fSAndroid Build Coastguard Worker    fsd   fs4,  (8*6)(t1)   // f20
297*795d594fSAndroid Build Coastguard Worker    fsd   fs5,  (8*7)(t1)   // f21
298*795d594fSAndroid Build Coastguard Worker    fsd   fs6,  (8*8)(t1)   // f22
299*795d594fSAndroid Build Coastguard Worker    fsd   fs7,  (8*9)(t1)   // f23
300*795d594fSAndroid Build Coastguard Worker    fsd   fs8,  (8*10)(t1)  // f24
301*795d594fSAndroid Build Coastguard Worker    fsd   fs9,  (8*11)(t1)  // f25
302*795d594fSAndroid Build Coastguard Worker    fsd   fs10, (8*12)(t1)  // f26
303*795d594fSAndroid Build Coastguard Worker    fsd   fs11, (8*13)(t1)  // f27
304*795d594fSAndroid Build Coastguard Worker    // GP callee-saves
305*795d594fSAndroid Build Coastguard Worker    sd    s0,  (8*14)(t1)  // x8/fp, frame pointer
306*795d594fSAndroid Build Coastguard Worker    // s1 (x9) is the ART thread register
307*795d594fSAndroid Build Coastguard Worker    sd    s2,  (8*15)(t1)  // x18
308*795d594fSAndroid Build Coastguard Worker    sd    s3,  (8*16)(t1)  // x19
309*795d594fSAndroid Build Coastguard Worker    sd    s4,  (8*17)(t1)  // x20
310*795d594fSAndroid Build Coastguard Worker    sd    s5,  (8*18)(t1)  // x21
311*795d594fSAndroid Build Coastguard Worker    sd    s6,  (8*19)(t1)  // x22
312*795d594fSAndroid Build Coastguard Worker    sd    s7,  (8*20)(t1)  // x23
313*795d594fSAndroid Build Coastguard Worker    sd    s8,  (8*21)(t1)  // x24
314*795d594fSAndroid Build Coastguard Worker    sd    s9,  (8*22)(t1)  // x25
315*795d594fSAndroid Build Coastguard Worker    sd    s10, (8*23)(t1)  // x26
316*795d594fSAndroid Build Coastguard Worker    sd    s11, (8*24)(t1)  // x27
317*795d594fSAndroid Build Coastguard Worker    // Keep the caller PC for managed stack walk.
318*795d594fSAndroid Build Coastguard Worker
319*795d594fSAndroid Build Coastguard Worker    // Move the managed frame address to native callee-save register fp (x8) and update CFI.
320*795d594fSAndroid Build Coastguard Worker    mv    fp, t1
321*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG  8, 8, (14*8)  // fp/x8: The base register for these CFI expressions.
322*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG  /*FP reg*/ 32 + 8, 8, (8*2)    // fs0/f8
323*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG  /*FP reg*/ 32 + 9, 8, (8*3)    // fs1/f9
324*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG  /*FP reg*/ 32 + 18, 8, (8*4)   // fs2/f18
325*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG  /*FP reg*/ 32 + 19, 8, (8*5)   // fs3/f19
326*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG  /*FP reg*/ 32 + 20, 8, (8*6)   // fs4/f20
327*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG  /*FP reg*/ 32 + 21, 8, (8*7)   // fs5/f21
328*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG  /*FP reg*/ 32 + 22, 8, (8*8)   // fs6/f22
329*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG  /*FP reg*/ 32 + 23, 8, (8*9)   // fs7/f23
330*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG  /*FP reg*/ 32 + 24, 8, (8*10)  // fs8/f24
331*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG  /*FP reg*/ 32 + 25, 8, (8*11)  // fs9/f25
332*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG  /*FP reg*/ 32 + 26, 8, (8*12)  // fs10/f26
333*795d594fSAndroid Build Coastguard Worker    // CFI expression for fp (x8) already emitted above.
334*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 18, 8, (15*8)  // s2/x18
335*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 19, 8, (16*8)  // s3/x19
336*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 20, 8, (17*8)  // s4/x20
337*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 21, 8, (18*8)  // s5/x21
338*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 22, 8, (19*8)  // s6/x22
339*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 23, 8, (20*8)  // s7/x23
340*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 24, 8, (21*8)  // s8/x24
341*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 25, 8, (22*8)  // s9/x25
342*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 26, 8, (23*8)  // s10/x26
343*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 27, 8, (24*8)  // s11/x27
344*795d594fSAndroid Build Coastguard Worker    // The saved return PC for managed stack walk is not necessarily our RA.
345*795d594fSAndroid Build Coastguard Worker
346*795d594fSAndroid Build Coastguard Worker    // Save our return PC below the managed frame.
347*795d594fSAndroid Build Coastguard Worker    sd    ra, -__SIZEOF_POINTER__(fp)
348*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 1, 8, -__SIZEOF_POINTER__
349*795d594fSAndroid Build Coastguard Worker
350*795d594fSAndroid Build Coastguard Worker    // Store ArtMethod* Runtime::callee_save_methods_[kSaveAllCalleeSaves] to the managed frame.
351*795d594fSAndroid Build Coastguard Worker    LOAD_RUNTIME_INSTANCE t0
352*795d594fSAndroid Build Coastguard Worker    ld    t0, RUNTIME_SAVE_ALL_CALLEE_SAVES_METHOD_OFFSET(t0)
353*795d594fSAndroid Build Coastguard Worker    sd    t0, (fp)
354*795d594fSAndroid Build Coastguard Worker
355*795d594fSAndroid Build Coastguard Worker    // Place the managed frame SP in Thread::Current()->top_quick_frame.
356*795d594fSAndroid Build Coastguard Worker    sd    fp, THREAD_TOP_QUICK_FRAME_OFFSET(xSELF)
357*795d594fSAndroid Build Coastguard Worker
358*795d594fSAndroid Build Coastguard Worker    DELIVER_PENDING_EXCEPTION_FRAME_READY
359*795d594fSAndroid Build Coastguard WorkerEND art_jni_dlsym_lookup_critical_stub
360*795d594fSAndroid Build Coastguard Worker
361*795d594fSAndroid Build Coastguard Worker    /*
362*795d594fSAndroid Build Coastguard Worker     * Read barrier for the method's declaring class needed by JNI stub for static methods.
363*795d594fSAndroid Build Coastguard Worker     * (We're using a pointer to the declaring class in `ArtMethod` as `jclass`.)
364*795d594fSAndroid Build Coastguard Worker     */
365*795d594fSAndroid Build Coastguard Worker// The method argument is already in a0 for call to `artJniReadBarrier(ArtMethod*)`.
366*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_read_barrier, artJniReadBarrier
367*795d594fSAndroid Build Coastguard Worker
368*795d594fSAndroid Build Coastguard Worker    /*
369*795d594fSAndroid Build Coastguard Worker     * Trampoline to `artJniMethodStart()` that preserves all managed arguments.
370*795d594fSAndroid Build Coastguard Worker     */
371*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_method_start, artJniMethodStart, xSELF
372*795d594fSAndroid Build Coastguard Worker
373*795d594fSAndroid Build Coastguard Worker    /*
374*795d594fSAndroid Build Coastguard Worker     * Trampoline to `artJniMethodEntryHook` that preserves all managed arguments.
375*795d594fSAndroid Build Coastguard Worker     */
376*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_method_entry_hook, artJniMethodEntryHook, xSELF
377*795d594fSAndroid Build Coastguard Worker
378*795d594fSAndroid Build Coastguard Worker    /*
379*795d594fSAndroid Build Coastguard Worker     * Trampoline to `artJniMonitoredMethodStart()` that preserves all managed arguments.
380*795d594fSAndroid Build Coastguard Worker     */
381*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_monitored_method_start, artJniMonitoredMethodStart, xSELF
382*795d594fSAndroid Build Coastguard Worker
383*795d594fSAndroid Build Coastguard Worker    /*
384*795d594fSAndroid Build Coastguard Worker     * Trampoline to `artJniMethodEnd()` that preserves all return registers.
385*795d594fSAndroid Build Coastguard Worker     */
386*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_method_end, artJniMethodEnd, xSELF
387*795d594fSAndroid Build Coastguard Worker
388*795d594fSAndroid Build Coastguard Worker    /*
389*795d594fSAndroid Build Coastguard Worker     * Trampoline to `artJniMonitoredMethodEnd()` that preserves all return registers.
390*795d594fSAndroid Build Coastguard Worker     */
391*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_monitored_method_end, artJniMonitoredMethodEnd, xSELF
392*795d594fSAndroid Build Coastguard Worker
393*795d594fSAndroid Build Coastguard Worker    /*
394*795d594fSAndroid Build Coastguard Worker     * Entry from JNI stub that tries to lock the object in a fast path and
395*795d594fSAndroid Build Coastguard Worker     * calls `artLockObjectFromCode()` (the same as for managed code) for the
396*795d594fSAndroid Build Coastguard Worker     * difficult cases, may block for GC.
397*795d594fSAndroid Build Coastguard Worker     * Custom calling convention:
398*795d594fSAndroid Build Coastguard Worker     *     T0 holds the non-null object to lock.
399*795d594fSAndroid Build Coastguard Worker     *     Callee-save registers have been saved and can be used as temporaries.
400*795d594fSAndroid Build Coastguard Worker     *     All argument registers need to be preserved.
401*795d594fSAndroid Build Coastguard Worker     */
402*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_lock_object
403*795d594fSAndroid Build Coastguard Worker    LOCK_OBJECT_FAST_PATH t0, art_jni_lock_object_no_inline, /*can_be_null*/ 0
404*795d594fSAndroid Build Coastguard WorkerEND art_jni_lock_object
405*795d594fSAndroid Build Coastguard Worker
406*795d594fSAndroid Build Coastguard Worker    /*
407*795d594fSAndroid Build Coastguard Worker     * Entry from JNI stub that calls `artLockObjectFromCode()`
408*795d594fSAndroid Build Coastguard Worker     * (the same as for managed code), may block for GC.
409*795d594fSAndroid Build Coastguard Worker     * Custom calling convention:
410*795d594fSAndroid Build Coastguard Worker     *     T0 holds the non-null object to lock.
411*795d594fSAndroid Build Coastguard Worker     *     Callee-save registers have been saved and can be used as temporaries.
412*795d594fSAndroid Build Coastguard Worker     *     All argument registers need to be preserved.
413*795d594fSAndroid Build Coastguard Worker     */
414*795d594fSAndroid Build Coastguard Worker    .extern artLockObjectFromCode
415*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_lock_object_no_inline
416*795d594fSAndroid Build Coastguard Worker    // This is also the slow path for art_jni_lock_object.
417*795d594fSAndroid Build Coastguard Worker    // Save args and RA.
418*795d594fSAndroid Build Coastguard Worker    SAVE_ALL_ARGS_INCREASE_FRAME /*padding*/ 8 + /*RA*/ 8
419*795d594fSAndroid Build Coastguard Worker    SAVE_GPR ra, (ALL_ARGS_SIZE + /*padding*/ 8)
420*795d594fSAndroid Build Coastguard Worker    // Call `artLockObjectFromCode()`.
421*795d594fSAndroid Build Coastguard Worker    mv    a0, t0                     // Pass the object to lock.
422*795d594fSAndroid Build Coastguard Worker    mv    a1, xSELF                  // Pass Thread::Current().
423*795d594fSAndroid Build Coastguard Worker    call  artLockObjectFromCode      // (Object* obj, Thread*)
424*795d594fSAndroid Build Coastguard Worker    // Restore return address.
425*795d594fSAndroid Build Coastguard Worker    RESTORE_GPR ra, (ALL_ARGS_SIZE + /*padding*/ 8)
426*795d594fSAndroid Build Coastguard Worker    // Check result.
427*795d594fSAndroid Build Coastguard Worker    bnez   a0, 1f
428*795d594fSAndroid Build Coastguard Worker    // Restore register args a0-a7, fa0-fa7 and return.
429*795d594fSAndroid Build Coastguard Worker    RESTORE_ALL_ARGS_DECREASE_FRAME /*padding*/ 8 + /*RA*/ 8
430*795d594fSAndroid Build Coastguard Worker    ret
431*795d594fSAndroid Build Coastguard Worker    .cfi_adjust_cfa_offset (ALL_ARGS_SIZE + /*padding*/ 8 + /*RA*/ 8)
432*795d594fSAndroid Build Coastguard Worker1:
433*795d594fSAndroid Build Coastguard Worker    // All args are irrelevant when throwing an exception. Remove the spill area.
434*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME (ALL_ARGS_SIZE + /*padding*/ 8 + /*RA*/ 8)
435*795d594fSAndroid Build Coastguard Worker    // Make a call to `artDeliverPendingExceptionFromCode()`.
436*795d594fSAndroid Build Coastguard Worker    // Rely on the JNI transition frame constructed in the JNI stub.
437*795d594fSAndroid Build Coastguard Worker    mv     a0, xSELF                           // Pass Thread::Current().
438*795d594fSAndroid Build Coastguard Worker    call   artDeliverPendingExceptionFromCode  // (Thread*)
439*795d594fSAndroid Build Coastguard Worker    call   art_quick_do_long_jump              // (Context*)
440*795d594fSAndroid Build Coastguard Worker    unimp  // Unreached
441*795d594fSAndroid Build Coastguard WorkerEND art_jni_lock_object_no_inline
442*795d594fSAndroid Build Coastguard Worker
443*795d594fSAndroid Build Coastguard Worker    /*
444*795d594fSAndroid Build Coastguard Worker     * Entry from JNI stub that tries to unlock the object in a fast path and calls
445*795d594fSAndroid Build Coastguard Worker     * `artJniUnlockObject()` for the difficult cases. Note that failure to unlock
446*795d594fSAndroid Build Coastguard Worker     * is fatal, so we do not need to check for exceptions in the slow path.
447*795d594fSAndroid Build Coastguard Worker     * Custom calling convention:
448*795d594fSAndroid Build Coastguard Worker     *     T0 holds the non-null object to unlock.
449*795d594fSAndroid Build Coastguard Worker     *     Callee-save registers have been saved and can be used as temporaries.
450*795d594fSAndroid Build Coastguard Worker     *     Return registers a0 and fa0 need to be preserved.
451*795d594fSAndroid Build Coastguard Worker     */
452*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_unlock_object
453*795d594fSAndroid Build Coastguard Worker    UNLOCK_OBJECT_FAST_PATH t0, art_jni_unlock_object_no_inline, /*can_be_null*/ 0
454*795d594fSAndroid Build Coastguard WorkerEND art_jni_unlock_object
455*795d594fSAndroid Build Coastguard Worker
456*795d594fSAndroid Build Coastguard Worker    /*
457*795d594fSAndroid Build Coastguard Worker     * Entry from JNI stub that calls `artJniUnlockObject()`. Note that failure to
458*795d594fSAndroid Build Coastguard Worker     * unlock is fatal, so we do not need to check for exceptions.
459*795d594fSAndroid Build Coastguard Worker     * Custom calling convention:
460*795d594fSAndroid Build Coastguard Worker     *     T0 holds the non-null object to unlock.
461*795d594fSAndroid Build Coastguard Worker     *     Callee-save registers have been saved and can be used as temporaries.
462*795d594fSAndroid Build Coastguard Worker     *     Return registers a0 and fa0 need to be preserved.
463*795d594fSAndroid Build Coastguard Worker     */
464*795d594fSAndroid Build Coastguard Worker    // This is also the slow path for art_jni_unlock_object.
465*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_unlock_object_no_inline, artJniUnlockObject, t0, xSELF
466