xref: /aosp_15_r20/art/runtime/interpreter/mterp/arm64ng/main.S (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker%def header():
2*795d594fSAndroid Build Coastguard Worker/*
3*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project
4*795d594fSAndroid Build Coastguard Worker *
5*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
8*795d594fSAndroid Build Coastguard Worker *
9*795d594fSAndroid Build Coastguard Worker *      http://www.apache.org/licenses/LICENSE-2.0
10*795d594fSAndroid Build Coastguard Worker *
11*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*795d594fSAndroid Build Coastguard Worker * limitations under the License.
16*795d594fSAndroid Build Coastguard Worker */
17*795d594fSAndroid Build Coastguard Worker
18*795d594fSAndroid Build Coastguard Worker/*
19*795d594fSAndroid Build Coastguard Worker * This is a #include, not a %include, because we want the C pre-processor
20*795d594fSAndroid Build Coastguard Worker * to expand the macros into assembler assignment statements.
21*795d594fSAndroid Build Coastguard Worker */
22*795d594fSAndroid Build Coastguard Worker#include "asm_support.h"
23*795d594fSAndroid Build Coastguard Worker#include "arch/arm64/asm_support_arm64.S"
24*795d594fSAndroid Build Coastguard Worker
25*795d594fSAndroid Build Coastguard Worker/**
26*795d594fSAndroid Build Coastguard Worker * ARM64 Runtime register usage conventions.
27*795d594fSAndroid Build Coastguard Worker *
28*795d594fSAndroid Build Coastguard Worker *   r0     : w0 is 32-bit return register and x0 is 64-bit.
29*795d594fSAndroid Build Coastguard Worker *   r0-r7  : Argument registers.
30*795d594fSAndroid Build Coastguard Worker *   r8-r15 : Caller save registers (used as temporary registers).
31*795d594fSAndroid Build Coastguard Worker *   r16-r17: Also known as ip0-ip1, respectively. Used as scratch registers by
32*795d594fSAndroid Build Coastguard Worker *            the linker, by the trampolines and other stubs (the compiler uses
33*795d594fSAndroid Build Coastguard Worker *            these as temporary registers).
34*795d594fSAndroid Build Coastguard Worker *   r18    : Reserved for platform (SCS, shadow call stack)
35*795d594fSAndroid Build Coastguard Worker *   r19    : Pointer to thread-local storage.
36*795d594fSAndroid Build Coastguard Worker *   r20-r29: Callee save registers.
37*795d594fSAndroid Build Coastguard Worker *   r30    : (lr) is reserved (the link register).
38*795d594fSAndroid Build Coastguard Worker *   rsp    : (sp) is reserved (the stack pointer).
39*795d594fSAndroid Build Coastguard Worker *   rzr    : (zr) is reserved (the zero register).
40*795d594fSAndroid Build Coastguard Worker *
41*795d594fSAndroid Build Coastguard Worker *   Floating-point registers
42*795d594fSAndroid Build Coastguard Worker *   v0-v31
43*795d594fSAndroid Build Coastguard Worker *
44*795d594fSAndroid Build Coastguard Worker *   v0     : s0 is return register for singles (32-bit) and d0 for doubles (64-bit).
45*795d594fSAndroid Build Coastguard Worker *            This is analogous to the C/C++ (hard-float) calling convention.
46*795d594fSAndroid Build Coastguard Worker *   v0-v7  : Floating-point argument registers in both Dalvik and C/C++ conventions.
47*795d594fSAndroid Build Coastguard Worker *            Also used as temporary and codegen scratch registers.
48*795d594fSAndroid Build Coastguard Worker *
49*795d594fSAndroid Build Coastguard Worker *   v0-v7 and v16-v31 : Caller save registers (used as temporary registers).
50*795d594fSAndroid Build Coastguard Worker *   v8-v15 : bottom 64-bits preserved across C calls (d8-d15 are preserved).
51*795d594fSAndroid Build Coastguard Worker *
52*795d594fSAndroid Build Coastguard Worker *   v16-v31: Used as codegen temp/scratch.
53*795d594fSAndroid Build Coastguard Worker *   v8-v15 : Can be used for promotion.
54*795d594fSAndroid Build Coastguard Worker *
55*795d594fSAndroid Build Coastguard Worker *   Must maintain 16-byte stack alignment.
56*795d594fSAndroid Build Coastguard Worker *
57*795d594fSAndroid Build Coastguard Worker * Nterp notes:
58*795d594fSAndroid Build Coastguard Worker *
59*795d594fSAndroid Build Coastguard Worker * The following registers have fixed assignments:
60*795d594fSAndroid Build Coastguard Worker *
61*795d594fSAndroid Build Coastguard Worker *   reg nick      purpose
62*795d594fSAndroid Build Coastguard Worker *   x19  xSELF     self (Thread) pointer
63*795d594fSAndroid Build Coastguard Worker *   x20  wMR       marking register
64*795d594fSAndroid Build Coastguard Worker *   x21  xSUSPEND  suspend check register
65*795d594fSAndroid Build Coastguard Worker *   x29  xFP       interpreted frame pointer, used for accessing locals and args
66*795d594fSAndroid Build Coastguard Worker *   x22  xPC       interpreted program counter, used for fetching instructions
67*795d594fSAndroid Build Coastguard Worker *   x23  xINST     first 16-bit code unit of current instruction
68*795d594fSAndroid Build Coastguard Worker *   x24  xIBASE    interpreted instruction base pointer, used for computed goto
69*795d594fSAndroid Build Coastguard Worker *   x25  xREFS     base of object references of dex registers.
70*795d594fSAndroid Build Coastguard Worker *   x16  ip        scratch reg
71*795d594fSAndroid Build Coastguard Worker *   x17  ip2       scratch reg (used by macros)
72*795d594fSAndroid Build Coastguard Worker *
73*795d594fSAndroid Build Coastguard Worker * Macros are provided for common operations.  They MUST NOT alter unspecified registers or
74*795d594fSAndroid Build Coastguard Worker * condition codes.
75*795d594fSAndroid Build Coastguard Worker*/
76*795d594fSAndroid Build Coastguard Worker
77*795d594fSAndroid Build Coastguard Worker/* single-purpose registers, given names for clarity */
78*795d594fSAndroid Build Coastguard Worker#define CFI_DEX  22 // DWARF register number of the register holding dex-pc (xPC).
79*795d594fSAndroid Build Coastguard Worker#define CFI_TMP  0  // DWARF register number of the first argument register (r0).
80*795d594fSAndroid Build Coastguard Worker#define xPC      x22
81*795d594fSAndroid Build Coastguard Worker#define xINST    x23
82*795d594fSAndroid Build Coastguard Worker#define wINST    w23
83*795d594fSAndroid Build Coastguard Worker#define xIBASE   x24
84*795d594fSAndroid Build Coastguard Worker#define xREFS    x25
85*795d594fSAndroid Build Coastguard Worker#define CFI_REFS 25
86*795d594fSAndroid Build Coastguard Worker#define ip       x16
87*795d594fSAndroid Build Coastguard Worker#define ip2      x17
88*795d594fSAndroid Build Coastguard Worker#define wip      w16
89*795d594fSAndroid Build Coastguard Worker#define wip2     w17
90*795d594fSAndroid Build Coastguard Worker
91*795d594fSAndroid Build Coastguard Worker// To avoid putting ifdefs arond the use of wMR, make sure it's defined.
92*795d594fSAndroid Build Coastguard Worker// IsNterpSupported returns false for configurations that don't have wMR (typically CMS).
93*795d594fSAndroid Build Coastguard Worker#ifndef wMR
94*795d594fSAndroid Build Coastguard Worker#define wMR w20
95*795d594fSAndroid Build Coastguard Worker#endif
96*795d594fSAndroid Build Coastguard Worker
97*795d594fSAndroid Build Coastguard Worker// Temporary registers while setting up a frame.
98*795d594fSAndroid Build Coastguard Worker#define xNEW_FP   x26
99*795d594fSAndroid Build Coastguard Worker#define xNEW_REFS x27
100*795d594fSAndroid Build Coastguard Worker#define CFI_NEW_REFS 27
101*795d594fSAndroid Build Coastguard Worker
102*795d594fSAndroid Build Coastguard Worker// +8 for the ArtMethod of the caller.
103*795d594fSAndroid Build Coastguard Worker#define OFFSET_TO_FIRST_ARGUMENT_IN_STACK (CALLEE_SAVES_SIZE + 8)
104*795d594fSAndroid Build Coastguard Worker
105*795d594fSAndroid Build Coastguard Worker/*
106*795d594fSAndroid Build Coastguard Worker * Fetch the next instruction from xPC into wINST.  Does not advance xPC.
107*795d594fSAndroid Build Coastguard Worker */
108*795d594fSAndroid Build Coastguard Worker.macro FETCH_INST
109*795d594fSAndroid Build Coastguard Worker    ldrh    wINST, [xPC]
110*795d594fSAndroid Build Coastguard Worker.endm
111*795d594fSAndroid Build Coastguard Worker
112*795d594fSAndroid Build Coastguard Worker/*
113*795d594fSAndroid Build Coastguard Worker * Fetch the next instruction from the specified offset.  Advances xPC
114*795d594fSAndroid Build Coastguard Worker * to point to the next instruction.  "count" is in 16-bit code units.
115*795d594fSAndroid Build Coastguard Worker *
116*795d594fSAndroid Build Coastguard Worker * Because of the limited size of immediate constants on ARM, this is only
117*795d594fSAndroid Build Coastguard Worker * suitable for small forward movements (i.e. don't try to implement "goto"
118*795d594fSAndroid Build Coastguard Worker * with this).
119*795d594fSAndroid Build Coastguard Worker *
120*795d594fSAndroid Build Coastguard Worker * This must come AFTER anything that can throw an exception, or the
121*795d594fSAndroid Build Coastguard Worker * exception catch may miss.  (This also implies that it must come after
122*795d594fSAndroid Build Coastguard Worker * EXPORT_PC.)
123*795d594fSAndroid Build Coastguard Worker */
124*795d594fSAndroid Build Coastguard Worker.macro FETCH_ADVANCE_INST count
125*795d594fSAndroid Build Coastguard Worker    ldrh    wINST, [xPC, #((\count)*2)]!
126*795d594fSAndroid Build Coastguard Worker.endm
127*795d594fSAndroid Build Coastguard Worker
128*795d594fSAndroid Build Coastguard Worker/*
129*795d594fSAndroid Build Coastguard Worker * Similar to FETCH_ADVANCE_INST, but does not update xPC.  Used to load
130*795d594fSAndroid Build Coastguard Worker * xINST ahead of possible exception point.  Be sure to manually advance xPC
131*795d594fSAndroid Build Coastguard Worker * later.
132*795d594fSAndroid Build Coastguard Worker */
133*795d594fSAndroid Build Coastguard Worker.macro PREFETCH_INST count
134*795d594fSAndroid Build Coastguard Worker    ldrh    wINST, [xPC, #((\count)*2)]
135*795d594fSAndroid Build Coastguard Worker.endm
136*795d594fSAndroid Build Coastguard Worker
137*795d594fSAndroid Build Coastguard Worker/* Advance xPC by some number of code units. */
138*795d594fSAndroid Build Coastguard Worker.macro ADVANCE count
139*795d594fSAndroid Build Coastguard Worker  add  xPC, xPC, #((\count)*2)
140*795d594fSAndroid Build Coastguard Worker.endm
141*795d594fSAndroid Build Coastguard Worker
142*795d594fSAndroid Build Coastguard Worker/*
143*795d594fSAndroid Build Coastguard Worker * Fetch a half-word code unit from an offset past the current PC.  The
144*795d594fSAndroid Build Coastguard Worker * "count" value is in 16-bit code units.  Does not advance xPC.
145*795d594fSAndroid Build Coastguard Worker *
146*795d594fSAndroid Build Coastguard Worker * The "_S" variant works the same but treats the value as signed.
147*795d594fSAndroid Build Coastguard Worker */
148*795d594fSAndroid Build Coastguard Worker.macro FETCH reg, count
149*795d594fSAndroid Build Coastguard Worker    ldrh    \reg, [xPC, #((\count)*2)]
150*795d594fSAndroid Build Coastguard Worker.endm
151*795d594fSAndroid Build Coastguard Worker
152*795d594fSAndroid Build Coastguard Worker.macro FETCH_S reg, count
153*795d594fSAndroid Build Coastguard Worker    ldrsh   \reg, [xPC, #((\count)*2)]
154*795d594fSAndroid Build Coastguard Worker.endm
155*795d594fSAndroid Build Coastguard Worker
156*795d594fSAndroid Build Coastguard Worker/*
157*795d594fSAndroid Build Coastguard Worker * Fetch one byte from an offset past the current PC.  Pass in the same
158*795d594fSAndroid Build Coastguard Worker * "count" as you would for FETCH, and an additional 0/1 indicating which
159*795d594fSAndroid Build Coastguard Worker * byte of the halfword you want (lo/hi).
160*795d594fSAndroid Build Coastguard Worker */
161*795d594fSAndroid Build Coastguard Worker.macro FETCH_B reg, count, byte
162*795d594fSAndroid Build Coastguard Worker    ldrb     \reg, [xPC, #((\count)*2+(\byte))]
163*795d594fSAndroid Build Coastguard Worker.endm
164*795d594fSAndroid Build Coastguard Worker
165*795d594fSAndroid Build Coastguard Worker/*
166*795d594fSAndroid Build Coastguard Worker * Put the instruction's opcode field into the specified register.
167*795d594fSAndroid Build Coastguard Worker */
168*795d594fSAndroid Build Coastguard Worker.macro GET_INST_OPCODE reg
169*795d594fSAndroid Build Coastguard Worker    and     \reg, xINST, #255
170*795d594fSAndroid Build Coastguard Worker.endm
171*795d594fSAndroid Build Coastguard Worker
172*795d594fSAndroid Build Coastguard Worker/*
173*795d594fSAndroid Build Coastguard Worker * Begin executing the opcode in _reg.  Clobbers reg
174*795d594fSAndroid Build Coastguard Worker */
175*795d594fSAndroid Build Coastguard Worker
176*795d594fSAndroid Build Coastguard Worker.macro GOTO_OPCODE reg
177*795d594fSAndroid Build Coastguard Worker    add     \reg, xIBASE, \reg, lsl #${handler_size_bits}
178*795d594fSAndroid Build Coastguard Worker    br      \reg
179*795d594fSAndroid Build Coastguard Worker.endm
180*795d594fSAndroid Build Coastguard Worker
181*795d594fSAndroid Build Coastguard Worker/*
182*795d594fSAndroid Build Coastguard Worker * Get/set the 32-bit value from a Dalvik register.
183*795d594fSAndroid Build Coastguard Worker */
184*795d594fSAndroid Build Coastguard Worker.macro GET_VREG reg, vreg
185*795d594fSAndroid Build Coastguard Worker    ldr     \reg, [xFP, \vreg, uxtw #2]
186*795d594fSAndroid Build Coastguard Worker.endm
187*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_OBJECT reg, vreg
188*795d594fSAndroid Build Coastguard Worker    ldr     \reg, [xREFS, \vreg, uxtw #2]
189*795d594fSAndroid Build Coastguard Worker.endm
190*795d594fSAndroid Build Coastguard Worker.macro SET_VREG reg, vreg
191*795d594fSAndroid Build Coastguard Worker    str     \reg, [xFP, \vreg, uxtw #2]
192*795d594fSAndroid Build Coastguard Worker    str     wzr, [xREFS, \vreg, uxtw #2]
193*795d594fSAndroid Build Coastguard Worker.endm
194*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_OBJECT reg, vreg
195*795d594fSAndroid Build Coastguard Worker    str     \reg, [xFP, \vreg, uxtw #2]
196*795d594fSAndroid Build Coastguard Worker    str     \reg, [xREFS, \vreg, uxtw #2]
197*795d594fSAndroid Build Coastguard Worker.endm
198*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_FLOAT reg, vreg
199*795d594fSAndroid Build Coastguard Worker    str     \reg, [xFP, \vreg, uxtw #2]
200*795d594fSAndroid Build Coastguard Worker    str     wzr, [xREFS, \vreg, uxtw #2]
201*795d594fSAndroid Build Coastguard Worker.endm
202*795d594fSAndroid Build Coastguard Worker
203*795d594fSAndroid Build Coastguard Worker/*
204*795d594fSAndroid Build Coastguard Worker * Get/set the 64-bit value from a Dalvik register.
205*795d594fSAndroid Build Coastguard Worker */
206*795d594fSAndroid Build Coastguard Worker.macro LOAD_SCALED_VREG_MASK scaled_mask_reg, unscaled_mask
207*795d594fSAndroid Build Coastguard Worker    mov     \scaled_mask_reg, \unscaled_mask << 2
208*795d594fSAndroid Build Coastguard Worker.endm
209*795d594fSAndroid Build Coastguard Worker.macro EXTRACT_SCALED_VREG scaled_vreg, scaled_mask_reg, src_reg, lsb
210*795d594fSAndroid Build Coastguard Worker    .if \lsb < 2
211*795d594fSAndroid Build Coastguard Worker    and     \scaled_vreg, \scaled_mask_reg, \src_reg, lsl #(2 - \lsb)
212*795d594fSAndroid Build Coastguard Worker    .else
213*795d594fSAndroid Build Coastguard Worker    and     \scaled_vreg, \scaled_mask_reg, \src_reg, lsr #(\lsb - 2)
214*795d594fSAndroid Build Coastguard Worker    .endif
215*795d594fSAndroid Build Coastguard Worker.endm
216*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_WIDE_PRESCALED reg, scaled_vreg
217*795d594fSAndroid Build Coastguard Worker    ldr     \reg, [xFP, \scaled_vreg, uxtw]
218*795d594fSAndroid Build Coastguard Worker.endm
219*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_WIDE reg, vreg
220*795d594fSAndroid Build Coastguard Worker    lsl     wip2, \vreg, #2
221*795d594fSAndroid Build Coastguard Worker    GET_VREG_WIDE_PRESCALED \reg, wip2
222*795d594fSAndroid Build Coastguard Worker.endm
223*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_WIDE_PRESCALED reg, scaled_vreg
224*795d594fSAndroid Build Coastguard Worker    str     \reg, [xFP, \scaled_vreg, uxtw]
225*795d594fSAndroid Build Coastguard Worker    str     xzr, [xREFS, \scaled_vreg, uxtw]
226*795d594fSAndroid Build Coastguard Worker.endm
227*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_WIDE reg, vreg
228*795d594fSAndroid Build Coastguard Worker    lsl     wip2, \vreg, #2
229*795d594fSAndroid Build Coastguard Worker    SET_VREG_WIDE_PRESCALED \reg, wip2
230*795d594fSAndroid Build Coastguard Worker.endm
231*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_DOUBLE_PRESCALED reg, scaled_vreg
232*795d594fSAndroid Build Coastguard Worker    GET_VREG_WIDE_PRESCALED \reg, \scaled_vreg
233*795d594fSAndroid Build Coastguard Worker.endm
234*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_DOUBLE reg, vreg
235*795d594fSAndroid Build Coastguard Worker    GET_VREG_WIDE \reg, \vreg
236*795d594fSAndroid Build Coastguard Worker.endm
237*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_DOUBLE reg, vreg
238*795d594fSAndroid Build Coastguard Worker    SET_VREG_WIDE \reg, \vreg
239*795d594fSAndroid Build Coastguard Worker.endm
240*795d594fSAndroid Build Coastguard Worker
241*795d594fSAndroid Build Coastguard Worker/*
242*795d594fSAndroid Build Coastguard Worker * Get the 32-bit value from a Dalvik register and sign-extend to 64-bit.
243*795d594fSAndroid Build Coastguard Worker * Used to avoid an extra instruction in int-to-long.
244*795d594fSAndroid Build Coastguard Worker */
245*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_S reg, vreg
246*795d594fSAndroid Build Coastguard Worker    ldrsw   \reg, [xFP, \vreg, uxtw #2]
247*795d594fSAndroid Build Coastguard Worker.endm
248*795d594fSAndroid Build Coastguard Worker
249*795d594fSAndroid Build Coastguard Worker// An assembly entry for nterp.
250*795d594fSAndroid Build Coastguard Worker.macro OAT_ENTRY name
251*795d594fSAndroid Build Coastguard Worker    .type \name, #function
252*795d594fSAndroid Build Coastguard Worker    .hidden \name
253*795d594fSAndroid Build Coastguard Worker    .global \name
254*795d594fSAndroid Build Coastguard Worker    .balign 16
255*795d594fSAndroid Build Coastguard Worker\name:
256*795d594fSAndroid Build Coastguard Worker.endm
257*795d594fSAndroid Build Coastguard Worker
258*795d594fSAndroid Build Coastguard Worker.macro SIZE name
259*795d594fSAndroid Build Coastguard Worker    .size \name, .-\name
260*795d594fSAndroid Build Coastguard Worker.endm
261*795d594fSAndroid Build Coastguard Worker
262*795d594fSAndroid Build Coastguard Worker.macro NAME_START name
263*795d594fSAndroid Build Coastguard Worker    .type \name, #function
264*795d594fSAndroid Build Coastguard Worker    .hidden \name  // Hide this as a global symbol, so we do not incur plt calls.
265*795d594fSAndroid Build Coastguard Worker    .global \name
266*795d594fSAndroid Build Coastguard Worker    /* Cache alignment for function entry */
267*795d594fSAndroid Build Coastguard Worker    .balign 16
268*795d594fSAndroid Build Coastguard Worker\name:
269*795d594fSAndroid Build Coastguard Worker.endm
270*795d594fSAndroid Build Coastguard Worker
271*795d594fSAndroid Build Coastguard Worker.macro NAME_END name
272*795d594fSAndroid Build Coastguard Worker  SIZE \name
273*795d594fSAndroid Build Coastguard Worker.endm
274*795d594fSAndroid Build Coastguard Worker
275*795d594fSAndroid Build Coastguard Worker// Macro for defining entrypoints into runtime. We don't need to save registers
276*795d594fSAndroid Build Coastguard Worker// (we're not holding references there), but there is no
277*795d594fSAndroid Build Coastguard Worker// kDontSave runtime method. So just use the kSaveRefsOnly runtime method.
278*795d594fSAndroid Build Coastguard Worker.macro NTERP_TRAMPOLINE name, helper
279*795d594fSAndroid Build Coastguard WorkerENTRY \name
280*795d594fSAndroid Build Coastguard Worker  SETUP_SAVE_REFS_ONLY_FRAME
281*795d594fSAndroid Build Coastguard Worker  bl \helper
282*795d594fSAndroid Build Coastguard Worker  RESTORE_SAVE_REFS_ONLY_FRAME
283*795d594fSAndroid Build Coastguard Worker  REFRESH_MARKING_REGISTER
284*795d594fSAndroid Build Coastguard Worker  ldr xIP0, [xSELF, # THREAD_EXCEPTION_OFFSET]   // Get exception field.
285*795d594fSAndroid Build Coastguard Worker  cbnz xIP0, nterp_deliver_pending_exception
286*795d594fSAndroid Build Coastguard Worker  ret
287*795d594fSAndroid Build Coastguard WorkerEND \name
288*795d594fSAndroid Build Coastguard Worker.endm
289*795d594fSAndroid Build Coastguard Worker
290*795d594fSAndroid Build Coastguard Worker.macro CLEAR_STATIC_VOLATILE_MARKER reg
291*795d594fSAndroid Build Coastguard Worker  and \reg, \reg, #-2
292*795d594fSAndroid Build Coastguard Worker.endm
293*795d594fSAndroid Build Coastguard Worker
294*795d594fSAndroid Build Coastguard Worker.macro CLEAR_INSTANCE_VOLATILE_MARKER reg
295*795d594fSAndroid Build Coastguard Worker  neg \reg, \reg
296*795d594fSAndroid Build Coastguard Worker.endm
297*795d594fSAndroid Build Coastguard Worker
298*795d594fSAndroid Build Coastguard Worker.macro EXPORT_PC
299*795d594fSAndroid Build Coastguard Worker    str    xPC, [xREFS, #-16]
300*795d594fSAndroid Build Coastguard Worker.endm
301*795d594fSAndroid Build Coastguard Worker
302*795d594fSAndroid Build Coastguard Worker.macro BRANCH
303*795d594fSAndroid Build Coastguard Worker    add     xPC, xPC, wINST, sxtw #1    // update xPC
304*795d594fSAndroid Build Coastguard Worker    // Update method counter and do a suspend check if the branch is negative or zero.
305*795d594fSAndroid Build Coastguard Worker    cmp wINST, #0
306*795d594fSAndroid Build Coastguard Worker    b.le 2f
307*795d594fSAndroid Build Coastguard Worker1:
308*795d594fSAndroid Build Coastguard Worker    FETCH wINST, 0                      // load wINST
309*795d594fSAndroid Build Coastguard Worker    GET_INST_OPCODE ip                  // extract opcode from wINST
310*795d594fSAndroid Build Coastguard Worker    GOTO_OPCODE ip                      // jump to next instruction
311*795d594fSAndroid Build Coastguard Worker2:
312*795d594fSAndroid Build Coastguard Worker    ldr x0, [sp]
313*795d594fSAndroid Build Coastguard Worker    ldrh w2, [x0, #ART_METHOD_HOTNESS_COUNT_OFFSET]
314*795d594fSAndroid Build Coastguard Worker#if (NTERP_HOTNESS_VALUE != 0)
315*795d594fSAndroid Build Coastguard Worker#error Expected 0 for hotness value
316*795d594fSAndroid Build Coastguard Worker#endif
317*795d594fSAndroid Build Coastguard Worker    // If the counter is at zero, handle this in the runtime.
318*795d594fSAndroid Build Coastguard Worker    cbz w2, NterpHandleHotnessOverflow
319*795d594fSAndroid Build Coastguard Worker    add x2, x2, #-1
320*795d594fSAndroid Build Coastguard Worker    strh w2, [x0, #ART_METHOD_HOTNESS_COUNT_OFFSET]
321*795d594fSAndroid Build Coastguard Worker    DO_SUSPEND_CHECK continue_label=1b
322*795d594fSAndroid Build Coastguard Worker    b 1b
323*795d594fSAndroid Build Coastguard Worker.endm
324*795d594fSAndroid Build Coastguard Worker
325*795d594fSAndroid Build Coastguard Worker// Uses x12, x13, and x14 as temporaries.
326*795d594fSAndroid Build Coastguard Worker.macro FETCH_CODE_ITEM_INFO code_item, registers, outs, ins, load_ins
327*795d594fSAndroid Build Coastguard Worker    // Fetch dex register size.
328*795d594fSAndroid Build Coastguard Worker    ldrh \registers, [\code_item, #CODE_ITEM_REGISTERS_SIZE_OFFSET]
329*795d594fSAndroid Build Coastguard Worker    // Fetch outs size.
330*795d594fSAndroid Build Coastguard Worker    ldrh \outs, [\code_item, #CODE_ITEM_OUTS_SIZE_OFFSET]
331*795d594fSAndroid Build Coastguard Worker    .if \load_ins
332*795d594fSAndroid Build Coastguard Worker    ldrh \ins, [\code_item, #CODE_ITEM_INS_SIZE_OFFSET]
333*795d594fSAndroid Build Coastguard Worker    .endif
334*795d594fSAndroid Build Coastguard Worker    add \code_item, \code_item, #CODE_ITEM_INSNS_OFFSET
335*795d594fSAndroid Build Coastguard Worker.endm
336*795d594fSAndroid Build Coastguard Worker
337*795d594fSAndroid Build Coastguard Worker.macro TEST_IF_MARKING label
338*795d594fSAndroid Build Coastguard Worker    cbnz wMR, \label
339*795d594fSAndroid Build Coastguard Worker.endm
340*795d594fSAndroid Build Coastguard Worker
341*795d594fSAndroid Build Coastguard Worker// Setup the stack to start executing the method. Expects:
342*795d594fSAndroid Build Coastguard Worker// - x0 to contain the ArtMethod
343*795d594fSAndroid Build Coastguard Worker//
344*795d594fSAndroid Build Coastguard Worker// Outputs
345*795d594fSAndroid Build Coastguard Worker// - ip contains the dex registers size
346*795d594fSAndroid Build Coastguard Worker// - x28 contains the old stack pointer.
347*795d594fSAndroid Build Coastguard Worker// - \code_item is replaced with a pointer to the instructions
348*795d594fSAndroid Build Coastguard Worker// - if load_ins is 1, w15 contains the ins
349*795d594fSAndroid Build Coastguard Worker//
350*795d594fSAndroid Build Coastguard Worker// Uses ip, ip2, x12, x13, x14 as temporaries.
351*795d594fSAndroid Build Coastguard Worker.macro SETUP_STACK_FRAME code_item, refs, fp, cfi_refs, load_ins
352*795d594fSAndroid Build Coastguard Worker    FETCH_CODE_ITEM_INFO \code_item, wip, wip2, w15, \load_ins
353*795d594fSAndroid Build Coastguard Worker
354*795d594fSAndroid Build Coastguard Worker    // Compute required frame size: ((2 * ip) + ip2) * 4 + 24
355*795d594fSAndroid Build Coastguard Worker    // 24 is for saving the previous frame, pc, and method being executed.
356*795d594fSAndroid Build Coastguard Worker    add x14, ip, ip
357*795d594fSAndroid Build Coastguard Worker    add x14, x14, ip2
358*795d594fSAndroid Build Coastguard Worker    lsl x14, x14, #2
359*795d594fSAndroid Build Coastguard Worker    add x14, x14, #24
360*795d594fSAndroid Build Coastguard Worker
361*795d594fSAndroid Build Coastguard Worker    // Compute new stack pointer in x14
362*795d594fSAndroid Build Coastguard Worker    sub x14, sp, x14
363*795d594fSAndroid Build Coastguard Worker    // Alignment
364*795d594fSAndroid Build Coastguard Worker    and x14, x14, #-16
365*795d594fSAndroid Build Coastguard Worker
366*795d594fSAndroid Build Coastguard Worker    // Set reference and dex registers, align to pointer size for previous frame and dex pc.
367*795d594fSAndroid Build Coastguard Worker    add \refs, x14, ip2, lsl #2
368*795d594fSAndroid Build Coastguard Worker    add \refs, \refs, 28
369*795d594fSAndroid Build Coastguard Worker    and \refs, \refs, #(-__SIZEOF_POINTER__)
370*795d594fSAndroid Build Coastguard Worker    add \fp, \refs, ip, lsl #2
371*795d594fSAndroid Build Coastguard Worker
372*795d594fSAndroid Build Coastguard Worker    // Now setup the stack pointer.
373*795d594fSAndroid Build Coastguard Worker    mov x28, sp
374*795d594fSAndroid Build Coastguard Worker    .cfi_def_cfa_register x28
375*795d594fSAndroid Build Coastguard Worker    mov sp, x14
376*795d594fSAndroid Build Coastguard Worker    str x28, [\refs, #-8]
377*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA_BREG_PLUS_UCONST \cfi_refs, -8, CALLEE_SAVES_SIZE
378*795d594fSAndroid Build Coastguard Worker
379*795d594fSAndroid Build Coastguard Worker    // Put nulls in reference frame.
380*795d594fSAndroid Build Coastguard Worker    cbz ip, 2f
381*795d594fSAndroid Build Coastguard Worker    mov ip2, \refs
382*795d594fSAndroid Build Coastguard Worker1:
383*795d594fSAndroid Build Coastguard Worker    str xzr, [ip2], #8  // May clear vreg[0].
384*795d594fSAndroid Build Coastguard Worker    cmp ip2, \fp
385*795d594fSAndroid Build Coastguard Worker    b.lo 1b
386*795d594fSAndroid Build Coastguard Worker2:
387*795d594fSAndroid Build Coastguard Worker    // Save the ArtMethod.
388*795d594fSAndroid Build Coastguard Worker    str x0, [sp]
389*795d594fSAndroid Build Coastguard Worker.endm
390*795d594fSAndroid Build Coastguard Worker
391*795d594fSAndroid Build Coastguard Worker// Increase method hotness and do suspend check before starting executing the method.
392*795d594fSAndroid Build Coastguard Worker.macro START_EXECUTING_INSTRUCTIONS
393*795d594fSAndroid Build Coastguard Worker    ldr x0, [sp]
394*795d594fSAndroid Build Coastguard Worker    ldrh w2, [x0, #ART_METHOD_HOTNESS_COUNT_OFFSET]
395*795d594fSAndroid Build Coastguard Worker#if (NTERP_HOTNESS_VALUE != 0)
396*795d594fSAndroid Build Coastguard Worker#error Expected 0 for hotness value
397*795d594fSAndroid Build Coastguard Worker#endif
398*795d594fSAndroid Build Coastguard Worker    // If the counter is at zero, handle this in the runtime.
399*795d594fSAndroid Build Coastguard Worker    cbz w2, 3f
400*795d594fSAndroid Build Coastguard Worker    add x2, x2, #-1
401*795d594fSAndroid Build Coastguard Worker    strh w2, [x0, #ART_METHOD_HOTNESS_COUNT_OFFSET]
402*795d594fSAndroid Build Coastguard Worker1:
403*795d594fSAndroid Build Coastguard Worker    DO_SUSPEND_CHECK continue_label=2f
404*795d594fSAndroid Build Coastguard Worker2:
405*795d594fSAndroid Build Coastguard Worker    FETCH_INST
406*795d594fSAndroid Build Coastguard Worker    GET_INST_OPCODE ip
407*795d594fSAndroid Build Coastguard Worker    GOTO_OPCODE ip
408*795d594fSAndroid Build Coastguard Worker3:
409*795d594fSAndroid Build Coastguard Worker    CHECK_AND_UPDATE_SHARED_MEMORY_METHOD if_hot=4f, if_not_hot=1b
410*795d594fSAndroid Build Coastguard Worker4:
411*795d594fSAndroid Build Coastguard Worker    mov x1, xzr
412*795d594fSAndroid Build Coastguard Worker    mov x2, xFP
413*795d594fSAndroid Build Coastguard Worker    bl nterp_hot_method
414*795d594fSAndroid Build Coastguard Worker    b 2b
415*795d594fSAndroid Build Coastguard Worker.endm
416*795d594fSAndroid Build Coastguard Worker
417*795d594fSAndroid Build Coastguard Worker.macro SPILL_ALL_CALLEE_SAVES
418*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME CALLEE_SAVES_SIZE
419*795d594fSAndroid Build Coastguard Worker    // Note: we technically don't need to save x19 and x20,
420*795d594fSAndroid Build Coastguard Worker    // but the runtime will expect those values to be there when unwinding
421*795d594fSAndroid Build Coastguard Worker    // (see Arm64Context::DoLongJump checking for the thread register).
422*795d594fSAndroid Build Coastguard Worker    SAVE_ALL_CALLEE_SAVES 0
423*795d594fSAndroid Build Coastguard Worker.endm
424*795d594fSAndroid Build Coastguard Worker
425*795d594fSAndroid Build Coastguard Worker.macro RESTORE_ALL_CALLEE_SAVES
426*795d594fSAndroid Build Coastguard Worker    // FP callee-saves
427*795d594fSAndroid Build Coastguard Worker    ldp d8, d9, [sp, #0]
428*795d594fSAndroid Build Coastguard Worker    ldp d10, d11, [sp, #16]
429*795d594fSAndroid Build Coastguard Worker    ldp d12, d13, [sp, #32]
430*795d594fSAndroid Build Coastguard Worker    ldp d14, d15, [sp, #48]
431*795d594fSAndroid Build Coastguard Worker
432*795d594fSAndroid Build Coastguard Worker    // GP callee-saves.
433*795d594fSAndroid Build Coastguard Worker    // No need to restore x19 (it's always the thread), and
434*795d594fSAndroid Build Coastguard Worker    // don't restore x20 (the marking register) as it may have been updated,
435*795d594fSAndroid Build Coastguard Worker    // don't restore x21 (the suspend check register) as it may have been updated.
436*795d594fSAndroid Build Coastguard Worker    RESTORE_REG      x22, 88
437*795d594fSAndroid Build Coastguard Worker    RESTORE_TWO_REGS x23, x24, 96
438*795d594fSAndroid Build Coastguard Worker    RESTORE_TWO_REGS x25, x26, 112
439*795d594fSAndroid Build Coastguard Worker    RESTORE_TWO_REGS x27, x28, 128
440*795d594fSAndroid Build Coastguard Worker    RESTORE_TWO_REGS x29, lr, 144
441*795d594fSAndroid Build Coastguard Worker
442*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME CALLEE_SAVES_SIZE
443*795d594fSAndroid Build Coastguard Worker.endm
444*795d594fSAndroid Build Coastguard Worker
445*795d594fSAndroid Build Coastguard Worker.macro SPILL_ALL_ARGUMENTS
446*795d594fSAndroid Build Coastguard Worker    stp x0, x1, [sp, #-128]!
447*795d594fSAndroid Build Coastguard Worker    stp x2, x3, [sp, #16]
448*795d594fSAndroid Build Coastguard Worker    stp x4, x5, [sp, #32]
449*795d594fSAndroid Build Coastguard Worker    stp x6, x7, [sp, #48]
450*795d594fSAndroid Build Coastguard Worker    stp d0, d1, [sp, #64]
451*795d594fSAndroid Build Coastguard Worker    stp d2, d3, [sp, #80]
452*795d594fSAndroid Build Coastguard Worker    stp d4, d5, [sp, #96]
453*795d594fSAndroid Build Coastguard Worker    stp d6, d7, [sp, #112]
454*795d594fSAndroid Build Coastguard Worker.endm
455*795d594fSAndroid Build Coastguard Worker
456*795d594fSAndroid Build Coastguard Worker.macro RESTORE_ALL_ARGUMENTS
457*795d594fSAndroid Build Coastguard Worker    ldp x2, x3, [sp, #16]
458*795d594fSAndroid Build Coastguard Worker    ldp x4, x5, [sp, #32]
459*795d594fSAndroid Build Coastguard Worker    ldp x6, x7, [sp, #48]
460*795d594fSAndroid Build Coastguard Worker    ldp d0, d1, [sp, #64]
461*795d594fSAndroid Build Coastguard Worker    ldp d2, d3, [sp, #80]
462*795d594fSAndroid Build Coastguard Worker    ldp d4, d5, [sp, #96]
463*795d594fSAndroid Build Coastguard Worker    ldp d6, d7, [sp, #112]
464*795d594fSAndroid Build Coastguard Worker    ldp x0, x1, [sp], #128
465*795d594fSAndroid Build Coastguard Worker.endm
466*795d594fSAndroid Build Coastguard Worker
467*795d594fSAndroid Build Coastguard Worker// Helper to setup the stack after doing a nterp to nterp call. This will setup:
468*795d594fSAndroid Build Coastguard Worker// - xNEW_FP: the new pointer to dex registers
469*795d594fSAndroid Build Coastguard Worker// - xNEW_REFS: the new pointer to references
470*795d594fSAndroid Build Coastguard Worker// - xPC: the new PC pointer to execute
471*795d594fSAndroid Build Coastguard Worker// - x2: value in instruction to decode the number of arguments.
472*795d594fSAndroid Build Coastguard Worker// - x3: first dex register
473*795d594fSAndroid Build Coastguard Worker// - x4: top of dex register array
474*795d594fSAndroid Build Coastguard Worker//
475*795d594fSAndroid Build Coastguard Worker// The method expects:
476*795d594fSAndroid Build Coastguard Worker// - x0 to contain the ArtMethod
477*795d594fSAndroid Build Coastguard Worker// - x8 to contain the code item
478*795d594fSAndroid Build Coastguard Worker.macro SETUP_STACK_FOR_INVOKE
479*795d594fSAndroid Build Coastguard Worker   // We do the same stack overflow check as the compiler. See CanMethodUseNterp
480*795d594fSAndroid Build Coastguard Worker   // in how we limit the maximum nterp frame size.
481*795d594fSAndroid Build Coastguard Worker   sub x16, sp, #STACK_OVERFLOW_RESERVED_BYTES
482*795d594fSAndroid Build Coastguard Worker   ldr wzr, [x16]
483*795d594fSAndroid Build Coastguard Worker
484*795d594fSAndroid Build Coastguard Worker   // Spill all callee saves to have a consistent stack frame whether we
485*795d594fSAndroid Build Coastguard Worker   // are called by compiled code or nterp.
486*795d594fSAndroid Build Coastguard Worker   SPILL_ALL_CALLEE_SAVES
487*795d594fSAndroid Build Coastguard Worker
488*795d594fSAndroid Build Coastguard Worker   // Setup the frame.
489*795d594fSAndroid Build Coastguard Worker   SETUP_STACK_FRAME x8, xNEW_REFS, xNEW_FP, CFI_NEW_REFS, load_ins=0
490*795d594fSAndroid Build Coastguard Worker   // Make x4 point to the top of the dex register array.
491*795d594fSAndroid Build Coastguard Worker   add x4, xNEW_FP, ip, uxtx #2
492*795d594fSAndroid Build Coastguard Worker
493*795d594fSAndroid Build Coastguard Worker   // Fetch instruction information before replacing xPC.
494*795d594fSAndroid Build Coastguard Worker   // TODO: move this down to the method that uses it, fetching it directly from wINST.
495*795d594fSAndroid Build Coastguard Worker   FETCH_B w2, 0, 1
496*795d594fSAndroid Build Coastguard Worker   // TODO: we could avoid this as instance invokes already fetch it.
497*795d594fSAndroid Build Coastguard Worker   FETCH w3, 2
498*795d594fSAndroid Build Coastguard Worker
499*795d594fSAndroid Build Coastguard Worker   // Set the dex pc pointer.
500*795d594fSAndroid Build Coastguard Worker   mov xPC, x8
501*795d594fSAndroid Build Coastguard Worker   CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
502*795d594fSAndroid Build Coastguard Worker.endm
503*795d594fSAndroid Build Coastguard Worker
504*795d594fSAndroid Build Coastguard Worker// Setup arguments based on a non-range nterp to nterp call, and start executing
505*795d594fSAndroid Build Coastguard Worker// the method. We expect:
506*795d594fSAndroid Build Coastguard Worker// - xNEW_FP: the new pointer to dex registers
507*795d594fSAndroid Build Coastguard Worker// - xNEW_REFS: the new pointer to references
508*795d594fSAndroid Build Coastguard Worker// - xPC: the new PC pointer to execute
509*795d594fSAndroid Build Coastguard Worker// - x2: number of arguments (bits 4-7), 5th argument if any (bits 0-3)
510*795d594fSAndroid Build Coastguard Worker// - x3: first dex register
511*795d594fSAndroid Build Coastguard Worker// - x4: top of dex register array
512*795d594fSAndroid Build Coastguard Worker// - x1: receiver if non-static.
513*795d594fSAndroid Build Coastguard Worker.macro SETUP_NON_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=0
514*795d594fSAndroid Build Coastguard Worker   // /* op vA, vB, {vC...vG} */
515*795d594fSAndroid Build Coastguard Worker   asr ip2, x2, #4
516*795d594fSAndroid Build Coastguard Worker   cbz ip2, 6f
517*795d594fSAndroid Build Coastguard Worker   mov ip, #-4
518*795d594fSAndroid Build Coastguard Worker   cmp ip2, #2
519*795d594fSAndroid Build Coastguard Worker   b.lt 1f
520*795d594fSAndroid Build Coastguard Worker   b.eq 2f
521*795d594fSAndroid Build Coastguard Worker   cmp ip2, #4
522*795d594fSAndroid Build Coastguard Worker   b.lt 3f
523*795d594fSAndroid Build Coastguard Worker   b.eq 4f
524*795d594fSAndroid Build Coastguard Worker
525*795d594fSAndroid Build Coastguard Worker  // We use a decrementing ip to store references relative
526*795d594fSAndroid Build Coastguard Worker  // to xNEW_FP and dex registers relative to x4
527*795d594fSAndroid Build Coastguard Worker  //
528*795d594fSAndroid Build Coastguard Worker  // TODO: We could set up ip as the number of registers (this can be an additional output from
529*795d594fSAndroid Build Coastguard Worker  // SETUP_STACK_FOR_INVOKE) and then just decrement it by one before copying each arg.
530*795d594fSAndroid Build Coastguard Worker  // Maybe even introduce macros NEW_VREG_ADDRESS/NEW_VREG_REF_ADDRESS.
531*795d594fSAndroid Build Coastguard Worker5:
532*795d594fSAndroid Build Coastguard Worker   and         x2, x2, #15
533*795d594fSAndroid Build Coastguard Worker   GET_VREG_OBJECT w5, w2
534*795d594fSAndroid Build Coastguard Worker   str         w5, [xNEW_FP, ip]
535*795d594fSAndroid Build Coastguard Worker   GET_VREG    w5, w2
536*795d594fSAndroid Build Coastguard Worker   str         w5, [x4, ip]
537*795d594fSAndroid Build Coastguard Worker   sub         ip, ip, #4
538*795d594fSAndroid Build Coastguard Worker4:
539*795d594fSAndroid Build Coastguard Worker   asr         x2, x3, #12
540*795d594fSAndroid Build Coastguard Worker   GET_VREG_OBJECT w5, w2
541*795d594fSAndroid Build Coastguard Worker   str         w5, [xNEW_FP, ip]
542*795d594fSAndroid Build Coastguard Worker   GET_VREG    w5, w2
543*795d594fSAndroid Build Coastguard Worker   str         w5, [x4, ip]
544*795d594fSAndroid Build Coastguard Worker   sub         ip, ip, #4
545*795d594fSAndroid Build Coastguard Worker3:
546*795d594fSAndroid Build Coastguard Worker   ubfx        x2, x3, #8, #4
547*795d594fSAndroid Build Coastguard Worker   GET_VREG_OBJECT w5, w2
548*795d594fSAndroid Build Coastguard Worker   str         w5, [xNEW_FP, ip]
549*795d594fSAndroid Build Coastguard Worker   GET_VREG    w5, w2
550*795d594fSAndroid Build Coastguard Worker   str         w5, [x4, ip]
551*795d594fSAndroid Build Coastguard Worker   sub         ip, ip, #4
552*795d594fSAndroid Build Coastguard Worker2:
553*795d594fSAndroid Build Coastguard Worker   ubfx        x2, x3, #4, #4
554*795d594fSAndroid Build Coastguard Worker   GET_VREG_OBJECT w5, w2
555*795d594fSAndroid Build Coastguard Worker   str         w5, [xNEW_FP, ip]
556*795d594fSAndroid Build Coastguard Worker   GET_VREG    w5, w2
557*795d594fSAndroid Build Coastguard Worker   str         w5, [x4, ip]
558*795d594fSAndroid Build Coastguard Worker   .if !\is_string_init
559*795d594fSAndroid Build Coastguard Worker   sub         ip, ip, #4
560*795d594fSAndroid Build Coastguard Worker   .endif
561*795d594fSAndroid Build Coastguard Worker1:
562*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
563*795d594fSAndroid Build Coastguard Worker   // Ignore the first argument
564*795d594fSAndroid Build Coastguard Worker   .elseif \is_static
565*795d594fSAndroid Build Coastguard Worker   and         x2, x3, #0xf
566*795d594fSAndroid Build Coastguard Worker   GET_VREG_OBJECT w5, w2
567*795d594fSAndroid Build Coastguard Worker   str         w5, [xNEW_FP, ip]
568*795d594fSAndroid Build Coastguard Worker   GET_VREG    w5, w2
569*795d594fSAndroid Build Coastguard Worker   str         w5, [x4, ip]
570*795d594fSAndroid Build Coastguard Worker   .else
571*795d594fSAndroid Build Coastguard Worker   str         w1, [xNEW_FP, ip]
572*795d594fSAndroid Build Coastguard Worker   str         w1, [x4, ip]
573*795d594fSAndroid Build Coastguard Worker   .endif
574*795d594fSAndroid Build Coastguard Worker
575*795d594fSAndroid Build Coastguard Worker6:
576*795d594fSAndroid Build Coastguard Worker   // Start executing the method.
577*795d594fSAndroid Build Coastguard Worker   mov xFP, xNEW_FP
578*795d594fSAndroid Build Coastguard Worker   mov xREFS, xNEW_REFS
579*795d594fSAndroid Build Coastguard Worker   CFI_DEF_CFA_BREG_PLUS_UCONST CFI_REFS, -8, CALLEE_SAVES_SIZE
580*795d594fSAndroid Build Coastguard Worker   START_EXECUTING_INSTRUCTIONS
581*795d594fSAndroid Build Coastguard Worker.endm
582*795d594fSAndroid Build Coastguard Worker
583*795d594fSAndroid Build Coastguard Worker// Setup arguments based on a range nterp to nterp call, and start executing
584*795d594fSAndroid Build Coastguard Worker// the method.
585*795d594fSAndroid Build Coastguard Worker// - xNEW_FP: the new pointer to dex registers
586*795d594fSAndroid Build Coastguard Worker// - xNEW_REFS: the new pointer to references
587*795d594fSAndroid Build Coastguard Worker// - xPC: the new PC pointer to execute
588*795d594fSAndroid Build Coastguard Worker// - x2: number of arguments
589*795d594fSAndroid Build Coastguard Worker// - x3: first dex register
590*795d594fSAndroid Build Coastguard Worker// - x4: top of dex register array
591*795d594fSAndroid Build Coastguard Worker// - x1: receiver if non-static.
592*795d594fSAndroid Build Coastguard Worker//
593*795d594fSAndroid Build Coastguard Worker// Uses ip, ip2, x5, x6 as temporaries.
594*795d594fSAndroid Build Coastguard Worker.macro SETUP_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=0
595*795d594fSAndroid Build Coastguard Worker   mov ip, #-4
596*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
597*795d594fSAndroid Build Coastguard Worker   // Ignore the first argument
598*795d594fSAndroid Build Coastguard Worker   sub x2, x2, #1
599*795d594fSAndroid Build Coastguard Worker   add x3, x3, #1
600*795d594fSAndroid Build Coastguard Worker   .elseif !\is_static
601*795d594fSAndroid Build Coastguard Worker   sub x2, x2, #1
602*795d594fSAndroid Build Coastguard Worker   add x3, x3, #1
603*795d594fSAndroid Build Coastguard Worker   .endif
604*795d594fSAndroid Build Coastguard Worker
605*795d594fSAndroid Build Coastguard Worker   cbz x2, 2f
606*795d594fSAndroid Build Coastguard Worker   add ip2, xREFS, x3, lsl #2  // pointer to first argument in reference array
607*795d594fSAndroid Build Coastguard Worker   add ip2, ip2, x2, lsl #2    // pointer to last argument in reference array
608*795d594fSAndroid Build Coastguard Worker   add x5, xFP, x3, lsl #2     // pointer to first argument in register array
609*795d594fSAndroid Build Coastguard Worker   add x6, x5, x2, lsl #2      // pointer to last argument in register array
610*795d594fSAndroid Build Coastguard Worker1:
611*795d594fSAndroid Build Coastguard Worker   ldr  w7, [ip2, #-4]!
612*795d594fSAndroid Build Coastguard Worker   str  w7, [xNEW_FP, ip]
613*795d594fSAndroid Build Coastguard Worker   sub  x2, x2, 1
614*795d594fSAndroid Build Coastguard Worker   ldr  w7, [x6, #-4]!
615*795d594fSAndroid Build Coastguard Worker   str  w7, [x4, ip]
616*795d594fSAndroid Build Coastguard Worker   sub ip, ip, 4
617*795d594fSAndroid Build Coastguard Worker   cbnz x2, 1b
618*795d594fSAndroid Build Coastguard Worker2:
619*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
620*795d594fSAndroid Build Coastguard Worker   // Ignore first argument
621*795d594fSAndroid Build Coastguard Worker   .elseif !\is_static
622*795d594fSAndroid Build Coastguard Worker   str w1, [xNEW_FP, ip]
623*795d594fSAndroid Build Coastguard Worker   str w1, [x4, ip]
624*795d594fSAndroid Build Coastguard Worker   .endif
625*795d594fSAndroid Build Coastguard Worker   mov xFP, xNEW_FP
626*795d594fSAndroid Build Coastguard Worker   mov xREFS, xNEW_REFS
627*795d594fSAndroid Build Coastguard Worker   CFI_DEF_CFA_BREG_PLUS_UCONST CFI_REFS, -8, CALLEE_SAVES_SIZE
628*795d594fSAndroid Build Coastguard Worker   START_EXECUTING_INSTRUCTIONS
629*795d594fSAndroid Build Coastguard Worker.endm
630*795d594fSAndroid Build Coastguard Worker
631*795d594fSAndroid Build Coastguard Worker.macro GET_SHORTY dest, is_interface, is_polymorphic, is_custom
632*795d594fSAndroid Build Coastguard Worker   stp x0, x1, [sp, #-16]!
633*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
634*795d594fSAndroid Build Coastguard Worker   ldr x0, [sp, #16]
635*795d594fSAndroid Build Coastguard Worker   mov x1, xPC
636*795d594fSAndroid Build Coastguard Worker   bl NterpGetShortyFromInvokePolymorphic
637*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
638*795d594fSAndroid Build Coastguard Worker   ldr x0, [sp, #16]
639*795d594fSAndroid Build Coastguard Worker   mov x1, xPC
640*795d594fSAndroid Build Coastguard Worker   bl NterpGetShortyFromInvokeCustom
641*795d594fSAndroid Build Coastguard Worker   .elseif \is_interface
642*795d594fSAndroid Build Coastguard Worker   ldr x0, [sp, #16]
643*795d594fSAndroid Build Coastguard Worker   FETCH w1, 1
644*795d594fSAndroid Build Coastguard Worker   bl NterpGetShortyFromMethodId
645*795d594fSAndroid Build Coastguard Worker   .else
646*795d594fSAndroid Build Coastguard Worker   bl NterpGetShorty
647*795d594fSAndroid Build Coastguard Worker   .endif
648*795d594fSAndroid Build Coastguard Worker   mov \dest, x0
649*795d594fSAndroid Build Coastguard Worker   ldp x0, x1, [sp], #16
650*795d594fSAndroid Build Coastguard Worker.endm
651*795d594fSAndroid Build Coastguard Worker
652*795d594fSAndroid Build Coastguard Worker.macro GET_SHORTY_SLOW_PATH dest, is_interface
653*795d594fSAndroid Build Coastguard Worker   // Save all registers that can hold arguments in the fast path.
654*795d594fSAndroid Build Coastguard Worker   stp x0, x1, [sp, #-32]!
655*795d594fSAndroid Build Coastguard Worker   str w2, [sp, #16]
656*795d594fSAndroid Build Coastguard Worker   str s0, [sp, #20]
657*795d594fSAndroid Build Coastguard Worker   .if \is_interface
658*795d594fSAndroid Build Coastguard Worker   ldr x0, [sp, #32]
659*795d594fSAndroid Build Coastguard Worker   FETCH w1, 1
660*795d594fSAndroid Build Coastguard Worker   bl NterpGetShortyFromMethodId
661*795d594fSAndroid Build Coastguard Worker   .else
662*795d594fSAndroid Build Coastguard Worker   bl NterpGetShorty
663*795d594fSAndroid Build Coastguard Worker   .endif
664*795d594fSAndroid Build Coastguard Worker   mov \dest, x0
665*795d594fSAndroid Build Coastguard Worker   ldr w2, [sp, #16]
666*795d594fSAndroid Build Coastguard Worker   ldr s0, [sp, #20]
667*795d594fSAndroid Build Coastguard Worker   ldp x0, x1, [sp], #32
668*795d594fSAndroid Build Coastguard Worker.endm
669*795d594fSAndroid Build Coastguard Worker
670*795d594fSAndroid Build Coastguard Worker// Input:  x0 contains the ArtMethod
671*795d594fSAndroid Build Coastguard Worker// Output: x8 contains the code item
672*795d594fSAndroid Build Coastguard Worker.macro GET_CODE_ITEM
673*795d594fSAndroid Build Coastguard Worker   ldr x8, [x0, #ART_METHOD_DATA_OFFSET_64]
674*795d594fSAndroid Build Coastguard Worker.endm
675*795d594fSAndroid Build Coastguard Worker
676*795d594fSAndroid Build Coastguard Worker.macro DO_ENTRY_POINT_CHECK call_compiled_code
677*795d594fSAndroid Build Coastguard Worker   // On entry, the method is x0, the instance is x1
678*795d594fSAndroid Build Coastguard Worker   adr x2, ExecuteNterpImpl
679*795d594fSAndroid Build Coastguard Worker   ldr x3, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64]
680*795d594fSAndroid Build Coastguard Worker   cmp x2, x3
681*795d594fSAndroid Build Coastguard Worker   b.ne  \call_compiled_code
682*795d594fSAndroid Build Coastguard Worker.endm
683*795d594fSAndroid Build Coastguard Worker
684*795d594fSAndroid Build Coastguard Worker.macro UPDATE_REGISTERS_FOR_STRING_INIT old_value, new_value
685*795d594fSAndroid Build Coastguard Worker   mov wip, wzr
686*795d594fSAndroid Build Coastguard Worker1:
687*795d594fSAndroid Build Coastguard Worker   GET_VREG_OBJECT wip2, wip
688*795d594fSAndroid Build Coastguard Worker   cmp wip2, \old_value
689*795d594fSAndroid Build Coastguard Worker   b.ne 2f
690*795d594fSAndroid Build Coastguard Worker   SET_VREG_OBJECT \new_value, wip
691*795d594fSAndroid Build Coastguard Worker2:
692*795d594fSAndroid Build Coastguard Worker   add wip, wip, #1
693*795d594fSAndroid Build Coastguard Worker   add ip2, xREFS, wip, uxtw #2
694*795d594fSAndroid Build Coastguard Worker   cmp ip2, xFP
695*795d594fSAndroid Build Coastguard Worker   b.ne 1b
696*795d594fSAndroid Build Coastguard Worker.endm
697*795d594fSAndroid Build Coastguard Worker
698*795d594fSAndroid Build Coastguard Worker// Puts the next floating point argument into the expected register,
699*795d594fSAndroid Build Coastguard Worker// fetching values based on a non-range invoke.
700*795d594fSAndroid Build Coastguard Worker// Uses ip and ip2.
701*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_SHORTY_LOADING_FPS dreg, sreg, inst, shorty, arg_index, finished
702*795d594fSAndroid Build Coastguard Worker1: // LOOP
703*795d594fSAndroid Build Coastguard Worker    ldrb wip, [\shorty], #1         // Load next character in shorty, and increment.
704*795d594fSAndroid Build Coastguard Worker    cbz wip, \finished              // if (wip == '\0') goto finished
705*795d594fSAndroid Build Coastguard Worker    cmp wip, #68                    // if (wip == 'D') goto FOUND_DOUBLE
706*795d594fSAndroid Build Coastguard Worker    b.eq 2f
707*795d594fSAndroid Build Coastguard Worker    cmp wip, #70                    // if (wip == 'F') goto FOUND_FLOAT
708*795d594fSAndroid Build Coastguard Worker    b.eq 3f
709*795d594fSAndroid Build Coastguard Worker    lsr \inst, \inst, #4
710*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
711*795d594fSAndroid Build Coastguard Worker    //  Handle extra argument in arg array taken by a long.
712*795d594fSAndroid Build Coastguard Worker    cmp wip, #74                   // if (wip != 'J') goto LOOP
713*795d594fSAndroid Build Coastguard Worker    b.ne 1b
714*795d594fSAndroid Build Coastguard Worker    lsr \inst, \inst, #4
715*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
716*795d594fSAndroid Build Coastguard Worker    b 1b                        // goto LOOP
717*795d594fSAndroid Build Coastguard Worker2:  // FOUND_DOUBLE
718*795d594fSAndroid Build Coastguard Worker    and ip, \inst, #0xf
719*795d594fSAndroid Build Coastguard Worker    GET_VREG wip, wip
720*795d594fSAndroid Build Coastguard Worker    lsr \inst, \inst, #4
721*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
722*795d594fSAndroid Build Coastguard Worker    cmp \arg_index, #4
723*795d594fSAndroid Build Coastguard Worker    b.eq 5f
724*795d594fSAndroid Build Coastguard Worker    and ip2, \inst, #0xf
725*795d594fSAndroid Build Coastguard Worker    lsr \inst, \inst, #4
726*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
727*795d594fSAndroid Build Coastguard Worker    b 6f
728*795d594fSAndroid Build Coastguard Worker5:
729*795d594fSAndroid Build Coastguard Worker    // TODO: Extract from wINST here and below? (Requires using a different register
730*795d594fSAndroid Build Coastguard Worker    // in the COMMON_INVOKE_NON_RANGE.)
731*795d594fSAndroid Build Coastguard Worker    FETCH_B wip2, 0, 1
732*795d594fSAndroid Build Coastguard Worker    and wip2, wip2, #0xf
733*795d594fSAndroid Build Coastguard Worker6:
734*795d594fSAndroid Build Coastguard Worker    GET_VREG wip2, wip2
735*795d594fSAndroid Build Coastguard Worker    add ip, ip, ip2, lsl #32
736*795d594fSAndroid Build Coastguard Worker    fmov \dreg, ip
737*795d594fSAndroid Build Coastguard Worker    b 4f
738*795d594fSAndroid Build Coastguard Worker3:  // FOUND_FLOAT
739*795d594fSAndroid Build Coastguard Worker    cmp \arg_index, #4
740*795d594fSAndroid Build Coastguard Worker    b.eq 7f
741*795d594fSAndroid Build Coastguard Worker    and ip, \inst, #0xf
742*795d594fSAndroid Build Coastguard Worker    lsr \inst, \inst, #4
743*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
744*795d594fSAndroid Build Coastguard Worker    b 8f
745*795d594fSAndroid Build Coastguard Worker7:
746*795d594fSAndroid Build Coastguard Worker    FETCH_B wip, 0, 1
747*795d594fSAndroid Build Coastguard Worker    and wip, wip, #0xf
748*795d594fSAndroid Build Coastguard Worker8:
749*795d594fSAndroid Build Coastguard Worker    GET_VREG \sreg, wip
750*795d594fSAndroid Build Coastguard Worker4:
751*795d594fSAndroid Build Coastguard Worker.endm
752*795d594fSAndroid Build Coastguard Worker
753*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object argument in the expected register,
754*795d594fSAndroid Build Coastguard Worker// fetching values based on a non-range invoke.
755*795d594fSAndroid Build Coastguard Worker// Uses ip and ip2.
756*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_SHORTY_LOADING_GPRS gpr_reg64, gpr_reg32, inst, shorty, arg_index, finished
757*795d594fSAndroid Build Coastguard Worker1: // LOOP
758*795d594fSAndroid Build Coastguard Worker    ldrb wip, [\shorty], #1         // Load next character in shorty, and increment.
759*795d594fSAndroid Build Coastguard Worker    cbz wip, \finished              // if (wip == '\0') goto finished
760*795d594fSAndroid Build Coastguard Worker    cmp wip, #74                    // if (wip == 'J') goto FOUND_LONG
761*795d594fSAndroid Build Coastguard Worker    b.eq 2f
762*795d594fSAndroid Build Coastguard Worker    cmp wip, #70                    // if (wip == 'F') goto SKIP_FLOAT
763*795d594fSAndroid Build Coastguard Worker    b.eq 3f
764*795d594fSAndroid Build Coastguard Worker    cmp wip, #68                    // if (wip == 'D') goto SKIP_DOUBLE
765*795d594fSAndroid Build Coastguard Worker    b.eq 4f
766*795d594fSAndroid Build Coastguard Worker    cmp \arg_index, #4
767*795d594fSAndroid Build Coastguard Worker    b.eq 7f
768*795d594fSAndroid Build Coastguard Worker    and ip, \inst, #0xf
769*795d594fSAndroid Build Coastguard Worker    lsr \inst, \inst, #4
770*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
771*795d594fSAndroid Build Coastguard Worker    b 8f
772*795d594fSAndroid Build Coastguard Worker7:
773*795d594fSAndroid Build Coastguard Worker    FETCH_B wip, 0, 1
774*795d594fSAndroid Build Coastguard Worker    and wip, wip, #0xf
775*795d594fSAndroid Build Coastguard Worker8:
776*795d594fSAndroid Build Coastguard Worker    GET_VREG \gpr_reg32, wip
777*795d594fSAndroid Build Coastguard Worker    b 5f
778*795d594fSAndroid Build Coastguard Worker2:  // FOUND_LONG
779*795d594fSAndroid Build Coastguard Worker    and ip, \inst, #0xf
780*795d594fSAndroid Build Coastguard Worker    GET_VREG wip, wip
781*795d594fSAndroid Build Coastguard Worker    lsr \inst, \inst, #4
782*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
783*795d594fSAndroid Build Coastguard Worker    cmp \arg_index, #4
784*795d594fSAndroid Build Coastguard Worker    b.eq 9f
785*795d594fSAndroid Build Coastguard Worker    and ip2, \inst, #0xf
786*795d594fSAndroid Build Coastguard Worker    lsr \inst, \inst, #4
787*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
788*795d594fSAndroid Build Coastguard Worker    b 10f
789*795d594fSAndroid Build Coastguard Worker9:
790*795d594fSAndroid Build Coastguard Worker    FETCH_B wip2, 0, 1
791*795d594fSAndroid Build Coastguard Worker    and wip2, wip2, #0xf
792*795d594fSAndroid Build Coastguard Worker10:
793*795d594fSAndroid Build Coastguard Worker    GET_VREG wip2, wip2
794*795d594fSAndroid Build Coastguard Worker    add \gpr_reg64, ip, ip2, lsl #32
795*795d594fSAndroid Build Coastguard Worker    b 5f
796*795d594fSAndroid Build Coastguard Worker3:  // SKIP_FLOAT
797*795d594fSAndroid Build Coastguard Worker    lsr \inst, \inst, #4
798*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
799*795d594fSAndroid Build Coastguard Worker    b 1b
800*795d594fSAndroid Build Coastguard Worker4:  // SKIP_DOUBLE
801*795d594fSAndroid Build Coastguard Worker    lsr \inst, \inst, #4
802*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
803*795d594fSAndroid Build Coastguard Worker    cmp \arg_index, #4
804*795d594fSAndroid Build Coastguard Worker    b.eq 1b
805*795d594fSAndroid Build Coastguard Worker    lsr \inst, \inst, #4
806*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
807*795d594fSAndroid Build Coastguard Worker    b 1b
808*795d594fSAndroid Build Coastguard Worker5:
809*795d594fSAndroid Build Coastguard Worker.endm
810*795d594fSAndroid Build Coastguard Worker
811*795d594fSAndroid Build Coastguard Worker.macro SETUP_RETURN_VALUE shorty
812*795d594fSAndroid Build Coastguard Worker   ldrb wip, [\shorty]
813*795d594fSAndroid Build Coastguard Worker   cmp ip, #68       // Test if result type char == 'D'.
814*795d594fSAndroid Build Coastguard Worker   b.eq 1f
815*795d594fSAndroid Build Coastguard Worker   cmp ip, #70       // Test if result type char == 'F'.
816*795d594fSAndroid Build Coastguard Worker   b.ne 2f
817*795d594fSAndroid Build Coastguard Worker   fmov w0, s0
818*795d594fSAndroid Build Coastguard Worker   b 2f
819*795d594fSAndroid Build Coastguard Worker1:
820*795d594fSAndroid Build Coastguard Worker   fmov x0, d0
821*795d594fSAndroid Build Coastguard Worker2:
822*795d594fSAndroid Build Coastguard Worker.endm
823*795d594fSAndroid Build Coastguard Worker
824*795d594fSAndroid Build Coastguard Worker.macro COMMON_INVOKE_NON_RANGE is_static=0, is_interface=0, suffix="", is_string_init=0, is_polymorphic=0, is_custom=0
825*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
826*795d594fSAndroid Build Coastguard Worker   // We always go to compiled code for polymorphic calls.
827*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
828*795d594fSAndroid Build Coastguard Worker   // We always go to compiled code for custom calls.
829*795d594fSAndroid Build Coastguard Worker   .else
830*795d594fSAndroid Build Coastguard Worker     DO_ENTRY_POINT_CHECK .Lcall_compiled_code_\suffix
831*795d594fSAndroid Build Coastguard Worker     GET_CODE_ITEM
832*795d594fSAndroid Build Coastguard Worker     .if \is_string_init
833*795d594fSAndroid Build Coastguard Worker     bl nterp_to_nterp_string_init_non_range
834*795d594fSAndroid Build Coastguard Worker     .elseif \is_static
835*795d594fSAndroid Build Coastguard Worker     bl nterp_to_nterp_static_non_range
836*795d594fSAndroid Build Coastguard Worker     .else
837*795d594fSAndroid Build Coastguard Worker     bl nterp_to_nterp_instance_non_range
838*795d594fSAndroid Build Coastguard Worker     .endif
839*795d594fSAndroid Build Coastguard Worker     b .Ldone_return_\suffix
840*795d594fSAndroid Build Coastguard Worker   .endif
841*795d594fSAndroid Build Coastguard Worker
842*795d594fSAndroid Build Coastguard Worker.Lcall_compiled_code_\suffix:
843*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
844*795d594fSAndroid Build Coastguard Worker   // No fast path for polymorphic calls.
845*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
846*795d594fSAndroid Build Coastguard Worker   // No fast path for custom calls.
847*795d594fSAndroid Build Coastguard Worker   .elseif \is_string_init
848*795d594fSAndroid Build Coastguard Worker   // No fast path for string.init.
849*795d594fSAndroid Build Coastguard Worker   .else
850*795d594fSAndroid Build Coastguard Worker     ldr wip, [x0, #ART_METHOD_ACCESS_FLAGS_OFFSET]
851*795d594fSAndroid Build Coastguard Worker     tbz wip, #ART_METHOD_NTERP_INVOKE_FAST_PATH_FLAG_BIT, .Lfast_path_with_few_args_\suffix
852*795d594fSAndroid Build Coastguard Worker     FETCH_B wip2, 0, 1
853*795d594fSAndroid Build Coastguard Worker     asr ip, ip2, #4
854*795d594fSAndroid Build Coastguard Worker     .if \is_static
855*795d594fSAndroid Build Coastguard Worker     cbz ip, .Linvoke_fast_path_\suffix
856*795d594fSAndroid Build Coastguard Worker     .else
857*795d594fSAndroid Build Coastguard Worker     cmp ip, #1
858*795d594fSAndroid Build Coastguard Worker     b.eq .Linvoke_fast_path_\suffix
859*795d594fSAndroid Build Coastguard Worker     .endif
860*795d594fSAndroid Build Coastguard Worker     FETCH w8, 2
861*795d594fSAndroid Build Coastguard Worker     cmp ip, #2
862*795d594fSAndroid Build Coastguard Worker     .if \is_static
863*795d594fSAndroid Build Coastguard Worker     b.lt .Lone_arg_fast_path_\suffix
864*795d594fSAndroid Build Coastguard Worker     .endif
865*795d594fSAndroid Build Coastguard Worker     b.eq .Ltwo_args_fast_path_\suffix
866*795d594fSAndroid Build Coastguard Worker     cmp ip, #4
867*795d594fSAndroid Build Coastguard Worker     b.lt .Lthree_args_fast_path_\suffix
868*795d594fSAndroid Build Coastguard Worker     b.eq .Lfour_args_fast_path_\suffix
869*795d594fSAndroid Build Coastguard Worker
870*795d594fSAndroid Build Coastguard Worker     and         ip, ip2, #15
871*795d594fSAndroid Build Coastguard Worker     GET_VREG    w5, wip
872*795d594fSAndroid Build Coastguard Worker.Lfour_args_fast_path_\suffix:
873*795d594fSAndroid Build Coastguard Worker     asr         ip, x8, #12
874*795d594fSAndroid Build Coastguard Worker     GET_VREG    w4, wip
875*795d594fSAndroid Build Coastguard Worker.Lthree_args_fast_path_\suffix:
876*795d594fSAndroid Build Coastguard Worker     ubfx        ip, x8, #8, #4
877*795d594fSAndroid Build Coastguard Worker     GET_VREG    w3, wip
878*795d594fSAndroid Build Coastguard Worker.Ltwo_args_fast_path_\suffix:
879*795d594fSAndroid Build Coastguard Worker     ubfx        ip, x8, #4, #4
880*795d594fSAndroid Build Coastguard Worker     GET_VREG    w2, wip
881*795d594fSAndroid Build Coastguard Worker.Lone_arg_fast_path_\suffix:
882*795d594fSAndroid Build Coastguard Worker     .if \is_static
883*795d594fSAndroid Build Coastguard Worker     and         ip, x8, #0xf
884*795d594fSAndroid Build Coastguard Worker     GET_VREG    w1, wip
885*795d594fSAndroid Build Coastguard Worker     .else
886*795d594fSAndroid Build Coastguard Worker     // First argument already in w1.
887*795d594fSAndroid Build Coastguard Worker     .endif
888*795d594fSAndroid Build Coastguard Worker.Linvoke_fast_path_\suffix:
889*795d594fSAndroid Build Coastguard Worker     .if \is_interface
890*795d594fSAndroid Build Coastguard Worker     // Setup hidden argument.
891*795d594fSAndroid Build Coastguard Worker     mov ip2, x26
892*795d594fSAndroid Build Coastguard Worker     .endif
893*795d594fSAndroid Build Coastguard Worker     ldr lr, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64]
894*795d594fSAndroid Build Coastguard Worker     blr lr
895*795d594fSAndroid Build Coastguard Worker     FETCH_ADVANCE_INST 3
896*795d594fSAndroid Build Coastguard Worker     GET_INST_OPCODE ip
897*795d594fSAndroid Build Coastguard Worker     GOTO_OPCODE ip
898*795d594fSAndroid Build Coastguard Worker
899*795d594fSAndroid Build Coastguard Worker.Lfast_path_with_few_args_\suffix:
900*795d594fSAndroid Build Coastguard Worker     // Fast path when we have zero or one argument (modulo 'this'). If there
901*795d594fSAndroid Build Coastguard Worker     // is one argument, we can put it in both floating point and core register.
902*795d594fSAndroid Build Coastguard Worker     FETCH_B w2, 0, 1
903*795d594fSAndroid Build Coastguard Worker     .if \is_static
904*795d594fSAndroid Build Coastguard Worker     cmp w2, #(2 << 4)
905*795d594fSAndroid Build Coastguard Worker     .else
906*795d594fSAndroid Build Coastguard Worker     cmp w2, #(3 << 4)
907*795d594fSAndroid Build Coastguard Worker     .endif
908*795d594fSAndroid Build Coastguard Worker     b.ge .Lget_shorty_\suffix
909*795d594fSAndroid Build Coastguard Worker     .if \is_static
910*795d594fSAndroid Build Coastguard Worker     tbz w2, #4, .Linvoke_with_few_args_\suffix
911*795d594fSAndroid Build Coastguard Worker     .else
912*795d594fSAndroid Build Coastguard Worker     tbnz w2, #4, .Linvoke_with_few_args_\suffix
913*795d594fSAndroid Build Coastguard Worker     .endif
914*795d594fSAndroid Build Coastguard Worker     FETCH w2, 2
915*795d594fSAndroid Build Coastguard Worker     .if \is_static
916*795d594fSAndroid Build Coastguard Worker     and w2, w2, #0xf  // dex register of first argument
917*795d594fSAndroid Build Coastguard Worker     GET_VREG w1, w2
918*795d594fSAndroid Build Coastguard Worker     fmov s0, w1
919*795d594fSAndroid Build Coastguard Worker     .else
920*795d594fSAndroid Build Coastguard Worker     ubfx x2, x2, #4, #4  // dex register of second argument
921*795d594fSAndroid Build Coastguard Worker     GET_VREG w2, w2
922*795d594fSAndroid Build Coastguard Worker     fmov s0, w2
923*795d594fSAndroid Build Coastguard Worker     .endif
924*795d594fSAndroid Build Coastguard Worker.Linvoke_with_few_args_\suffix:
925*795d594fSAndroid Build Coastguard Worker     // Check if the next instruction is move-result or move-result-wide.
926*795d594fSAndroid Build Coastguard Worker     // If it is, we fetch the shorty and jump to the regular invocation.
927*795d594fSAndroid Build Coastguard Worker     FETCH w27, 3
928*795d594fSAndroid Build Coastguard Worker     and ip, x27, #0xfe
929*795d594fSAndroid Build Coastguard Worker     cmp ip, #0x0a
930*795d594fSAndroid Build Coastguard Worker     b.eq .Lget_shorty_and_invoke_\suffix
931*795d594fSAndroid Build Coastguard Worker     .if \is_interface
932*795d594fSAndroid Build Coastguard Worker     // Setup hidden argument.
933*795d594fSAndroid Build Coastguard Worker     mov ip2, x26
934*795d594fSAndroid Build Coastguard Worker     .endif
935*795d594fSAndroid Build Coastguard Worker     ldr lr, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64]
936*795d594fSAndroid Build Coastguard Worker     blr lr
937*795d594fSAndroid Build Coastguard Worker     # TODO: Use some other register for shorty and prefetch the instruction directly to wINST.
938*795d594fSAndroid Build Coastguard Worker     mov xINST, x27
939*795d594fSAndroid Build Coastguard Worker     ADVANCE 3
940*795d594fSAndroid Build Coastguard Worker     GET_INST_OPCODE ip
941*795d594fSAndroid Build Coastguard Worker     GOTO_OPCODE ip
942*795d594fSAndroid Build Coastguard Worker.Lget_shorty_and_invoke_\suffix:
943*795d594fSAndroid Build Coastguard Worker     GET_SHORTY_SLOW_PATH xINST, \is_interface
944*795d594fSAndroid Build Coastguard Worker     b .Lgpr_setup_finished_\suffix
945*795d594fSAndroid Build Coastguard Worker   .endif
946*795d594fSAndroid Build Coastguard Worker
947*795d594fSAndroid Build Coastguard Worker.Lget_shorty_\suffix:
948*795d594fSAndroid Build Coastguard Worker   GET_SHORTY xINST, \is_interface, \is_polymorphic, \is_custom
949*795d594fSAndroid Build Coastguard Worker   // From this point:
950*795d594fSAndroid Build Coastguard Worker   // - xINST contains shorty (in callee-save to switch over return value after call).
951*795d594fSAndroid Build Coastguard Worker   // - x0 contains method
952*795d594fSAndroid Build Coastguard Worker   // - x1 contains 'this' pointer for instance method.
953*795d594fSAndroid Build Coastguard Worker   // - for interface calls, x26 contains the interface method.
954*795d594fSAndroid Build Coastguard Worker   add x9, xINST, #1  // shorty + 1  ; ie skip return arg character
955*795d594fSAndroid Build Coastguard Worker   FETCH w11, 2 // arguments
956*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
957*795d594fSAndroid Build Coastguard Worker   lsr x11, x11, #4
958*795d594fSAndroid Build Coastguard Worker   mov x10, #1       // ignore first argument
959*795d594fSAndroid Build Coastguard Worker   .elseif \is_static
960*795d594fSAndroid Build Coastguard Worker   mov x10, xzr      // arg_index
961*795d594fSAndroid Build Coastguard Worker   .else
962*795d594fSAndroid Build Coastguard Worker   lsr x11, x11, #4
963*795d594fSAndroid Build Coastguard Worker   mov x10, #1       // ignore first argument
964*795d594fSAndroid Build Coastguard Worker   .endif
965*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_FPS d0, s0, x11, x9, x10, .Lxmm_setup_finished_\suffix
966*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_FPS d1, s1, x11, x9, x10, .Lxmm_setup_finished_\suffix
967*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_FPS d2, s2, x11, x9, x10, .Lxmm_setup_finished_\suffix
968*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_FPS d3, s3, x11, x9, x10, .Lxmm_setup_finished_\suffix
969*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_FPS d4, s4, x11, x9, x10, .Lxmm_setup_finished_\suffix
970*795d594fSAndroid Build Coastguard Worker.Lxmm_setup_finished_\suffix:
971*795d594fSAndroid Build Coastguard Worker   add x9, xINST, #1  // shorty + 1  ; ie skip return arg character
972*795d594fSAndroid Build Coastguard Worker   FETCH w11, 2 // arguments
973*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
974*795d594fSAndroid Build Coastguard Worker   lsr x11, x11, #4
975*795d594fSAndroid Build Coastguard Worker   mov x10, #1       // ignore first argument
976*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_GPRS x1, w1, x11, x9, x10, .Lgpr_setup_finished_\suffix
977*795d594fSAndroid Build Coastguard Worker   .elseif \is_static
978*795d594fSAndroid Build Coastguard Worker   mov x10, xzr      // arg_index
979*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_GPRS x1, w1, x11, x9, x10, .Lgpr_setup_finished_\suffix
980*795d594fSAndroid Build Coastguard Worker   .else
981*795d594fSAndroid Build Coastguard Worker   lsr x11, x11, #4
982*795d594fSAndroid Build Coastguard Worker   mov x10, #1       // ignore first argument
983*795d594fSAndroid Build Coastguard Worker   .endif
984*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_GPRS x2, w2, x11, x9, x10, .Lgpr_setup_finished_\suffix
985*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_GPRS x3, w3, x11, x9, x10, .Lgpr_setup_finished_\suffix
986*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_GPRS x4, w4, x11, x9, x10, .Lgpr_setup_finished_\suffix
987*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_GPRS x5, w5, x11, x9, x10, .Lgpr_setup_finished_\suffix
988*795d594fSAndroid Build Coastguard Worker.Lgpr_setup_finished_\suffix:
989*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
990*795d594fSAndroid Build Coastguard Worker   bl art_quick_invoke_polymorphic
991*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
992*795d594fSAndroid Build Coastguard Worker   bl art_quick_invoke_custom
993*795d594fSAndroid Build Coastguard Worker   .else
994*795d594fSAndroid Build Coastguard Worker      .if \is_interface
995*795d594fSAndroid Build Coastguard Worker      // Setup hidden argument.
996*795d594fSAndroid Build Coastguard Worker      mov ip2, x26
997*795d594fSAndroid Build Coastguard Worker      .endif
998*795d594fSAndroid Build Coastguard Worker      ldr lr, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64]
999*795d594fSAndroid Build Coastguard Worker      blr lr
1000*795d594fSAndroid Build Coastguard Worker   .endif
1001*795d594fSAndroid Build Coastguard Worker   SETUP_RETURN_VALUE xINST
1002*795d594fSAndroid Build Coastguard Worker.Ldone_return_\suffix:
1003*795d594fSAndroid Build Coastguard Worker   /* resume execution of caller */
1004*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
1005*795d594fSAndroid Build Coastguard Worker   FETCH w11, 2 // arguments
1006*795d594fSAndroid Build Coastguard Worker   and x11, x11, #0xf
1007*795d594fSAndroid Build Coastguard Worker   GET_VREG w1, w11
1008*795d594fSAndroid Build Coastguard Worker   UPDATE_REGISTERS_FOR_STRING_INIT w1, w0
1009*795d594fSAndroid Build Coastguard Worker   .endif
1010*795d594fSAndroid Build Coastguard Worker
1011*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
1012*795d594fSAndroid Build Coastguard Worker   FETCH_ADVANCE_INST 4
1013*795d594fSAndroid Build Coastguard Worker   .else
1014*795d594fSAndroid Build Coastguard Worker   FETCH_ADVANCE_INST 3
1015*795d594fSAndroid Build Coastguard Worker   .endif
1016*795d594fSAndroid Build Coastguard Worker   GET_INST_OPCODE ip
1017*795d594fSAndroid Build Coastguard Worker   GOTO_OPCODE ip
1018*795d594fSAndroid Build Coastguard Worker.endm
1019*795d594fSAndroid Build Coastguard Worker
1020*795d594fSAndroid Build Coastguard Worker// Puts the next floating point argument into the expected register,
1021*795d594fSAndroid Build Coastguard Worker// fetching values based on a range invoke.
1022*795d594fSAndroid Build Coastguard Worker// Uses ip as temporary.
1023*795d594fSAndroid Build Coastguard Worker.macro LOOP_RANGE_OVER_SHORTY_LOADING_FPS dreg, sreg, shorty, arg_index, stack_index, finished
1024*795d594fSAndroid Build Coastguard Worker1: // LOOP
1025*795d594fSAndroid Build Coastguard Worker    ldrb wip, [\shorty], #1         // Load next character in shorty, and increment.
1026*795d594fSAndroid Build Coastguard Worker    cbz wip, \finished              // if (wip == '\0') goto finished
1027*795d594fSAndroid Build Coastguard Worker    cmp wip, #68                    // if (wip == 'D') goto FOUND_DOUBLE
1028*795d594fSAndroid Build Coastguard Worker    b.eq 2f
1029*795d594fSAndroid Build Coastguard Worker    cmp wip, #70                    // if (wip == 'F') goto FOUND_FLOAT
1030*795d594fSAndroid Build Coastguard Worker    b.eq 3f
1031*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
1032*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #1
1033*795d594fSAndroid Build Coastguard Worker    //  Handle extra argument in arg array taken by a long.
1034*795d594fSAndroid Build Coastguard Worker    cmp wip, #74                    // if (wip != 'J') goto LOOP
1035*795d594fSAndroid Build Coastguard Worker    b.ne 1b
1036*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
1037*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #1
1038*795d594fSAndroid Build Coastguard Worker    b 1b                        // goto LOOP
1039*795d594fSAndroid Build Coastguard Worker2:  // FOUND_DOUBLE
1040*795d594fSAndroid Build Coastguard Worker    GET_VREG_DOUBLE \dreg, \arg_index
1041*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #2
1042*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #2
1043*795d594fSAndroid Build Coastguard Worker    b 4f
1044*795d594fSAndroid Build Coastguard Worker3:  // FOUND_FLOAT
1045*795d594fSAndroid Build Coastguard Worker    GET_VREG \sreg, \arg_index
1046*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
1047*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #1
1048*795d594fSAndroid Build Coastguard Worker4:
1049*795d594fSAndroid Build Coastguard Worker.endm
1050*795d594fSAndroid Build Coastguard Worker
1051*795d594fSAndroid Build Coastguard Worker// Puts the next floating point argument into the expected stack slot,
1052*795d594fSAndroid Build Coastguard Worker// fetching values based on a range invoke.
1053*795d594fSAndroid Build Coastguard Worker// Uses ip as temporary.
1054*795d594fSAndroid Build Coastguard Worker//
1055*795d594fSAndroid Build Coastguard Worker// TODO: We could just copy all the vregs to the stack slots in a simple loop
1056*795d594fSAndroid Build Coastguard Worker// without looking at the shorty at all. (We could also drop
1057*795d594fSAndroid Build Coastguard Worker// the "stack_index" from the macros for loading registers.) We could also do
1058*795d594fSAndroid Build Coastguard Worker// that conditionally if argument word count > 6; otherwise we know that all
1059*795d594fSAndroid Build Coastguard Worker// args fit into registers.
1060*795d594fSAndroid Build Coastguard Worker.macro LOOP_RANGE_OVER_FPs shorty, arg_index, stack_index, finished
1061*795d594fSAndroid Build Coastguard Worker1: // LOOP
1062*795d594fSAndroid Build Coastguard Worker    ldrb wip, [\shorty], #1         // Load next character in shorty, and increment.
1063*795d594fSAndroid Build Coastguard Worker    cbz wip, \finished              // if (wip == '\0') goto finished
1064*795d594fSAndroid Build Coastguard Worker    cmp wip, #68                    // if (wip == 'D') goto FOUND_DOUBLE
1065*795d594fSAndroid Build Coastguard Worker    b.eq 2f
1066*795d594fSAndroid Build Coastguard Worker    cmp wip, #70                    // if (wip == 'F') goto FOUND_FLOAT
1067*795d594fSAndroid Build Coastguard Worker    b.eq 3f
1068*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
1069*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #1
1070*795d594fSAndroid Build Coastguard Worker    //  Handle extra argument in arg array taken by a long.
1071*795d594fSAndroid Build Coastguard Worker    cmp wip, #74                    // if (wip != 'J') goto LOOP
1072*795d594fSAndroid Build Coastguard Worker    b.ne 1b
1073*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
1074*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #1
1075*795d594fSAndroid Build Coastguard Worker    b 1b                        // goto LOOP
1076*795d594fSAndroid Build Coastguard Worker2:  // FOUND_DOUBLE
1077*795d594fSAndroid Build Coastguard Worker    GET_VREG_WIDE ip, \arg_index
1078*795d594fSAndroid Build Coastguard Worker    add ip2, sp, \stack_index, uxtw #2
1079*795d594fSAndroid Build Coastguard Worker    str ip, [ip2]
1080*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #2
1081*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #2
1082*795d594fSAndroid Build Coastguard Worker    b 1b
1083*795d594fSAndroid Build Coastguard Worker3:  // FOUND_FLOAT
1084*795d594fSAndroid Build Coastguard Worker    GET_VREG wip, \arg_index
1085*795d594fSAndroid Build Coastguard Worker    str wip, [sp, \stack_index, uxtw #2]
1086*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
1087*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #1
1088*795d594fSAndroid Build Coastguard Worker    b 1b
1089*795d594fSAndroid Build Coastguard Worker.endm
1090*795d594fSAndroid Build Coastguard Worker
1091*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object argument in the expected register,
1092*795d594fSAndroid Build Coastguard Worker// fetching values based on a range invoke.
1093*795d594fSAndroid Build Coastguard Worker// Uses ip as temporary.
1094*795d594fSAndroid Build Coastguard Worker.macro LOOP_RANGE_OVER_SHORTY_LOADING_GPRS reg64, reg32, shorty, arg_index, stack_index, finished
1095*795d594fSAndroid Build Coastguard Worker1: // LOOP
1096*795d594fSAndroid Build Coastguard Worker    ldrb wip, [\shorty], #1         // Load next character in shorty, and increment.
1097*795d594fSAndroid Build Coastguard Worker    cbz wip, \finished              // if (wip == '\0') goto finished
1098*795d594fSAndroid Build Coastguard Worker    cmp wip, #74                    // if (wip == 'J') goto FOUND_LONG
1099*795d594fSAndroid Build Coastguard Worker    b.eq 2f
1100*795d594fSAndroid Build Coastguard Worker    cmp wip, #70                   // if (wip == 'F') goto SKIP_FLOAT
1101*795d594fSAndroid Build Coastguard Worker    b.eq 3f
1102*795d594fSAndroid Build Coastguard Worker    cmp wip, #68                    // if (wip == 'D') goto SKIP_DOUBLE
1103*795d594fSAndroid Build Coastguard Worker    b.eq 4f
1104*795d594fSAndroid Build Coastguard Worker    GET_VREG \reg32, \arg_index
1105*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
1106*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #1
1107*795d594fSAndroid Build Coastguard Worker    b 5f
1108*795d594fSAndroid Build Coastguard Worker2:  // FOUND_LONG
1109*795d594fSAndroid Build Coastguard Worker    GET_VREG_WIDE \reg64, \arg_index
1110*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #2
1111*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #2
1112*795d594fSAndroid Build Coastguard Worker    b 5f
1113*795d594fSAndroid Build Coastguard Worker3:  // SKIP_FLOAT
1114*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
1115*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #1
1116*795d594fSAndroid Build Coastguard Worker    b 1b
1117*795d594fSAndroid Build Coastguard Worker4:  // SKIP_DOUBLE
1118*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #2
1119*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #2
1120*795d594fSAndroid Build Coastguard Worker    b 1b
1121*795d594fSAndroid Build Coastguard Worker5:
1122*795d594fSAndroid Build Coastguard Worker.endm
1123*795d594fSAndroid Build Coastguard Worker
1124*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object argument in the expected stack slot,
1125*795d594fSAndroid Build Coastguard Worker// fetching values based on a range invoke.
1126*795d594fSAndroid Build Coastguard Worker// Uses ip as temporary.
1127*795d594fSAndroid Build Coastguard Worker.macro LOOP_RANGE_OVER_INTs shorty, arg_index, stack_index, finished
1128*795d594fSAndroid Build Coastguard Worker1: // LOOP
1129*795d594fSAndroid Build Coastguard Worker    ldrb wip, [\shorty], #1         // Load next character in shorty, and increment.
1130*795d594fSAndroid Build Coastguard Worker    cbz wip, \finished              // if (wip == '\0') goto finished
1131*795d594fSAndroid Build Coastguard Worker    cmp wip, #74                    // if (wip == 'J') goto FOUND_LONG
1132*795d594fSAndroid Build Coastguard Worker    b.eq 2f
1133*795d594fSAndroid Build Coastguard Worker    cmp wip, #70                    // if (wip == 'F') goto SKIP_FLOAT
1134*795d594fSAndroid Build Coastguard Worker    b.eq 3f
1135*795d594fSAndroid Build Coastguard Worker    cmp wip, #68                    // if (wip == 'D') goto SKIP_DOUBLE
1136*795d594fSAndroid Build Coastguard Worker    b.eq 4f
1137*795d594fSAndroid Build Coastguard Worker    GET_VREG wip, \arg_index
1138*795d594fSAndroid Build Coastguard Worker    str wip, [sp, \stack_index, uxtw #2]
1139*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
1140*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #1
1141*795d594fSAndroid Build Coastguard Worker    b 1b
1142*795d594fSAndroid Build Coastguard Worker2:  // FOUND_LONG
1143*795d594fSAndroid Build Coastguard Worker    GET_VREG_WIDE ip, \arg_index
1144*795d594fSAndroid Build Coastguard Worker    add ip2, sp, \stack_index, uxtw #2
1145*795d594fSAndroid Build Coastguard Worker    str ip, [ip2]
1146*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #2
1147*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #2
1148*795d594fSAndroid Build Coastguard Worker    b 1b
1149*795d594fSAndroid Build Coastguard Worker3:  // SKIP_FLOAT
1150*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #1
1151*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #1
1152*795d594fSAndroid Build Coastguard Worker    b 1b
1153*795d594fSAndroid Build Coastguard Worker4:  // SKIP_DOUBLE
1154*795d594fSAndroid Build Coastguard Worker    add \arg_index, \arg_index, #2
1155*795d594fSAndroid Build Coastguard Worker    add \stack_index, \stack_index, #2
1156*795d594fSAndroid Build Coastguard Worker    b 1b
1157*795d594fSAndroid Build Coastguard Worker.endm
1158*795d594fSAndroid Build Coastguard Worker
1159*795d594fSAndroid Build Coastguard Worker.macro COMMON_INVOKE_RANGE is_static=0, is_interface=0, suffix="", is_string_init=0, is_polymorphic=0, is_custom=0
1160*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
1161*795d594fSAndroid Build Coastguard Worker   // We always go to compiled code for polymorphic calls.
1162*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
1163*795d594fSAndroid Build Coastguard Worker   // We always go to compiled code for custom calls.
1164*795d594fSAndroid Build Coastguard Worker   .else
1165*795d594fSAndroid Build Coastguard Worker     DO_ENTRY_POINT_CHECK .Lcall_compiled_code_range_\suffix
1166*795d594fSAndroid Build Coastguard Worker     GET_CODE_ITEM
1167*795d594fSAndroid Build Coastguard Worker     .if \is_string_init
1168*795d594fSAndroid Build Coastguard Worker     bl nterp_to_nterp_string_init_range
1169*795d594fSAndroid Build Coastguard Worker     .elseif \is_static
1170*795d594fSAndroid Build Coastguard Worker     bl nterp_to_nterp_static_range
1171*795d594fSAndroid Build Coastguard Worker     .else
1172*795d594fSAndroid Build Coastguard Worker     bl nterp_to_nterp_instance_range
1173*795d594fSAndroid Build Coastguard Worker     .endif
1174*795d594fSAndroid Build Coastguard Worker     b .Ldone_return_range_\suffix
1175*795d594fSAndroid Build Coastguard Worker   .endif
1176*795d594fSAndroid Build Coastguard Worker
1177*795d594fSAndroid Build Coastguard Worker.Lcall_compiled_code_range_\suffix:
1178*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
1179*795d594fSAndroid Build Coastguard Worker   // No fast path for polymorphic calls.
1180*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
1181*795d594fSAndroid Build Coastguard Worker   // No fast path for custom calls.
1182*795d594fSAndroid Build Coastguard Worker   .elseif \is_string_init
1183*795d594fSAndroid Build Coastguard Worker   // No fast path for string.init.
1184*795d594fSAndroid Build Coastguard Worker   .else
1185*795d594fSAndroid Build Coastguard Worker     ldr wip, [x0, #ART_METHOD_ACCESS_FLAGS_OFFSET]
1186*795d594fSAndroid Build Coastguard Worker     tbz wip, #ART_METHOD_NTERP_INVOKE_FAST_PATH_FLAG_BIT, .Lfast_path_with_few_args_range_\suffix
1187*795d594fSAndroid Build Coastguard Worker     FETCH_B wip2, 0, 1  // Number of arguments
1188*795d594fSAndroid Build Coastguard Worker     .if \is_static
1189*795d594fSAndroid Build Coastguard Worker     cbz ip2, .Linvoke_fast_path_range_\suffix
1190*795d594fSAndroid Build Coastguard Worker     .else
1191*795d594fSAndroid Build Coastguard Worker     cmp ip2, #1
1192*795d594fSAndroid Build Coastguard Worker     b.eq .Linvoke_fast_path_range_\suffix
1193*795d594fSAndroid Build Coastguard Worker     .endif
1194*795d594fSAndroid Build Coastguard Worker     FETCH wip, 2  // dex register of first argument
1195*795d594fSAndroid Build Coastguard Worker     add x8, xFP, wip, uxtw #2  // location of first dex register value
1196*795d594fSAndroid Build Coastguard Worker     cmp ip2, #2
1197*795d594fSAndroid Build Coastguard Worker     .if \is_static
1198*795d594fSAndroid Build Coastguard Worker     b.lt .Lone_arg_fast_path_range_\suffix
1199*795d594fSAndroid Build Coastguard Worker     .endif
1200*795d594fSAndroid Build Coastguard Worker     b.eq .Ltwo_args_fast_path_range_\suffix
1201*795d594fSAndroid Build Coastguard Worker     cmp ip2, #4
1202*795d594fSAndroid Build Coastguard Worker     b.lt .Lthree_args_fast_path_range_\suffix
1203*795d594fSAndroid Build Coastguard Worker     b.eq .Lfour_args_fast_path_range_\suffix
1204*795d594fSAndroid Build Coastguard Worker     cmp ip2, #6
1205*795d594fSAndroid Build Coastguard Worker     b.lt .Lfive_args_fast_path_range_\suffix
1206*795d594fSAndroid Build Coastguard Worker     b.eq .Lsix_args_fast_path_range_\suffix
1207*795d594fSAndroid Build Coastguard Worker     cmp ip2, #7
1208*795d594fSAndroid Build Coastguard Worker     b.eq .Lseven_args_fast_path_range_\suffix
1209*795d594fSAndroid Build Coastguard Worker     // Setup x8 to point to the stack location of parameters we do not need
1210*795d594fSAndroid Build Coastguard Worker     // to put parameters in.
1211*795d594fSAndroid Build Coastguard Worker     add x9, sp, #8  // Add space for the ArtMethod
1212*795d594fSAndroid Build Coastguard Worker
1213*795d594fSAndroid Build Coastguard Worker.Lloop_over_fast_path_range_\suffix:
1214*795d594fSAndroid Build Coastguard Worker     sub ip2, ip2, #1
1215*795d594fSAndroid Build Coastguard Worker     ldr wip, [x8, ip2, lsl #2]
1216*795d594fSAndroid Build Coastguard Worker     str wip, [x9, ip2, lsl #2]
1217*795d594fSAndroid Build Coastguard Worker     cmp ip2, #7
1218*795d594fSAndroid Build Coastguard Worker     b.ne .Lloop_over_fast_path_range_\suffix
1219*795d594fSAndroid Build Coastguard Worker
1220*795d594fSAndroid Build Coastguard Worker.Lseven_args_fast_path_range_\suffix:
1221*795d594fSAndroid Build Coastguard Worker     ldr w7, [x8, #24]
1222*795d594fSAndroid Build Coastguard Worker.Lsix_args_fast_path_range_\suffix:
1223*795d594fSAndroid Build Coastguard Worker     ldr w6, [x8, #20]
1224*795d594fSAndroid Build Coastguard Worker.Lfive_args_fast_path_range_\suffix:
1225*795d594fSAndroid Build Coastguard Worker     ldr w5, [x8, #16]
1226*795d594fSAndroid Build Coastguard Worker.Lfour_args_fast_path_range_\suffix:
1227*795d594fSAndroid Build Coastguard Worker     ldr w4, [x8, #12]
1228*795d594fSAndroid Build Coastguard Worker.Lthree_args_fast_path_range_\suffix:
1229*795d594fSAndroid Build Coastguard Worker     ldr w3, [x8, #8]
1230*795d594fSAndroid Build Coastguard Worker.Ltwo_args_fast_path_range_\suffix:
1231*795d594fSAndroid Build Coastguard Worker     ldr w2, [x8, #4]
1232*795d594fSAndroid Build Coastguard Worker.Lone_arg_fast_path_range_\suffix:
1233*795d594fSAndroid Build Coastguard Worker     .if \is_static
1234*795d594fSAndroid Build Coastguard Worker     ldr w1, [x8, #0]
1235*795d594fSAndroid Build Coastguard Worker     .else
1236*795d594fSAndroid Build Coastguard Worker     // First argument already in w1.
1237*795d594fSAndroid Build Coastguard Worker     .endif
1238*795d594fSAndroid Build Coastguard Worker.Linvoke_fast_path_range_\suffix:
1239*795d594fSAndroid Build Coastguard Worker     .if \is_interface
1240*795d594fSAndroid Build Coastguard Worker     // Setup hidden argument.
1241*795d594fSAndroid Build Coastguard Worker     mov ip2, x26
1242*795d594fSAndroid Build Coastguard Worker     .endif
1243*795d594fSAndroid Build Coastguard Worker     ldr lr, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64]
1244*795d594fSAndroid Build Coastguard Worker     blr lr
1245*795d594fSAndroid Build Coastguard Worker     FETCH_ADVANCE_INST 3
1246*795d594fSAndroid Build Coastguard Worker     GET_INST_OPCODE ip
1247*795d594fSAndroid Build Coastguard Worker     GOTO_OPCODE ip
1248*795d594fSAndroid Build Coastguard Worker
1249*795d594fSAndroid Build Coastguard Worker.Lfast_path_with_few_args_range_\suffix:
1250*795d594fSAndroid Build Coastguard Worker     // Fast path when we have zero or one argument (modulo 'this'). If there
1251*795d594fSAndroid Build Coastguard Worker     // is one argument, we can put it in both floating point and core register.
1252*795d594fSAndroid Build Coastguard Worker     FETCH_B w2, 0, 1 // number of arguments
1253*795d594fSAndroid Build Coastguard Worker     .if \is_static
1254*795d594fSAndroid Build Coastguard Worker     cmp w2, #1
1255*795d594fSAndroid Build Coastguard Worker     .else
1256*795d594fSAndroid Build Coastguard Worker     cmp w2, #2
1257*795d594fSAndroid Build Coastguard Worker     .endif
1258*795d594fSAndroid Build Coastguard Worker     b.lt .Linvoke_with_few_args_range_\suffix
1259*795d594fSAndroid Build Coastguard Worker     b.ne .Lget_shorty_range_\suffix
1260*795d594fSAndroid Build Coastguard Worker     FETCH w3, 2  // dex register of first argument
1261*795d594fSAndroid Build Coastguard Worker     .if \is_static
1262*795d594fSAndroid Build Coastguard Worker     GET_VREG w1, w3
1263*795d594fSAndroid Build Coastguard Worker     fmov s0, w1
1264*795d594fSAndroid Build Coastguard Worker     .else
1265*795d594fSAndroid Build Coastguard Worker     add w3, w3, #1  // Add 1 for next argument
1266*795d594fSAndroid Build Coastguard Worker     GET_VREG w2, w3
1267*795d594fSAndroid Build Coastguard Worker     fmov s0, w2
1268*795d594fSAndroid Build Coastguard Worker     .endif
1269*795d594fSAndroid Build Coastguard Worker.Linvoke_with_few_args_range_\suffix:
1270*795d594fSAndroid Build Coastguard Worker     // Check if the next instruction is move-result or move-result-wide.
1271*795d594fSAndroid Build Coastguard Worker     // If it is, we fetch the shorty and jump to the regular invocation.
1272*795d594fSAndroid Build Coastguard Worker     FETCH w27, 3
1273*795d594fSAndroid Build Coastguard Worker     and ip, x27, #0xfe
1274*795d594fSAndroid Build Coastguard Worker     cmp ip, #0x0a
1275*795d594fSAndroid Build Coastguard Worker     b.eq .Lget_shorty_and_invoke_range_\suffix
1276*795d594fSAndroid Build Coastguard Worker     .if \is_interface
1277*795d594fSAndroid Build Coastguard Worker     // Setup hidden argument.
1278*795d594fSAndroid Build Coastguard Worker     mov ip2, x26
1279*795d594fSAndroid Build Coastguard Worker     .endif
1280*795d594fSAndroid Build Coastguard Worker     ldr lr, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64]
1281*795d594fSAndroid Build Coastguard Worker     blr lr
1282*795d594fSAndroid Build Coastguard Worker     mov xINST, x27
1283*795d594fSAndroid Build Coastguard Worker     ADVANCE 3
1284*795d594fSAndroid Build Coastguard Worker     GET_INST_OPCODE ip
1285*795d594fSAndroid Build Coastguard Worker     GOTO_OPCODE ip
1286*795d594fSAndroid Build Coastguard Worker.Lget_shorty_and_invoke_range_\suffix:
1287*795d594fSAndroid Build Coastguard Worker     GET_SHORTY_SLOW_PATH xINST, \is_interface
1288*795d594fSAndroid Build Coastguard Worker     b .Lgpr_setup_finished_range_\suffix
1289*795d594fSAndroid Build Coastguard Worker   .endif
1290*795d594fSAndroid Build Coastguard Worker
1291*795d594fSAndroid Build Coastguard Worker.Lget_shorty_range_\suffix:
1292*795d594fSAndroid Build Coastguard Worker   GET_SHORTY xINST, \is_interface, \is_polymorphic, \is_custom
1293*795d594fSAndroid Build Coastguard Worker   // From this point:
1294*795d594fSAndroid Build Coastguard Worker   // - xINST contains shorty (in callee-save to switch over return value after call).
1295*795d594fSAndroid Build Coastguard Worker   // - x0 contains method
1296*795d594fSAndroid Build Coastguard Worker   // - x1 contains 'this' pointer for instance method.
1297*795d594fSAndroid Build Coastguard Worker   // - for interface calls, x26 contains the interface method.
1298*795d594fSAndroid Build Coastguard Worker   add x9, xINST, #1  // shorty + 1  ; ie skip return arg character
1299*795d594fSAndroid Build Coastguard Worker   FETCH w10, 2 // arguments
1300*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
1301*795d594fSAndroid Build Coastguard Worker   add x10, x10, #1  // arg start index
1302*795d594fSAndroid Build Coastguard Worker   mov x11, #1       // index in stack
1303*795d594fSAndroid Build Coastguard Worker   .elseif \is_static
1304*795d594fSAndroid Build Coastguard Worker   mov x11, xzr      // index in stack
1305*795d594fSAndroid Build Coastguard Worker   .else
1306*795d594fSAndroid Build Coastguard Worker   add x10, x10, #1  // arg start index
1307*795d594fSAndroid Build Coastguard Worker   mov x11, #1       // index in stack
1308*795d594fSAndroid Build Coastguard Worker   .endif
1309*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_FPS d0, s0, x9, w10, w11, .Lxmm_setup_finished_range_\suffix
1310*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_FPS d1, s1, x9, w10, w11, .Lxmm_setup_finished_range_\suffix
1311*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_FPS d2, s2, x9, w10, w11, .Lxmm_setup_finished_range_\suffix
1312*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_FPS d3, s3, x9, w10, w11, .Lxmm_setup_finished_range_\suffix
1313*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_FPS d4, s4, x9, w10, w11, .Lxmm_setup_finished_range_\suffix
1314*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_FPS d5, s5, x9, w10, w11, .Lxmm_setup_finished_range_\suffix
1315*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_FPS d6, s6, x9, w10, w11, .Lxmm_setup_finished_range_\suffix
1316*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_FPS d7, s7, x9, w10, w11, .Lxmm_setup_finished_range_\suffix
1317*795d594fSAndroid Build Coastguard Worker   // Store in the outs array (stored above the ArtMethod in the stack)
1318*795d594fSAndroid Build Coastguard Worker   add x11, x11, #2 // Add two words for the ArtMethod stored before the outs.
1319*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_FPs x9, w10, w11, .Lxmm_setup_finished_range_\suffix
1320*795d594fSAndroid Build Coastguard Worker.Lxmm_setup_finished_range_\suffix:
1321*795d594fSAndroid Build Coastguard Worker   add x9, xINST, #1  // shorty + 1  ; ie skip return arg character
1322*795d594fSAndroid Build Coastguard Worker   FETCH w10, 2 // arguments
1323*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
1324*795d594fSAndroid Build Coastguard Worker   add x10, x10, #1  // arg start index
1325*795d594fSAndroid Build Coastguard Worker   mov x11, #1       // index in stack
1326*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x1, w1, x9, w10, w11, .Lgpr_setup_finished_range_\suffix
1327*795d594fSAndroid Build Coastguard Worker   .elseif \is_static
1328*795d594fSAndroid Build Coastguard Worker   mov x11, xzr      // index in stack
1329*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x1, w1, x9, w10, w11 .Lgpr_setup_finished_range_\suffix
1330*795d594fSAndroid Build Coastguard Worker   .else
1331*795d594fSAndroid Build Coastguard Worker   add x10, x10, #1  // arg start index
1332*795d594fSAndroid Build Coastguard Worker   mov x11, #1       // index in stack
1333*795d594fSAndroid Build Coastguard Worker   .endif
1334*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x2, w2, x9, w10, w11, .Lgpr_setup_finished_range_\suffix
1335*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x3, w3, x9, w10, w11, .Lgpr_setup_finished_range_\suffix
1336*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x4, w4, x9, w10, w11, .Lgpr_setup_finished_range_\suffix
1337*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x5, w5, x9, w10, w11, .Lgpr_setup_finished_range_\suffix
1338*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x6, w6, x9, w10, w11, .Lgpr_setup_finished_range_\suffix
1339*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x7, w7, x9, w10, w11, .Lgpr_setup_finished_range_\suffix
1340*795d594fSAndroid Build Coastguard Worker   // Store in the outs array (stored above the ArtMethod in the stack)
1341*795d594fSAndroid Build Coastguard Worker   add x11, x11, #2 // Add two words for the ArtMethod stored before the outs.
1342*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_INTs x9, w10, w11, .Lgpr_setup_finished_range_\suffix
1343*795d594fSAndroid Build Coastguard Worker.Lgpr_setup_finished_range_\suffix:
1344*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
1345*795d594fSAndroid Build Coastguard Worker   bl art_quick_invoke_polymorphic
1346*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
1347*795d594fSAndroid Build Coastguard Worker   bl art_quick_invoke_custom
1348*795d594fSAndroid Build Coastguard Worker   .else
1349*795d594fSAndroid Build Coastguard Worker      .if \is_interface
1350*795d594fSAndroid Build Coastguard Worker      // Setup hidden argument.
1351*795d594fSAndroid Build Coastguard Worker      mov ip2, x26
1352*795d594fSAndroid Build Coastguard Worker      .endif
1353*795d594fSAndroid Build Coastguard Worker      ldr lr, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64]
1354*795d594fSAndroid Build Coastguard Worker      blr lr
1355*795d594fSAndroid Build Coastguard Worker   .endif
1356*795d594fSAndroid Build Coastguard Worker   SETUP_RETURN_VALUE xINST
1357*795d594fSAndroid Build Coastguard Worker.Ldone_return_range_\suffix:
1358*795d594fSAndroid Build Coastguard Worker   /* resume execution of caller */
1359*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
1360*795d594fSAndroid Build Coastguard Worker   FETCH w11, 2 // arguments
1361*795d594fSAndroid Build Coastguard Worker   GET_VREG w1, w11
1362*795d594fSAndroid Build Coastguard Worker   UPDATE_REGISTERS_FOR_STRING_INIT w1, w0
1363*795d594fSAndroid Build Coastguard Worker   .endif
1364*795d594fSAndroid Build Coastguard Worker
1365*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
1366*795d594fSAndroid Build Coastguard Worker   FETCH_ADVANCE_INST 4
1367*795d594fSAndroid Build Coastguard Worker   .else
1368*795d594fSAndroid Build Coastguard Worker   FETCH_ADVANCE_INST 3
1369*795d594fSAndroid Build Coastguard Worker   .endif
1370*795d594fSAndroid Build Coastguard Worker   GET_INST_OPCODE ip
1371*795d594fSAndroid Build Coastguard Worker   GOTO_OPCODE ip
1372*795d594fSAndroid Build Coastguard Worker.endm
1373*795d594fSAndroid Build Coastguard Worker
1374*795d594fSAndroid Build Coastguard Worker.macro POISON_HEAP_REF_IF_OBJECT is_object, rRef
1375*795d594fSAndroid Build Coastguard Worker   .if \is_object
1376*795d594fSAndroid Build Coastguard Worker   POISON_HEAP_REF \rRef
1377*795d594fSAndroid Build Coastguard Worker   .endif
1378*795d594fSAndroid Build Coastguard Worker.endm
1379*795d594fSAndroid Build Coastguard Worker
1380*795d594fSAndroid Build Coastguard Worker.macro WRITE_BARRIER_IF_OBJECT is_object, value, holder, label
1381*795d594fSAndroid Build Coastguard Worker   .if \is_object
1382*795d594fSAndroid Build Coastguard Worker   cbz     \value, \label
1383*795d594fSAndroid Build Coastguard Worker   ldr     ip, [xSELF, #THREAD_CARD_TABLE_OFFSET]
1384*795d594fSAndroid Build Coastguard Worker   lsr     wip2, \holder, #CARD_TABLE_CARD_SHIFT
1385*795d594fSAndroid Build Coastguard Worker   strb    wip, [ip, ip2]
1386*795d594fSAndroid Build Coastguard Worker\label:
1387*795d594fSAndroid Build Coastguard Worker   .endif
1388*795d594fSAndroid Build Coastguard Worker.endm
1389*795d594fSAndroid Build Coastguard Worker
1390*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object parameter passed in physical register
1391*795d594fSAndroid Build Coastguard Worker// in the expected dex register array entry, and in case of object in the
1392*795d594fSAndroid Build Coastguard Worker// expected reference array entry.
1393*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_SHORTY_STORING_GPRS gpr_64, gpr_32, shorty, arg_offset, regs, refs, finished
1394*795d594fSAndroid Build Coastguard Worker1: // LOOP
1395*795d594fSAndroid Build Coastguard Worker    ldrb wip, [\shorty], #1       // Load next character in shorty, and increment.
1396*795d594fSAndroid Build Coastguard Worker    cbz wip, \finished            // if (wip == '\0') goto finished
1397*795d594fSAndroid Build Coastguard Worker    cmp wip, #74                  // if (wip == 'J') goto FOUND_LONG
1398*795d594fSAndroid Build Coastguard Worker    b.eq 2f
1399*795d594fSAndroid Build Coastguard Worker    cmp wip, #70                  // if (wip == 'F') goto SKIP_FLOAT
1400*795d594fSAndroid Build Coastguard Worker    b.eq 3f
1401*795d594fSAndroid Build Coastguard Worker    cmp wip, #68                  // if (wip == 'D') goto SKIP_DOUBLE
1402*795d594fSAndroid Build Coastguard Worker    b.eq 4f
1403*795d594fSAndroid Build Coastguard Worker    str \gpr_32, [\regs, \arg_offset]
1404*795d594fSAndroid Build Coastguard Worker    cmp wip, #76                  // if (wip != 'L') goto NOT_REFERENCE
1405*795d594fSAndroid Build Coastguard Worker    b.ne 6f
1406*795d594fSAndroid Build Coastguard Worker    str \gpr_32, [\refs, \arg_offset]
1407*795d594fSAndroid Build Coastguard Worker6:  // NOT_REFERENCE
1408*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #4
1409*795d594fSAndroid Build Coastguard Worker    b 5f
1410*795d594fSAndroid Build Coastguard Worker2:  // FOUND_LONG
1411*795d594fSAndroid Build Coastguard Worker    str \gpr_64, [\regs, \arg_offset]
1412*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #8
1413*795d594fSAndroid Build Coastguard Worker    b 5f
1414*795d594fSAndroid Build Coastguard Worker3:  // SKIP_FLOAT
1415*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #4
1416*795d594fSAndroid Build Coastguard Worker    b 1b
1417*795d594fSAndroid Build Coastguard Worker4:  // SKIP_DOUBLE
1418*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #8
1419*795d594fSAndroid Build Coastguard Worker    b 1b
1420*795d594fSAndroid Build Coastguard Worker5:
1421*795d594fSAndroid Build Coastguard Worker.endm
1422*795d594fSAndroid Build Coastguard Worker
1423*795d594fSAndroid Build Coastguard Worker// Puts the next floating point parameter passed in physical register
1424*795d594fSAndroid Build Coastguard Worker// in the expected dex register array entry.
1425*795d594fSAndroid Build Coastguard Worker// Uses ip as temporary.
1426*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_SHORTY_STORING_FPS dreg, sreg, shorty, arg_offset, fp, finished
1427*795d594fSAndroid Build Coastguard Worker1: // LOOP
1428*795d594fSAndroid Build Coastguard Worker    ldrb wip, [\shorty], #1                 // Load next character in shorty, and increment.
1429*795d594fSAndroid Build Coastguard Worker    cbz wip, \finished                      // if (wip == '\0') goto finished
1430*795d594fSAndroid Build Coastguard Worker    cmp wip, #68                            // if (wip == 'D') goto FOUND_DOUBLE
1431*795d594fSAndroid Build Coastguard Worker    b.eq 2f
1432*795d594fSAndroid Build Coastguard Worker    cmp wip, #70                            // if (wip == 'F') goto FOUND_FLOAT
1433*795d594fSAndroid Build Coastguard Worker    b.eq 3f
1434*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #4
1435*795d594fSAndroid Build Coastguard Worker    //  Handle extra argument in arg array taken by a long.
1436*795d594fSAndroid Build Coastguard Worker    cmp wip, #74                            // if (wip != 'J') goto LOOP
1437*795d594fSAndroid Build Coastguard Worker    b.ne 1b
1438*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #4
1439*795d594fSAndroid Build Coastguard Worker    b 1b                        // goto LOOP
1440*795d594fSAndroid Build Coastguard Worker2:  // FOUND_DOUBLE
1441*795d594fSAndroid Build Coastguard Worker    str \dreg, [\fp, \arg_offset]
1442*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #8
1443*795d594fSAndroid Build Coastguard Worker    b 4f
1444*795d594fSAndroid Build Coastguard Worker3:  // FOUND_FLOAT
1445*795d594fSAndroid Build Coastguard Worker    str \sreg, [\fp, \arg_offset]
1446*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #4
1447*795d594fSAndroid Build Coastguard Worker4:
1448*795d594fSAndroid Build Coastguard Worker.endm
1449*795d594fSAndroid Build Coastguard Worker
1450*795d594fSAndroid Build Coastguard Worker// Puts the next floating point parameter passed in stack
1451*795d594fSAndroid Build Coastguard Worker// in the expected dex register array entry.
1452*795d594fSAndroid Build Coastguard Worker// Uses ip as temporary.
1453*795d594fSAndroid Build Coastguard Worker//
1454*795d594fSAndroid Build Coastguard Worker// TODO: Or we could just spill regs to the reserved slots in the caller's
1455*795d594fSAndroid Build Coastguard Worker// frame and copy all regs in a simple loop. This time, however, we would
1456*795d594fSAndroid Build Coastguard Worker// need to look at the shorty anyway to look for the references.
1457*795d594fSAndroid Build Coastguard Worker// (The trade-off is different for passing arguments and receiving them.)
1458*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_FPs shorty, arg_offset, regs, stack_ptr, finished
1459*795d594fSAndroid Build Coastguard Worker1: // LOOP
1460*795d594fSAndroid Build Coastguard Worker    ldrb wip, [\shorty], #1                 // Load next character in shorty, and increment.
1461*795d594fSAndroid Build Coastguard Worker    cbz wip, \finished                      // if (wip == '\0') goto finished
1462*795d594fSAndroid Build Coastguard Worker    cmp wip, #68                            // if (wip == 'D') goto FOUND_DOUBLE
1463*795d594fSAndroid Build Coastguard Worker    b.eq 2f
1464*795d594fSAndroid Build Coastguard Worker    cmp wip, #70                            // if (wip == 'F') goto FOUND_FLOAT
1465*795d594fSAndroid Build Coastguard Worker    b.eq 3f
1466*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #4
1467*795d594fSAndroid Build Coastguard Worker    //  Handle extra argument in arg array taken by a long.
1468*795d594fSAndroid Build Coastguard Worker    cmp wip, #74                            // if (wip != 'J') goto LOOP
1469*795d594fSAndroid Build Coastguard Worker    b.ne 1b
1470*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #4
1471*795d594fSAndroid Build Coastguard Worker    b 1b                        // goto LOOP
1472*795d594fSAndroid Build Coastguard Worker2:  // FOUND_DOUBLE
1473*795d594fSAndroid Build Coastguard Worker    add ip, \stack_ptr, \arg_offset
1474*795d594fSAndroid Build Coastguard Worker    ldr ip, [ip,  #OFFSET_TO_FIRST_ARGUMENT_IN_STACK]
1475*795d594fSAndroid Build Coastguard Worker    str ip, [\regs, \arg_offset]
1476*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #8
1477*795d594fSAndroid Build Coastguard Worker    b 1b
1478*795d594fSAndroid Build Coastguard Worker3:  // FOUND_FLOAT
1479*795d594fSAndroid Build Coastguard Worker    add ip, \stack_ptr, \arg_offset
1480*795d594fSAndroid Build Coastguard Worker    ldr wip, [ip,  #OFFSET_TO_FIRST_ARGUMENT_IN_STACK]
1481*795d594fSAndroid Build Coastguard Worker    str wip, [\regs, \arg_offset]
1482*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #4
1483*795d594fSAndroid Build Coastguard Worker    b 1b
1484*795d594fSAndroid Build Coastguard Worker.endm
1485*795d594fSAndroid Build Coastguard Worker
1486*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object parameter passed in stack
1487*795d594fSAndroid Build Coastguard Worker// in the expected dex register array entry, and in case of object in the
1488*795d594fSAndroid Build Coastguard Worker// expected reference array entry.
1489*795d594fSAndroid Build Coastguard Worker// Uses ip and ip2 as temporary.
1490*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_INTs shorty, arg_offset, regs, refs, stack_ptr, finished
1491*795d594fSAndroid Build Coastguard Worker1: // LOOP
1492*795d594fSAndroid Build Coastguard Worker    ldrb wip, [\shorty], #1       // Load next character in shorty, and increment.
1493*795d594fSAndroid Build Coastguard Worker    cbz wip, \finished            // if (wip == '\0') goto finished
1494*795d594fSAndroid Build Coastguard Worker    cmp wip, #74                  // if (wip == 'J') goto FOUND_LONG
1495*795d594fSAndroid Build Coastguard Worker    b.eq 2f
1496*795d594fSAndroid Build Coastguard Worker    cmp wip, #70                  // if (wip == 'F') goto SKIP_FLOAT
1497*795d594fSAndroid Build Coastguard Worker    b.eq 3f
1498*795d594fSAndroid Build Coastguard Worker    cmp wip, #68                  // if (wip == 'D') goto SKIP_DOUBLE
1499*795d594fSAndroid Build Coastguard Worker    b.eq 4f
1500*795d594fSAndroid Build Coastguard Worker    add ip2, \stack_ptr, \arg_offset
1501*795d594fSAndroid Build Coastguard Worker    ldr wip2, [ip2,  #OFFSET_TO_FIRST_ARGUMENT_IN_STACK]
1502*795d594fSAndroid Build Coastguard Worker    str wip2, [\regs, \arg_offset]
1503*795d594fSAndroid Build Coastguard Worker    cmp wip, #76                  // if (wip != 'L') goto loop
1504*795d594fSAndroid Build Coastguard Worker    b.ne 3f
1505*795d594fSAndroid Build Coastguard Worker    str wip2, [\refs, \arg_offset]
1506*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #4
1507*795d594fSAndroid Build Coastguard Worker    b 1b
1508*795d594fSAndroid Build Coastguard Worker2:  // FOUND_LONG
1509*795d594fSAndroid Build Coastguard Worker    add ip, \stack_ptr, \arg_offset
1510*795d594fSAndroid Build Coastguard Worker    ldr ip, [ip,  #OFFSET_TO_FIRST_ARGUMENT_IN_STACK]
1511*795d594fSAndroid Build Coastguard Worker    str ip, [\regs, \arg_offset]
1512*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #8
1513*795d594fSAndroid Build Coastguard Worker    b 1b
1514*795d594fSAndroid Build Coastguard Worker3:  // SKIP_FLOAT
1515*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #4
1516*795d594fSAndroid Build Coastguard Worker    b 1b
1517*795d594fSAndroid Build Coastguard Worker4:  // SKIP_DOUBLE
1518*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #8
1519*795d594fSAndroid Build Coastguard Worker    b 1b
1520*795d594fSAndroid Build Coastguard Worker.endm
1521*795d594fSAndroid Build Coastguard Worker
1522*795d594fSAndroid Build Coastguard Worker.macro SETUP_REFERENCE_PARAMETER_IN_GPR gpr32, regs, refs, ins, arg_offset, finished
1523*795d594fSAndroid Build Coastguard Worker    str \gpr32, [\regs, \arg_offset]
1524*795d594fSAndroid Build Coastguard Worker    sub \ins, \ins, #1
1525*795d594fSAndroid Build Coastguard Worker    str \gpr32, [\refs, \arg_offset]
1526*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #4
1527*795d594fSAndroid Build Coastguard Worker    cbz \ins, \finished
1528*795d594fSAndroid Build Coastguard Worker.endm
1529*795d594fSAndroid Build Coastguard Worker
1530*795d594fSAndroid Build Coastguard Worker// Uses ip2 as temporary.
1531*795d594fSAndroid Build Coastguard Worker.macro SETUP_REFERENCE_PARAMETERS_IN_STACK regs, refs, ins, stack_ptr, arg_offset
1532*795d594fSAndroid Build Coastguard Worker1:
1533*795d594fSAndroid Build Coastguard Worker    ldr wip2, [\stack_ptr, \arg_offset]
1534*795d594fSAndroid Build Coastguard Worker    sub \ins, \ins, #1
1535*795d594fSAndroid Build Coastguard Worker    str wip2, [\regs, \arg_offset]
1536*795d594fSAndroid Build Coastguard Worker    str wip2, [\refs, \arg_offset]
1537*795d594fSAndroid Build Coastguard Worker    add \arg_offset, \arg_offset, #4
1538*795d594fSAndroid Build Coastguard Worker    cbnz \ins, 1b
1539*795d594fSAndroid Build Coastguard Worker.endm
1540*795d594fSAndroid Build Coastguard Worker
1541*795d594fSAndroid Build Coastguard Worker.macro CHECK_AND_UPDATE_SHARED_MEMORY_METHOD if_hot, if_not_hot
1542*795d594fSAndroid Build Coastguard Worker    ldr wip, [x0, #ART_METHOD_ACCESS_FLAGS_OFFSET]
1543*795d594fSAndroid Build Coastguard Worker    tbz wip, #ART_METHOD_IS_MEMORY_SHARED_FLAG_BIT, \if_hot
1544*795d594fSAndroid Build Coastguard Worker    // Intrinsics are always in the boot image and considered hot.
1545*795d594fSAndroid Build Coastguard Worker    tbnz wip, #ART_METHOD_IS_INTRINSIC_FLAG_BIT, \if_hot
1546*795d594fSAndroid Build Coastguard Worker    ldr wip, [xSELF, #THREAD_SHARED_METHOD_HOTNESS_OFFSET]
1547*795d594fSAndroid Build Coastguard Worker    cbz wip, \if_hot
1548*795d594fSAndroid Build Coastguard Worker    add wip, wip, #-1
1549*795d594fSAndroid Build Coastguard Worker    str wip, [xSELF, #THREAD_SHARED_METHOD_HOTNESS_OFFSET]
1550*795d594fSAndroid Build Coastguard Worker    b \if_not_hot
1551*795d594fSAndroid Build Coastguard Worker.endm
1552*795d594fSAndroid Build Coastguard Worker
1553*795d594fSAndroid Build Coastguard Worker.macro DO_SUSPEND_CHECK continue_label
1554*795d594fSAndroid Build Coastguard Worker    ldr wip, [xSELF, #THREAD_FLAGS_OFFSET]
1555*795d594fSAndroid Build Coastguard Worker    tst wip, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
1556*795d594fSAndroid Build Coastguard Worker    b.eq \continue_label
1557*795d594fSAndroid Build Coastguard Worker    EXPORT_PC
1558*795d594fSAndroid Build Coastguard Worker    bl    art_quick_test_suspend
1559*795d594fSAndroid Build Coastguard Worker.endm
1560*795d594fSAndroid Build Coastguard Worker
1561*795d594fSAndroid Build Coastguard Worker%def entry():
1562*795d594fSAndroid Build Coastguard Worker/*
1563*795d594fSAndroid Build Coastguard Worker * ArtMethod entry point.
1564*795d594fSAndroid Build Coastguard Worker *
1565*795d594fSAndroid Build Coastguard Worker * On entry:
1566*795d594fSAndroid Build Coastguard Worker *  x0   ArtMethod* callee
1567*795d594fSAndroid Build Coastguard Worker *  rest  method parameters
1568*795d594fSAndroid Build Coastguard Worker */
1569*795d594fSAndroid Build Coastguard Worker
1570*795d594fSAndroid Build Coastguard WorkerOAT_ENTRY ExecuteNterpWithClinitImpl
1571*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
1572*795d594fSAndroid Build Coastguard Worker    // For simplicity, we don't do a read barrier here, but instead rely
1573*795d594fSAndroid Build Coastguard Worker    // on art_quick_resolution_trampoline to always have a suspend point before
1574*795d594fSAndroid Build Coastguard Worker    // calling back here.
1575*795d594fSAndroid Build Coastguard Worker    ldr wip, [x0, #ART_METHOD_DECLARING_CLASS_OFFSET]
1576*795d594fSAndroid Build Coastguard Worker    ldr wip2, [ip, #MIRROR_CLASS_STATUS_OFFSET]
1577*795d594fSAndroid Build Coastguard Worker    lsr wip2, wip2, #MIRROR_CLASS_STATUS_SHIFT
1578*795d594fSAndroid Build Coastguard Worker    cmp wip2, #MIRROR_CLASS_STATUS_VISIBLY_INITIALIZED
1579*795d594fSAndroid Build Coastguard Worker    b.hs ExecuteNterpImpl
1580*795d594fSAndroid Build Coastguard Worker    cmp wip2, #MIRROR_CLASS_STATUS_INITIALIZED
1581*795d594fSAndroid Build Coastguard Worker    b.lo .Linitializing_check
1582*795d594fSAndroid Build Coastguard Worker    dmb ish
1583*795d594fSAndroid Build Coastguard Worker    b ExecuteNterpImpl
1584*795d594fSAndroid Build Coastguard Worker.Linitializing_check:
1585*795d594fSAndroid Build Coastguard Worker    cmp wip2, #MIRROR_CLASS_STATUS_INITIALIZING
1586*795d594fSAndroid Build Coastguard Worker    b.lo .Lresolution_trampoline
1587*795d594fSAndroid Build Coastguard Worker    ldr wip2, [ip, #MIRROR_CLASS_CLINIT_THREAD_ID_OFFSET]
1588*795d594fSAndroid Build Coastguard Worker    ldr wip, [xSELF, #THREAD_TID_OFFSET]
1589*795d594fSAndroid Build Coastguard Worker    cmp wip, wip2
1590*795d594fSAndroid Build Coastguard Worker    b.eq ExecuteNterpImpl
1591*795d594fSAndroid Build Coastguard Worker.Lresolution_trampoline:
1592*795d594fSAndroid Build Coastguard Worker    b art_quick_resolution_trampoline
1593*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
1594*795d594fSAndroid Build Coastguard Worker    .type EndExecuteNterpWithClinitImpl, #function
1595*795d594fSAndroid Build Coastguard Worker    .hidden EndExecuteNterpWithClinitImpl
1596*795d594fSAndroid Build Coastguard Worker    .global EndExecuteNterpWithClinitImpl
1597*795d594fSAndroid Build Coastguard WorkerEndExecuteNterpWithClinitImpl:
1598*795d594fSAndroid Build Coastguard Worker
1599*795d594fSAndroid Build Coastguard WorkerOAT_ENTRY ExecuteNterpImpl
1600*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
1601*795d594fSAndroid Build Coastguard Worker    sub x16, sp, #STACK_OVERFLOW_RESERVED_BYTES
1602*795d594fSAndroid Build Coastguard Worker    ldr wzr, [x16]
1603*795d594fSAndroid Build Coastguard Worker    /* Spill callee save regs */
1604*795d594fSAndroid Build Coastguard Worker    SPILL_ALL_CALLEE_SAVES
1605*795d594fSAndroid Build Coastguard Worker
1606*795d594fSAndroid Build Coastguard Worker    ldr xPC, [x0, #ART_METHOD_DATA_OFFSET_64]
1607*795d594fSAndroid Build Coastguard Worker    // Setup the stack for executing the method.
1608*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FRAME xPC, xREFS, xFP, CFI_REFS, load_ins=1
1609*795d594fSAndroid Build Coastguard Worker
1610*795d594fSAndroid Build Coastguard Worker    // Setup the parameters
1611*795d594fSAndroid Build Coastguard Worker    cbz w15, .Lxmm_setup_finished
1612*795d594fSAndroid Build Coastguard Worker
1613*795d594fSAndroid Build Coastguard Worker    sub ip2, ip, x15
1614*795d594fSAndroid Build Coastguard Worker    ldr w26, [x0, #ART_METHOD_ACCESS_FLAGS_OFFSET]
1615*795d594fSAndroid Build Coastguard Worker    lsl x27, ip2, #2 // x27 is now the offset for inputs into the registers array.
1616*795d594fSAndroid Build Coastguard Worker
1617*795d594fSAndroid Build Coastguard Worker    tbz w26, #ART_METHOD_NTERP_ENTRY_POINT_FAST_PATH_FLAG_BIT, .Lsetup_slow_path
1618*795d594fSAndroid Build Coastguard Worker    // Setup pointer to inputs in FP and pointer to inputs in REFS
1619*795d594fSAndroid Build Coastguard Worker    add x10, xFP, x27
1620*795d594fSAndroid Build Coastguard Worker    add x11, xREFS, x27
1621*795d594fSAndroid Build Coastguard Worker    mov x12, #0
1622*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETER_IN_GPR w1, x10, x11, w15, x12, .Lxmm_setup_finished
1623*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETER_IN_GPR w2, x10, x11, w15, x12, .Lxmm_setup_finished
1624*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETER_IN_GPR w3, x10, x11, w15, x12, .Lxmm_setup_finished
1625*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETER_IN_GPR w4, x10, x11, w15, x12, .Lxmm_setup_finished
1626*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETER_IN_GPR w5, x10, x11, w15, x12, .Lxmm_setup_finished
1627*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETER_IN_GPR w6, x10, x11, w15, x12, .Lxmm_setup_finished
1628*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETER_IN_GPR w7, x10, x11, w15, x12, .Lxmm_setup_finished
1629*795d594fSAndroid Build Coastguard Worker    add x28, x28, #OFFSET_TO_FIRST_ARGUMENT_IN_STACK
1630*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETERS_IN_STACK x10, x11, w15, x28, x12
1631*795d594fSAndroid Build Coastguard Worker    b .Lxmm_setup_finished
1632*795d594fSAndroid Build Coastguard Worker
1633*795d594fSAndroid Build Coastguard Worker.Lsetup_slow_path:
1634*795d594fSAndroid Build Coastguard Worker    // If the method is not static and there is one argument ('this'), we don't need to fetch the
1635*795d594fSAndroid Build Coastguard Worker    // shorty.
1636*795d594fSAndroid Build Coastguard Worker    tbnz w26, #ART_METHOD_IS_STATIC_FLAG_BIT, .Lsetup_with_shorty
1637*795d594fSAndroid Build Coastguard Worker    str w1, [xFP, x27]
1638*795d594fSAndroid Build Coastguard Worker    str w1, [xREFS, x27]
1639*795d594fSAndroid Build Coastguard Worker    cmp w15, #1
1640*795d594fSAndroid Build Coastguard Worker    b.eq .Lxmm_setup_finished
1641*795d594fSAndroid Build Coastguard Worker
1642*795d594fSAndroid Build Coastguard Worker.Lsetup_with_shorty:
1643*795d594fSAndroid Build Coastguard Worker    // TODO: Get shorty in a better way and remove below
1644*795d594fSAndroid Build Coastguard Worker    SPILL_ALL_ARGUMENTS
1645*795d594fSAndroid Build Coastguard Worker    bl NterpGetShorty
1646*795d594fSAndroid Build Coastguard Worker    // Save shorty in callee-save xIBASE.
1647*795d594fSAndroid Build Coastguard Worker    mov xIBASE, x0
1648*795d594fSAndroid Build Coastguard Worker    RESTORE_ALL_ARGUMENTS
1649*795d594fSAndroid Build Coastguard Worker
1650*795d594fSAndroid Build Coastguard Worker    // Setup pointer to inputs in FP and pointer to inputs in REFS
1651*795d594fSAndroid Build Coastguard Worker    add x10, xFP, x27
1652*795d594fSAndroid Build Coastguard Worker    add x11, xREFS, x27
1653*795d594fSAndroid Build Coastguard Worker    mov x12, #0
1654*795d594fSAndroid Build Coastguard Worker
1655*795d594fSAndroid Build Coastguard Worker    add x9, xIBASE, #1  // shorty + 1  ; ie skip return arg character
1656*795d594fSAndroid Build Coastguard Worker    tbnz w26, #ART_METHOD_IS_STATIC_FLAG_BIT, .Lhandle_static_method
1657*795d594fSAndroid Build Coastguard Worker    add x10, x10, #4
1658*795d594fSAndroid Build Coastguard Worker    add x11, x11, #4
1659*795d594fSAndroid Build Coastguard Worker    add x28, x28, #4
1660*795d594fSAndroid Build Coastguard Worker    b .Lcontinue_setup_gprs
1661*795d594fSAndroid Build Coastguard Worker.Lhandle_static_method:
1662*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_GPRS x1, w1, x9, x12, x10, x11, .Lgpr_setup_finished
1663*795d594fSAndroid Build Coastguard Worker.Lcontinue_setup_gprs:
1664*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_GPRS x2, w2, x9, x12, x10, x11, .Lgpr_setup_finished
1665*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_GPRS x3, w3, x9, x12, x10, x11, .Lgpr_setup_finished
1666*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_GPRS x4, w4, x9, x12, x10, x11, .Lgpr_setup_finished
1667*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_GPRS x5, w5, x9, x12, x10, x11, .Lgpr_setup_finished
1668*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_GPRS x6, w6, x9, x12, x10, x11, .Lgpr_setup_finished
1669*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_GPRS x7, w7, x9, x12, x10, x11, .Lgpr_setup_finished
1670*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_INTs x9, x12, x10, x11, x28, .Lgpr_setup_finished
1671*795d594fSAndroid Build Coastguard Worker.Lgpr_setup_finished:
1672*795d594fSAndroid Build Coastguard Worker    add x9, xIBASE, #1  // shorty + 1  ; ie skip return arg character
1673*795d594fSAndroid Build Coastguard Worker    mov x12, #0  // reset counter
1674*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_FPS d0, s0, x9, x12, x10, .Lxmm_setup_finished
1675*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_FPS d1, s1, x9, x12, x10, .Lxmm_setup_finished
1676*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_FPS d2, s2, x9, x12, x10, .Lxmm_setup_finished
1677*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_FPS d3, s3, x9, x12, x10, .Lxmm_setup_finished
1678*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_FPS d4, s4, x9, x12, x10, .Lxmm_setup_finished
1679*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_FPS d5, s5, x9, x12, x10, .Lxmm_setup_finished
1680*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_FPS d6, s6, x9, x12, x10, .Lxmm_setup_finished
1681*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_FPS d7, s7, x9, x12, x10, .Lxmm_setup_finished
1682*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_FPs x9, x12, x10, x28, .Lxmm_setup_finished
1683*795d594fSAndroid Build Coastguard Worker.Lxmm_setup_finished:
1684*795d594fSAndroid Build Coastguard Worker    CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
1685*795d594fSAndroid Build Coastguard Worker
1686*795d594fSAndroid Build Coastguard Worker    // Set rIBASE
1687*795d594fSAndroid Build Coastguard Worker    adr xIBASE, artNterpAsmInstructionStart
1688*795d594fSAndroid Build Coastguard Worker    /* start executing the instruction at xPC */
1689*795d594fSAndroid Build Coastguard Worker    START_EXECUTING_INSTRUCTIONS
1690*795d594fSAndroid Build Coastguard Worker    /* NOTE: no fallthrough */
1691*795d594fSAndroid Build Coastguard Worker    // cfi info continues, and covers the whole nterp implementation.
1692*795d594fSAndroid Build Coastguard Worker    SIZE ExecuteNterpImpl
1693*795d594fSAndroid Build Coastguard Worker
1694*795d594fSAndroid Build Coastguard Worker%def opcode_pre():
1695*795d594fSAndroid Build Coastguard Worker
1696*795d594fSAndroid Build Coastguard Worker%def fetch_from_thread_cache(dest_reg, miss_label):
1697*795d594fSAndroid Build Coastguard Worker   // Fetch some information from the thread cache.
1698*795d594fSAndroid Build Coastguard Worker   // Uses ip and ip2 as temporaries.
1699*795d594fSAndroid Build Coastguard Worker   add      ip, xSELF, #THREAD_INTERPRETER_CACHE_OFFSET       // cache address
1700*795d594fSAndroid Build Coastguard Worker   ubfx     ip2, xPC, #2, #THREAD_INTERPRETER_CACHE_SIZE_LOG2  // entry index
1701*795d594fSAndroid Build Coastguard Worker   add      ip, ip, ip2, lsl #4            // entry address within the cache
1702*795d594fSAndroid Build Coastguard Worker   ldp      ip, ${dest_reg}, [ip]          // entry key (pc) and value (offset)
1703*795d594fSAndroid Build Coastguard Worker   cmp      ip, xPC
1704*795d594fSAndroid Build Coastguard Worker   b.ne     ${miss_label}
1705*795d594fSAndroid Build Coastguard Worker
1706*795d594fSAndroid Build Coastguard Worker%def footer():
1707*795d594fSAndroid Build Coastguard Worker/*
1708*795d594fSAndroid Build Coastguard Worker * ===========================================================================
1709*795d594fSAndroid Build Coastguard Worker *  Common subroutines and data
1710*795d594fSAndroid Build Coastguard Worker * ===========================================================================
1711*795d594fSAndroid Build Coastguard Worker */
1712*795d594fSAndroid Build Coastguard Worker
1713*795d594fSAndroid Build Coastguard Worker    .text
1714*795d594fSAndroid Build Coastguard Worker    .align  2
1715*795d594fSAndroid Build Coastguard Worker
1716*795d594fSAndroid Build Coastguard Worker// Enclose all code below in a symbol (which gets printed in backtraces).
1717*795d594fSAndroid Build Coastguard WorkerNAME_START nterp_helper
1718*795d594fSAndroid Build Coastguard Worker
1719*795d594fSAndroid Build Coastguard Worker// Note: mterp also uses the common_* names below for helpers, but that's OK
1720*795d594fSAndroid Build Coastguard Worker// as the assembler compiled each interpreter separately.
1721*795d594fSAndroid Build Coastguard Workercommon_errDivideByZero:
1722*795d594fSAndroid Build Coastguard Worker    EXPORT_PC
1723*795d594fSAndroid Build Coastguard Worker    bl art_quick_throw_div_zero
1724*795d594fSAndroid Build Coastguard Worker
1725*795d594fSAndroid Build Coastguard Worker// Expect index in w1, length in w3.
1726*795d594fSAndroid Build Coastguard Workercommon_errArrayIndex:
1727*795d594fSAndroid Build Coastguard Worker    EXPORT_PC
1728*795d594fSAndroid Build Coastguard Worker    mov x0, x1
1729*795d594fSAndroid Build Coastguard Worker    mov x1, x3
1730*795d594fSAndroid Build Coastguard Worker    bl art_quick_throw_array_bounds
1731*795d594fSAndroid Build Coastguard Worker
1732*795d594fSAndroid Build Coastguard Workercommon_errNullObject:
1733*795d594fSAndroid Build Coastguard Worker    EXPORT_PC
1734*795d594fSAndroid Build Coastguard Worker    bl art_quick_throw_null_pointer_exception
1735*795d594fSAndroid Build Coastguard Worker
1736*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeStatic:
1737*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_NON_RANGE is_static=1, suffix="invokeStatic"
1738*795d594fSAndroid Build Coastguard Worker
1739*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeStaticRange:
1740*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_RANGE is_static=1, suffix="invokeStatic"
1741*795d594fSAndroid Build Coastguard Worker
1742*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeInstance:
1743*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_NON_RANGE suffix="invokeInstance"
1744*795d594fSAndroid Build Coastguard Worker
1745*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeInstanceRange:
1746*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_RANGE suffix="invokeInstance"
1747*795d594fSAndroid Build Coastguard Worker
1748*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeInterface:
1749*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_NON_RANGE is_interface=1, suffix="invokeInterface"
1750*795d594fSAndroid Build Coastguard Worker
1751*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeInterfaceRange:
1752*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_RANGE is_interface=1, suffix="invokeInterface"
1753*795d594fSAndroid Build Coastguard Worker
1754*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokePolymorphic:
1755*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_NON_RANGE is_polymorphic=1, suffix="invokePolymorphic"
1756*795d594fSAndroid Build Coastguard Worker
1757*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokePolymorphicRange:
1758*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_RANGE is_polymorphic=1, suffix="invokePolymorphic"
1759*795d594fSAndroid Build Coastguard Worker
1760*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeCustom:
1761*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_NON_RANGE is_static=1, is_custom=1, suffix="invokeCustom"
1762*795d594fSAndroid Build Coastguard Worker
1763*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeCustomRange:
1764*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_RANGE is_static=1, is_custom=1, suffix="invokeCustom"
1765*795d594fSAndroid Build Coastguard Worker
1766*795d594fSAndroid Build Coastguard WorkerNterpHandleStringInit:
1767*795d594fSAndroid Build Coastguard Worker   COMMON_INVOKE_NON_RANGE is_string_init=1, suffix="stringInit"
1768*795d594fSAndroid Build Coastguard Worker
1769*795d594fSAndroid Build Coastguard WorkerNterpHandleStringInitRange:
1770*795d594fSAndroid Build Coastguard Worker   COMMON_INVOKE_RANGE is_string_init=1, suffix="stringInit"
1771*795d594fSAndroid Build Coastguard Worker
1772*795d594fSAndroid Build Coastguard WorkerNterpHandleHotnessOverflow:
1773*795d594fSAndroid Build Coastguard Worker    CHECK_AND_UPDATE_SHARED_MEMORY_METHOD if_hot=1f, if_not_hot=5f
1774*795d594fSAndroid Build Coastguard Worker1:
1775*795d594fSAndroid Build Coastguard Worker    mov x1, xPC
1776*795d594fSAndroid Build Coastguard Worker    mov x2, xFP
1777*795d594fSAndroid Build Coastguard Worker    bl nterp_hot_method
1778*795d594fSAndroid Build Coastguard Worker    cbnz x0, 3f
1779*795d594fSAndroid Build Coastguard Worker2:
1780*795d594fSAndroid Build Coastguard Worker    FETCH wINST, 0                      // load wINST
1781*795d594fSAndroid Build Coastguard Worker    GET_INST_OPCODE ip                  // extract opcode from wINST
1782*795d594fSAndroid Build Coastguard Worker    GOTO_OPCODE ip                      // jump to next instruction
1783*795d594fSAndroid Build Coastguard Worker3:
1784*795d594fSAndroid Build Coastguard Worker    // Drop the current frame.
1785*795d594fSAndroid Build Coastguard Worker    ldr ip, [xREFS, #-8]
1786*795d594fSAndroid Build Coastguard Worker    mov sp, ip
1787*795d594fSAndroid Build Coastguard Worker    .cfi_def_cfa sp, CALLEE_SAVES_SIZE
1788*795d594fSAndroid Build Coastguard Worker
1789*795d594fSAndroid Build Coastguard Worker    // The transition frame of type SaveAllCalleeSaves saves x19 and x20,
1790*795d594fSAndroid Build Coastguard Worker    // but not managed ABI. So we need to restore callee-saves of the nterp frame,
1791*795d594fSAndroid Build Coastguard Worker    // and save managed ABI callee saves, which will be restored by the callee upon
1792*795d594fSAndroid Build Coastguard Worker    // return.
1793*795d594fSAndroid Build Coastguard Worker    RESTORE_ALL_CALLEE_SAVES
1794*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME ((CALLEE_SAVES_SIZE) - 16)
1795*795d594fSAndroid Build Coastguard Worker
1796*795d594fSAndroid Build Coastguard Worker    // FP callee-saves
1797*795d594fSAndroid Build Coastguard Worker    stp d8, d9, [sp, #0]
1798*795d594fSAndroid Build Coastguard Worker    stp d10, d11, [sp, #16]
1799*795d594fSAndroid Build Coastguard Worker    stp d12, d13, [sp, #32]
1800*795d594fSAndroid Build Coastguard Worker    stp d14, d15, [sp, #48]
1801*795d594fSAndroid Build Coastguard Worker
1802*795d594fSAndroid Build Coastguard Worker    // GP callee-saves.
1803*795d594fSAndroid Build Coastguard Worker    SAVE_TWO_REGS x21, x22, 64
1804*795d594fSAndroid Build Coastguard Worker    SAVE_TWO_REGS x23, x24, 80
1805*795d594fSAndroid Build Coastguard Worker    SAVE_TWO_REGS x25, x26, 96
1806*795d594fSAndroid Build Coastguard Worker    SAVE_TWO_REGS x27, x28, 112
1807*795d594fSAndroid Build Coastguard Worker    SAVE_TWO_REGS x29, lr, 128
1808*795d594fSAndroid Build Coastguard Worker
1809*795d594fSAndroid Build Coastguard Worker    // Setup the new frame
1810*795d594fSAndroid Build Coastguard Worker    ldr x1, [x0, #OSR_DATA_FRAME_SIZE]
1811*795d594fSAndroid Build Coastguard Worker    // Given stack size contains all callee saved registers, remove them.
1812*795d594fSAndroid Build Coastguard Worker    sub x1, x1, #(CALLEE_SAVES_SIZE - 16)
1813*795d594fSAndroid Build Coastguard Worker
1814*795d594fSAndroid Build Coastguard Worker    // We know x1 cannot be 0, as it at least contains the ArtMethod.
1815*795d594fSAndroid Build Coastguard Worker
1816*795d594fSAndroid Build Coastguard Worker    // Remember CFA in a callee-save register.
1817*795d594fSAndroid Build Coastguard Worker    mov xINST, sp
1818*795d594fSAndroid Build Coastguard Worker    .cfi_def_cfa_register xINST
1819*795d594fSAndroid Build Coastguard Worker
1820*795d594fSAndroid Build Coastguard Worker    sub sp, sp, x1
1821*795d594fSAndroid Build Coastguard Worker
1822*795d594fSAndroid Build Coastguard Worker    add x2, x0, #OSR_DATA_MEMORY
1823*795d594fSAndroid Build Coastguard Worker4:
1824*795d594fSAndroid Build Coastguard Worker    sub x1, x1, #8
1825*795d594fSAndroid Build Coastguard Worker    ldr ip, [x2, x1]
1826*795d594fSAndroid Build Coastguard Worker    str ip, [sp, x1]
1827*795d594fSAndroid Build Coastguard Worker    cbnz x1, 4b
1828*795d594fSAndroid Build Coastguard Worker
1829*795d594fSAndroid Build Coastguard Worker    // Fetch the native PC to jump to and save it in a callee-save register.
1830*795d594fSAndroid Build Coastguard Worker    ldr xFP, [x0, #OSR_DATA_NATIVE_PC]
1831*795d594fSAndroid Build Coastguard Worker
1832*795d594fSAndroid Build Coastguard Worker    // Free the memory holding OSR Data.
1833*795d594fSAndroid Build Coastguard Worker    bl free
1834*795d594fSAndroid Build Coastguard Worker
1835*795d594fSAndroid Build Coastguard Worker    // Jump to the compiled code.
1836*795d594fSAndroid Build Coastguard Worker    br xFP
1837*795d594fSAndroid Build Coastguard Worker5:
1838*795d594fSAndroid Build Coastguard Worker    DO_SUSPEND_CHECK continue_label=2b
1839*795d594fSAndroid Build Coastguard Worker    b 2b
1840*795d594fSAndroid Build Coastguard Worker
1841*795d594fSAndroid Build Coastguard Worker// This is the logical end of ExecuteNterpImpl, where the frame info applies.
1842*795d594fSAndroid Build Coastguard Worker// EndExecuteNterpImpl includes the methods below as we want the runtime to
1843*795d594fSAndroid Build Coastguard Worker// see them as part of the Nterp PCs.
1844*795d594fSAndroid Build Coastguard Worker.cfi_endproc
1845*795d594fSAndroid Build Coastguard Worker
1846*795d594fSAndroid Build Coastguard Workernterp_to_nterp_static_non_range:
1847*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
1848*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FOR_INVOKE
1849*795d594fSAndroid Build Coastguard Worker    SETUP_NON_RANGE_ARGUMENTS_AND_EXECUTE is_static=1, is_string_init=0
1850*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
1851*795d594fSAndroid Build Coastguard Worker
1852*795d594fSAndroid Build Coastguard Workernterp_to_nterp_string_init_non_range:
1853*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
1854*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FOR_INVOKE
1855*795d594fSAndroid Build Coastguard Worker    SETUP_NON_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=1
1856*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
1857*795d594fSAndroid Build Coastguard Worker
1858*795d594fSAndroid Build Coastguard Workernterp_to_nterp_instance_non_range:
1859*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
1860*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FOR_INVOKE
1861*795d594fSAndroid Build Coastguard Worker    SETUP_NON_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=0
1862*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
1863*795d594fSAndroid Build Coastguard Worker
1864*795d594fSAndroid Build Coastguard Workernterp_to_nterp_static_range:
1865*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
1866*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FOR_INVOKE
1867*795d594fSAndroid Build Coastguard Worker    SETUP_RANGE_ARGUMENTS_AND_EXECUTE is_static=1
1868*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
1869*795d594fSAndroid Build Coastguard Worker
1870*795d594fSAndroid Build Coastguard Workernterp_to_nterp_instance_range:
1871*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
1872*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FOR_INVOKE
1873*795d594fSAndroid Build Coastguard Worker    SETUP_RANGE_ARGUMENTS_AND_EXECUTE is_static=0
1874*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
1875*795d594fSAndroid Build Coastguard Worker
1876*795d594fSAndroid Build Coastguard Workernterp_to_nterp_string_init_range:
1877*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
1878*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FOR_INVOKE
1879*795d594fSAndroid Build Coastguard Worker    SETUP_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=1
1880*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
1881*795d594fSAndroid Build Coastguard Worker
1882*795d594fSAndroid Build Coastguard WorkerNAME_END nterp_helper
1883*795d594fSAndroid Build Coastguard Worker
1884*795d594fSAndroid Build Coastguard Worker// This is the end of PCs contained by the OatQuickMethodHeader created for the interpreter
1885*795d594fSAndroid Build Coastguard Worker// entry point.
1886*795d594fSAndroid Build Coastguard Worker    .type EndExecuteNterpImpl, #function
1887*795d594fSAndroid Build Coastguard Worker    .hidden EndExecuteNterpImpl
1888*795d594fSAndroid Build Coastguard Worker    .global EndExecuteNterpImpl
1889*795d594fSAndroid Build Coastguard WorkerEndExecuteNterpImpl:
1890*795d594fSAndroid Build Coastguard Worker
1891*795d594fSAndroid Build Coastguard Worker// Entrypoints into runtime.
1892*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_get_static_field, NterpGetStaticField
1893*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_get_instance_field_offset, NterpGetInstanceFieldOffset
1894*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_filled_new_array, NterpFilledNewArray
1895*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_filled_new_array_range, NterpFilledNewArrayRange
1896*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_get_class, NterpGetClass
1897*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_allocate_object, NterpAllocateObject
1898*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_get_method, NterpGetMethod
1899*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_hot_method, NterpHotMethod
1900*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_load_object, NterpLoadObject
1901*795d594fSAndroid Build Coastguard Worker
1902*795d594fSAndroid Build Coastguard WorkerENTRY nterp_deliver_pending_exception
1903*795d594fSAndroid Build Coastguard Worker    DELIVER_PENDING_EXCEPTION
1904*795d594fSAndroid Build Coastguard WorkerEND nterp_deliver_pending_exception
1905*795d594fSAndroid Build Coastguard Worker
1906*795d594fSAndroid Build Coastguard Worker// gen_mterp.py will inline the following definitions
1907*795d594fSAndroid Build Coastguard Worker// within [ExecuteNterpImpl, EndExecuteNterpImpl).
1908*795d594fSAndroid Build Coastguard Worker%def instruction_end():
1909*795d594fSAndroid Build Coastguard Worker
1910*795d594fSAndroid Build Coastguard Worker    .type artNterpAsmInstructionEnd, #function
1911*795d594fSAndroid Build Coastguard Worker    .hidden artNterpAsmInstructionEnd
1912*795d594fSAndroid Build Coastguard Worker    .global artNterpAsmInstructionEnd
1913*795d594fSAndroid Build Coastguard WorkerartNterpAsmInstructionEnd:
1914*795d594fSAndroid Build Coastguard Worker    // artNterpAsmInstructionEnd is used as landing pad for exception handling.
1915*795d594fSAndroid Build Coastguard Worker    FETCH_INST
1916*795d594fSAndroid Build Coastguard Worker    GET_INST_OPCODE ip
1917*795d594fSAndroid Build Coastguard Worker    GOTO_OPCODE ip
1918*795d594fSAndroid Build Coastguard Worker
1919*795d594fSAndroid Build Coastguard Worker%def instruction_start():
1920*795d594fSAndroid Build Coastguard Worker
1921*795d594fSAndroid Build Coastguard Worker    .type artNterpAsmInstructionStart, #function
1922*795d594fSAndroid Build Coastguard Worker    .hidden artNterpAsmInstructionStart
1923*795d594fSAndroid Build Coastguard Worker    .global artNterpAsmInstructionStart
1924*795d594fSAndroid Build Coastguard WorkerartNterpAsmInstructionStart = .L_op_nop
1925*795d594fSAndroid Build Coastguard Worker    .text
1926*795d594fSAndroid Build Coastguard Worker
1927*795d594fSAndroid Build Coastguard Worker%def opcode_name_prefix():
1928*795d594fSAndroid Build Coastguard Worker%   return "nterp_"
1929*795d594fSAndroid Build Coastguard Worker%def opcode_start():
1930*795d594fSAndroid Build Coastguard Worker    NAME_START nterp_${opcode}
1931*795d594fSAndroid Build Coastguard Worker    # Explicitly restore CFA, just in case the previous opcode clobbered it (by .cfi_def_*).
1932*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA_BREG_PLUS_UCONST CFI_REFS, -8, CALLEE_SAVES_SIZE
1933*795d594fSAndroid Build Coastguard Worker%def opcode_end():
1934*795d594fSAndroid Build Coastguard Worker    NAME_END nterp_${opcode}
1935*795d594fSAndroid Build Coastguard Worker    // Advance to the end of this handler. Causes error if we are past that point.
1936*795d594fSAndroid Build Coastguard Worker    .org nterp_${opcode} + NTERP_HANDLER_SIZE  // ${opcode} handler is too big!
1937*795d594fSAndroid Build Coastguard Worker%def opcode_slow_path_start(name):
1938*795d594fSAndroid Build Coastguard Worker    NAME_START ${name}
1939*795d594fSAndroid Build Coastguard Worker%def opcode_slow_path_end(name):
1940*795d594fSAndroid Build Coastguard Worker    NAME_END ${name}
1941