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