xref: /aosp_15_r20/art/runtime/interpreter/mterp/x86_64ng/main.S (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker%def header():
2*795d594fSAndroid Build Coastguard Worker/*
3*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2019 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/x86_64/asm_support_x86_64.S"
24*795d594fSAndroid Build Coastguard Worker
25*795d594fSAndroid Build Coastguard Worker/**
26*795d594fSAndroid Build Coastguard Worker * x86_64 ABI general notes:
27*795d594fSAndroid Build Coastguard Worker *
28*795d594fSAndroid Build Coastguard Worker * Caller save set:
29*795d594fSAndroid Build Coastguard Worker *    rax, rdx, rcx, rsi, rdi, r8-r11, st(0)-st(7)
30*795d594fSAndroid Build Coastguard Worker * Callee save set:
31*795d594fSAndroid Build Coastguard Worker *    rbx, rbp, r12-r15
32*795d594fSAndroid Build Coastguard Worker * Return regs:
33*795d594fSAndroid Build Coastguard Worker *    32-bit in eax
34*795d594fSAndroid Build Coastguard Worker *    64-bit in rax
35*795d594fSAndroid Build Coastguard Worker *    fp on xmm0
36*795d594fSAndroid Build Coastguard Worker *
37*795d594fSAndroid Build Coastguard Worker * First 8 fp parameters came in xmm0-xmm7.
38*795d594fSAndroid Build Coastguard Worker * First 6 non-fp parameters came in rdi, rsi, rdx, rcx, r8, r9.
39*795d594fSAndroid Build Coastguard Worker * Other parameters passed on stack, pushed right-to-left.  On entry to target, first
40*795d594fSAndroid Build Coastguard Worker * param is at 8(%esp).
41*795d594fSAndroid Build Coastguard Worker *
42*795d594fSAndroid Build Coastguard Worker * Stack must be 16-byte aligned to support SSE in native code.
43*795d594fSAndroid Build Coastguard Worker */
44*795d594fSAndroid Build Coastguard Worker
45*795d594fSAndroid Build Coastguard Worker#define IN_ARG3        %rcx
46*795d594fSAndroid Build Coastguard Worker#define IN_ARG2        %rdx
47*795d594fSAndroid Build Coastguard Worker#define IN_ARG1        %rsi
48*795d594fSAndroid Build Coastguard Worker#define IN_ARG0        %rdi
49*795d594fSAndroid Build Coastguard Worker/* Out Args  */
50*795d594fSAndroid Build Coastguard Worker#define OUT_ARG3       %rcx
51*795d594fSAndroid Build Coastguard Worker#define OUT_ARG2       %rdx
52*795d594fSAndroid Build Coastguard Worker#define OUT_ARG1       %rsi
53*795d594fSAndroid Build Coastguard Worker#define OUT_ARG0       %rdi
54*795d594fSAndroid Build Coastguard Worker#define OUT_32_ARG3    %ecx
55*795d594fSAndroid Build Coastguard Worker#define OUT_32_ARG2    %edx
56*795d594fSAndroid Build Coastguard Worker#define OUT_32_ARG1    %esi
57*795d594fSAndroid Build Coastguard Worker#define OUT_32_ARG0    %edi
58*795d594fSAndroid Build Coastguard Worker#define OUT_FP_ARG1    %xmm1
59*795d594fSAndroid Build Coastguard Worker#define OUT_FP_ARG0    %xmm0
60*795d594fSAndroid Build Coastguard Worker
61*795d594fSAndroid Build Coastguard Worker/*
62*795d594fSAndroid Build Coastguard Worker * single-purpose registers, given names for clarity
63*795d594fSAndroid Build Coastguard Worker */
64*795d594fSAndroid Build Coastguard Worker#define rSELF    %gs
65*795d594fSAndroid Build Coastguard Worker#define rPC      %r12
66*795d594fSAndroid Build Coastguard Worker#define CFI_DEX  12 // DWARF register number of the register holding dex-pc (rPC).
67*795d594fSAndroid Build Coastguard Worker#define CFI_TMP  5  // DWARF register number of the first argument register (rdi).
68*795d594fSAndroid Build Coastguard Worker#define rFP      %r13
69*795d594fSAndroid Build Coastguard Worker#define rINST    %ebx
70*795d594fSAndroid Build Coastguard Worker#define rINSTq   %rbx
71*795d594fSAndroid Build Coastguard Worker#define rINSTw   %bx
72*795d594fSAndroid Build Coastguard Worker#define rINSTbh  %bh
73*795d594fSAndroid Build Coastguard Worker#define rINSTbl  %bl
74*795d594fSAndroid Build Coastguard Worker#define rIBASE   %r14
75*795d594fSAndroid Build Coastguard Worker#define rREFS    %r15
76*795d594fSAndroid Build Coastguard Worker#define rREFS32  %r15d
77*795d594fSAndroid Build Coastguard Worker#define CFI_REFS 15 // DWARF register number of the reference array (r15).
78*795d594fSAndroid Build Coastguard Worker
79*795d594fSAndroid Build Coastguard Worker// Temporary registers while setting up a frame.
80*795d594fSAndroid Build Coastguard Worker#define rNEW_FP   %r8
81*795d594fSAndroid Build Coastguard Worker#define rNEW_REFS %r9
82*795d594fSAndroid Build Coastguard Worker#define rNEW_REFS32 %r9d
83*795d594fSAndroid Build Coastguard Worker#define CFI_NEW_REFS 9
84*795d594fSAndroid Build Coastguard Worker
85*795d594fSAndroid Build Coastguard Worker/*
86*795d594fSAndroid Build Coastguard Worker * Get/set the 32-bit value from a Dalvik register.
87*795d594fSAndroid Build Coastguard Worker */
88*795d594fSAndroid Build Coastguard Worker#define VREG_ADDRESS(_vreg) (rFP,_vreg,4)
89*795d594fSAndroid Build Coastguard Worker#define VREG_HIGH_ADDRESS(_vreg) 4(rFP,_vreg,4)
90*795d594fSAndroid Build Coastguard Worker#define VREG_REF_ADDRESS(_vreg) (rREFS,_vreg,4)
91*795d594fSAndroid Build Coastguard Worker#define VREG_REF_HIGH_ADDRESS(_vreg) 4(rREFS,_vreg,4)
92*795d594fSAndroid Build Coastguard Worker
93*795d594fSAndroid Build Coastguard Worker// Includes the return address implictly pushed on stack by 'call'.
94*795d594fSAndroid Build Coastguard Worker#define CALLEE_SAVES_SIZE (6 * 8 + 4 * 8 + 1 * 8)
95*795d594fSAndroid Build Coastguard Worker
96*795d594fSAndroid Build Coastguard Worker// +8 for the ArtMethod of the caller.
97*795d594fSAndroid Build Coastguard Worker#define OFFSET_TO_FIRST_ARGUMENT_IN_STACK (CALLEE_SAVES_SIZE + 8)
98*795d594fSAndroid Build Coastguard Worker
99*795d594fSAndroid Build Coastguard Worker/*
100*795d594fSAndroid Build Coastguard Worker * Refresh rINST.
101*795d594fSAndroid Build Coastguard Worker * At enter to handler rINST does not contain the opcode number.
102*795d594fSAndroid Build Coastguard Worker * However some utilities require the full value, so this macro
103*795d594fSAndroid Build Coastguard Worker * restores the opcode number.
104*795d594fSAndroid Build Coastguard Worker */
105*795d594fSAndroid Build Coastguard Worker.macro REFRESH_INST _opnum
106*795d594fSAndroid Build Coastguard Worker    movb    rINSTbl, rINSTbh
107*795d594fSAndroid Build Coastguard Worker    movb    $$\_opnum, rINSTbl
108*795d594fSAndroid Build Coastguard Worker.endm
109*795d594fSAndroid Build Coastguard Worker
110*795d594fSAndroid Build Coastguard Worker/*
111*795d594fSAndroid Build Coastguard Worker * Fetch the next instruction from rPC into rINSTw.  Does not advance rPC.
112*795d594fSAndroid Build Coastguard Worker */
113*795d594fSAndroid Build Coastguard Worker.macro FETCH_INST
114*795d594fSAndroid Build Coastguard Worker    movzwq  (rPC), rINSTq
115*795d594fSAndroid Build Coastguard Worker.endm
116*795d594fSAndroid Build Coastguard Worker
117*795d594fSAndroid Build Coastguard Worker/*
118*795d594fSAndroid Build Coastguard Worker * Remove opcode from rINST, compute the address of handler and jump to it.
119*795d594fSAndroid Build Coastguard Worker */
120*795d594fSAndroid Build Coastguard Worker.macro GOTO_NEXT
121*795d594fSAndroid Build Coastguard Worker    movzx   rINSTbl,%ecx
122*795d594fSAndroid Build Coastguard Worker    movzbl  rINSTbh,rINST
123*795d594fSAndroid Build Coastguard Worker    shll    MACRO_LITERAL(${handler_size_bits}), %ecx
124*795d594fSAndroid Build Coastguard Worker    addq    rIBASE, %rcx
125*795d594fSAndroid Build Coastguard Worker    jmp     *%rcx
126*795d594fSAndroid Build Coastguard Worker.endm
127*795d594fSAndroid Build Coastguard Worker
128*795d594fSAndroid Build Coastguard Worker/*
129*795d594fSAndroid Build Coastguard Worker * Advance rPC by instruction count.
130*795d594fSAndroid Build Coastguard Worker */
131*795d594fSAndroid Build Coastguard Worker.macro ADVANCE_PC _count
132*795d594fSAndroid Build Coastguard Worker    leaq    2*\_count(rPC), rPC
133*795d594fSAndroid Build Coastguard Worker.endm
134*795d594fSAndroid Build Coastguard Worker
135*795d594fSAndroid Build Coastguard Worker/*
136*795d594fSAndroid Build Coastguard Worker * Advance rPC by instruction count, fetch instruction and jump to handler.
137*795d594fSAndroid Build Coastguard Worker */
138*795d594fSAndroid Build Coastguard Worker.macro ADVANCE_PC_FETCH_AND_GOTO_NEXT _count
139*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC \_count
140*795d594fSAndroid Build Coastguard Worker    FETCH_INST
141*795d594fSAndroid Build Coastguard Worker    GOTO_NEXT
142*795d594fSAndroid Build Coastguard Worker.endm
143*795d594fSAndroid Build Coastguard Worker
144*795d594fSAndroid Build Coastguard Worker.macro GET_VREG _reg _vreg
145*795d594fSAndroid Build Coastguard Worker    movl    VREG_ADDRESS(\_vreg), \_reg
146*795d594fSAndroid Build Coastguard Worker.endm
147*795d594fSAndroid Build Coastguard Worker
148*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_OBJECT _reg _vreg
149*795d594fSAndroid Build Coastguard Worker    movl    VREG_REF_ADDRESS(\_vreg), \_reg
150*795d594fSAndroid Build Coastguard Worker.endm
151*795d594fSAndroid Build Coastguard Worker
152*795d594fSAndroid Build Coastguard Worker/* Read wide value. */
153*795d594fSAndroid Build Coastguard Worker.macro GET_WIDE_VREG _reg _vreg
154*795d594fSAndroid Build Coastguard Worker    movq    VREG_ADDRESS(\_vreg), \_reg
155*795d594fSAndroid Build Coastguard Worker.endm
156*795d594fSAndroid Build Coastguard Worker
157*795d594fSAndroid Build Coastguard Worker.macro SET_VREG _reg _vreg
158*795d594fSAndroid Build Coastguard Worker    movl    \_reg, VREG_ADDRESS(\_vreg)
159*795d594fSAndroid Build Coastguard Worker    movl    MACRO_LITERAL(0), VREG_REF_ADDRESS(\_vreg)
160*795d594fSAndroid Build Coastguard Worker.endm
161*795d594fSAndroid Build Coastguard Worker
162*795d594fSAndroid Build Coastguard Worker/* Write wide value. reg is clobbered. */
163*795d594fSAndroid Build Coastguard Worker.macro SET_WIDE_VREG _reg _vreg
164*795d594fSAndroid Build Coastguard Worker    movq    \_reg, VREG_ADDRESS(\_vreg)
165*795d594fSAndroid Build Coastguard Worker    xorq    \_reg, \_reg
166*795d594fSAndroid Build Coastguard Worker    movq    \_reg, VREG_REF_ADDRESS(\_vreg)
167*795d594fSAndroid Build Coastguard Worker.endm
168*795d594fSAndroid Build Coastguard Worker
169*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_OBJECT _reg _vreg
170*795d594fSAndroid Build Coastguard Worker    movl    \_reg, VREG_ADDRESS(\_vreg)
171*795d594fSAndroid Build Coastguard Worker    movl    \_reg, VREG_REF_ADDRESS(\_vreg)
172*795d594fSAndroid Build Coastguard Worker.endm
173*795d594fSAndroid Build Coastguard Worker
174*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_HIGH _reg _vreg
175*795d594fSAndroid Build Coastguard Worker    movl    VREG_HIGH_ADDRESS(\_vreg), \_reg
176*795d594fSAndroid Build Coastguard Worker.endm
177*795d594fSAndroid Build Coastguard Worker
178*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_HIGH _reg _vreg
179*795d594fSAndroid Build Coastguard Worker    movl    \_reg, VREG_HIGH_ADDRESS(\_vreg)
180*795d594fSAndroid Build Coastguard Worker    movl    MACRO_LITERAL(0), VREG_REF_HIGH_ADDRESS(\_vreg)
181*795d594fSAndroid Build Coastguard Worker.endm
182*795d594fSAndroid Build Coastguard Worker
183*795d594fSAndroid Build Coastguard Worker.macro CLEAR_REF _vreg
184*795d594fSAndroid Build Coastguard Worker    movl    MACRO_LITERAL(0), VREG_REF_ADDRESS(\_vreg)
185*795d594fSAndroid Build Coastguard Worker.endm
186*795d594fSAndroid Build Coastguard Worker
187*795d594fSAndroid Build Coastguard Worker.macro CLEAR_WIDE_REF _vreg
188*795d594fSAndroid Build Coastguard Worker    movl    MACRO_LITERAL(0), VREG_REF_ADDRESS(\_vreg)
189*795d594fSAndroid Build Coastguard Worker    movl    MACRO_LITERAL(0), VREG_REF_HIGH_ADDRESS(\_vreg)
190*795d594fSAndroid Build Coastguard Worker.endm
191*795d594fSAndroid Build Coastguard Worker
192*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_XMMs _xmmreg _vreg
193*795d594fSAndroid Build Coastguard Worker    movss VREG_ADDRESS(\_vreg), \_xmmreg
194*795d594fSAndroid Build Coastguard Worker.endm
195*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_XMMd _xmmreg _vreg
196*795d594fSAndroid Build Coastguard Worker    movsd VREG_ADDRESS(\_vreg), \_xmmreg
197*795d594fSAndroid Build Coastguard Worker.endm
198*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_XMMs _xmmreg _vreg
199*795d594fSAndroid Build Coastguard Worker    movss \_xmmreg, VREG_ADDRESS(\_vreg)
200*795d594fSAndroid Build Coastguard Worker.endm
201*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_XMMd _xmmreg _vreg
202*795d594fSAndroid Build Coastguard Worker    movsd \_xmmreg, VREG_ADDRESS(\_vreg)
203*795d594fSAndroid Build Coastguard Worker.endm
204*795d594fSAndroid Build Coastguard Worker
205*795d594fSAndroid Build Coastguard Worker// An assembly entry for nterp.
206*795d594fSAndroid Build Coastguard Worker.macro OAT_ENTRY name
207*795d594fSAndroid Build Coastguard Worker    FUNCTION_TYPE(\name)
208*795d594fSAndroid Build Coastguard Worker    ASM_HIDDEN SYMBOL(\name)
209*795d594fSAndroid Build Coastguard Worker    .global SYMBOL(\name)
210*795d594fSAndroid Build Coastguard Worker    .balign 16
211*795d594fSAndroid Build Coastguard WorkerSYMBOL(\name):
212*795d594fSAndroid Build Coastguard Worker.endm
213*795d594fSAndroid Build Coastguard Worker
214*795d594fSAndroid Build Coastguard Worker.macro ENTRY name
215*795d594fSAndroid Build Coastguard Worker    .text
216*795d594fSAndroid Build Coastguard Worker    ASM_HIDDEN SYMBOL(\name)
217*795d594fSAndroid Build Coastguard Worker    .global SYMBOL(\name)
218*795d594fSAndroid Build Coastguard Worker    FUNCTION_TYPE(\name)
219*795d594fSAndroid Build Coastguard WorkerSYMBOL(\name):
220*795d594fSAndroid Build Coastguard Worker.endm
221*795d594fSAndroid Build Coastguard Worker
222*795d594fSAndroid Build Coastguard Worker.macro END name
223*795d594fSAndroid Build Coastguard Worker    SIZE(\name)
224*795d594fSAndroid Build Coastguard Worker.endm
225*795d594fSAndroid Build Coastguard Worker
226*795d594fSAndroid Build Coastguard Worker// Macro for defining entrypoints into runtime. We don't need to save registers
227*795d594fSAndroid Build Coastguard Worker// (we're not holding references there), but there is no
228*795d594fSAndroid Build Coastguard Worker// kDontSave runtime method. So just use the kSaveRefsOnly runtime method.
229*795d594fSAndroid Build Coastguard Worker.macro NTERP_TRAMPOLINE name, helper
230*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION \name
231*795d594fSAndroid Build Coastguard Worker  SETUP_SAVE_REFS_ONLY_FRAME
232*795d594fSAndroid Build Coastguard Worker  call \helper
233*795d594fSAndroid Build Coastguard Worker  RESTORE_SAVE_REFS_ONLY_FRAME
234*795d594fSAndroid Build Coastguard Worker  cmpq LITERAL(0), %gs:THREAD_EXCEPTION_OFFSET
235*795d594fSAndroid Build Coastguard Worker  jne nterp_deliver_pending_exception
236*795d594fSAndroid Build Coastguard Worker  ret
237*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION \name
238*795d594fSAndroid Build Coastguard Worker.endm
239*795d594fSAndroid Build Coastguard Worker
240*795d594fSAndroid Build Coastguard Worker.macro CLEAR_VOLATILE_MARKER reg
241*795d594fSAndroid Build Coastguard Worker  andq MACRO_LITERAL(-2), \reg
242*795d594fSAndroid Build Coastguard Worker.endm
243*795d594fSAndroid Build Coastguard Worker
244*795d594fSAndroid Build Coastguard Worker.macro EXPORT_PC
245*795d594fSAndroid Build Coastguard Worker    movq    rPC, -16(rREFS)
246*795d594fSAndroid Build Coastguard Worker.endm
247*795d594fSAndroid Build Coastguard Worker
248*795d594fSAndroid Build Coastguard Worker
249*795d594fSAndroid Build Coastguard Worker.macro BRANCH
250*795d594fSAndroid Build Coastguard Worker    leaq    (rPC, rINSTq, 2), rPC
251*795d594fSAndroid Build Coastguard Worker    // Update method counter and do a suspend check if the branch is negative or zero.
252*795d594fSAndroid Build Coastguard Worker    testq rINSTq, rINSTq
253*795d594fSAndroid Build Coastguard Worker    jle 3f
254*795d594fSAndroid Build Coastguard Worker2:  // We use 2 and not 1 for this local label as the users of the BRANCH macro have a 1 label.
255*795d594fSAndroid Build Coastguard Worker    FETCH_INST
256*795d594fSAndroid Build Coastguard Worker    GOTO_NEXT
257*795d594fSAndroid Build Coastguard Worker3:
258*795d594fSAndroid Build Coastguard Worker    movq (%rsp), %rdi
259*795d594fSAndroid Build Coastguard Worker    movzwl ART_METHOD_HOTNESS_COUNT_OFFSET(%rdi), %esi
260*795d594fSAndroid Build Coastguard Worker#if (NTERP_HOTNESS_VALUE != 0)
261*795d594fSAndroid Build Coastguard Worker#error Expected 0 for hotness value
262*795d594fSAndroid Build Coastguard Worker#endif
263*795d594fSAndroid Build Coastguard Worker    // If the counter is at zero, handle this in the runtime.
264*795d594fSAndroid Build Coastguard Worker    testw %si, %si
265*795d594fSAndroid Build Coastguard Worker    je NterpHandleHotnessOverflow
266*795d594fSAndroid Build Coastguard Worker    // Update counter.
267*795d594fSAndroid Build Coastguard Worker    addl $$-1, %esi
268*795d594fSAndroid Build Coastguard Worker    movw %si, ART_METHOD_HOTNESS_COUNT_OFFSET(%rdi)
269*795d594fSAndroid Build Coastguard Worker    DO_SUSPEND_CHECK continue_label=2b
270*795d594fSAndroid Build Coastguard Worker    jmp 2b
271*795d594fSAndroid Build Coastguard Worker.endm
272*795d594fSAndroid Build Coastguard Worker
273*795d594fSAndroid Build Coastguard Worker// Expects:
274*795d594fSAndroid Build Coastguard Worker// - r10, and r11 to be available.
275*795d594fSAndroid Build Coastguard Worker// Outputs:
276*795d594fSAndroid Build Coastguard Worker// - \registers contains the dex registers size
277*795d594fSAndroid Build Coastguard Worker// - \outs contains the outs size
278*795d594fSAndroid Build Coastguard Worker// - if load_ins is 1, \ins contains the ins
279*795d594fSAndroid Build Coastguard Worker// - \code_item is replace with a pointer to the instructions
280*795d594fSAndroid Build Coastguard Worker.macro FETCH_CODE_ITEM_INFO code_item, registers, outs, ins, load_ins
281*795d594fSAndroid Build Coastguard Worker    // Fetch dex register size.
282*795d594fSAndroid Build Coastguard Worker    movzwl CODE_ITEM_REGISTERS_SIZE_OFFSET(\code_item), \registers
283*795d594fSAndroid Build Coastguard Worker    // Fetch outs size.
284*795d594fSAndroid Build Coastguard Worker    movzwl CODE_ITEM_OUTS_SIZE_OFFSET(\code_item), \outs
285*795d594fSAndroid Build Coastguard Worker    .if \load_ins
286*795d594fSAndroid Build Coastguard Worker    movzwl CODE_ITEM_INS_SIZE_OFFSET(\code_item), \ins
287*795d594fSAndroid Build Coastguard Worker    .endif
288*795d594fSAndroid Build Coastguard Worker    addq $$CODE_ITEM_INSNS_OFFSET, \code_item
289*795d594fSAndroid Build Coastguard Worker.endm
290*795d594fSAndroid Build Coastguard Worker
291*795d594fSAndroid Build Coastguard Worker// Setup the stack to start executing the method. Expects:
292*795d594fSAndroid Build Coastguard Worker// - rdi to contain the ArtMethod
293*795d594fSAndroid Build Coastguard Worker// - rbx, r10, r11 to be available.
294*795d594fSAndroid Build Coastguard Worker//
295*795d594fSAndroid Build Coastguard Worker// Outputs
296*795d594fSAndroid Build Coastguard Worker// - rbx contains the dex registers size
297*795d594fSAndroid Build Coastguard Worker// - r11 contains the old stack pointer.
298*795d594fSAndroid Build Coastguard Worker// - \code_item is replace with a pointer to the instructions
299*795d594fSAndroid Build Coastguard Worker// - if load_ins is 1, r14 contains the ins
300*795d594fSAndroid Build Coastguard Worker.macro SETUP_STACK_FRAME code_item, refs, refs32, fp, cfi_refs, load_ins
301*795d594fSAndroid Build Coastguard Worker    FETCH_CODE_ITEM_INFO \code_item, %ebx, \refs32, %r14d, \load_ins
302*795d594fSAndroid Build Coastguard Worker
303*795d594fSAndroid Build Coastguard Worker    // Compute required frame size for dex registers: ((2 * ebx) + refs)
304*795d594fSAndroid Build Coastguard Worker    leaq (\refs, %rbx, 2), %r11
305*795d594fSAndroid Build Coastguard Worker    salq $$2, %r11
306*795d594fSAndroid Build Coastguard Worker
307*795d594fSAndroid Build Coastguard Worker    // Compute new stack pointer in r10: add 24 for saving the previous frame,
308*795d594fSAndroid Build Coastguard Worker    // pc, and method being executed.
309*795d594fSAndroid Build Coastguard Worker    leaq -24(%rsp), %r10
310*795d594fSAndroid Build Coastguard Worker    subq %r11, %r10
311*795d594fSAndroid Build Coastguard Worker    // Alignment
312*795d594fSAndroid Build Coastguard Worker    // Note: There may be two pieces of alignment but there is no need to align
313*795d594fSAndroid Build Coastguard Worker    // out args to `kPointerSize` separately before aligning to kStackAlignment.
314*795d594fSAndroid Build Coastguard Worker    andq $$-16, %r10
315*795d594fSAndroid Build Coastguard Worker
316*795d594fSAndroid Build Coastguard Worker    // Set reference and dex registers, align to pointer size for previous frame and dex pc.
317*795d594fSAndroid Build Coastguard Worker    leaq 24 + 4(%r10, \refs, 4), \refs
318*795d594fSAndroid Build Coastguard Worker    andq LITERAL(-__SIZEOF_POINTER__), \refs
319*795d594fSAndroid Build Coastguard Worker    leaq (\refs, %rbx, 4), \fp
320*795d594fSAndroid Build Coastguard Worker
321*795d594fSAndroid Build Coastguard Worker    // Now setup the stack pointer.
322*795d594fSAndroid Build Coastguard Worker    movq %rsp, %r11
323*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA_REGISTER(r11)
324*795d594fSAndroid Build Coastguard Worker    movq %r10, %rsp
325*795d594fSAndroid Build Coastguard Worker    movq %r11, -8(\refs)
326*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA_BREG_PLUS_UCONST \cfi_refs, -8, ((6 + 4 + 1) * 8)
327*795d594fSAndroid Build Coastguard Worker
328*795d594fSAndroid Build Coastguard Worker    // Put nulls in reference frame.
329*795d594fSAndroid Build Coastguard Worker    testl %ebx, %ebx
330*795d594fSAndroid Build Coastguard Worker    je 2f
331*795d594fSAndroid Build Coastguard Worker    movq \refs, %r10
332*795d594fSAndroid Build Coastguard Worker1:
333*795d594fSAndroid Build Coastguard Worker    movl $$0, (%r10)
334*795d594fSAndroid Build Coastguard Worker    addq $$4, %r10
335*795d594fSAndroid Build Coastguard Worker    cmpq %r10, \fp
336*795d594fSAndroid Build Coastguard Worker    jne 1b
337*795d594fSAndroid Build Coastguard Worker2:
338*795d594fSAndroid Build Coastguard Worker    // Save the ArtMethod.
339*795d594fSAndroid Build Coastguard Worker    movq %rdi, (%rsp)
340*795d594fSAndroid Build Coastguard Worker.endm
341*795d594fSAndroid Build Coastguard Worker
342*795d594fSAndroid Build Coastguard Worker// Puts the next floating point argument into the expected register,
343*795d594fSAndroid Build Coastguard Worker// fetching values based on a non-range invoke.
344*795d594fSAndroid Build Coastguard Worker// Uses rax as temporary.
345*795d594fSAndroid Build Coastguard Worker//
346*795d594fSAndroid Build Coastguard Worker// TODO: We could simplify a lot of code by loading the G argument into
347*795d594fSAndroid Build Coastguard Worker// the "inst" register. Given that we enter the handler with "1(rPC)" in
348*795d594fSAndroid Build Coastguard Worker// the rINST, we can just add rINST<<16 to the args and we don't even
349*795d594fSAndroid Build Coastguard Worker// need to pass "arg_index" around.
350*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_SHORTY_LOADING_XMMS xmm_reg, inst, shorty, arg_index, finished
351*795d594fSAndroid Build Coastguard Worker1: // LOOP
352*795d594fSAndroid Build Coastguard Worker    movb (REG_VAR(shorty)), %al             // bl := *shorty
353*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(shorty)  // shorty++
354*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(0), %al              // if (al == '\0') goto finished
355*795d594fSAndroid Build Coastguard Worker    je VAR(finished)
356*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(68), %al             // if (al == 'D') goto FOUND_DOUBLE
357*795d594fSAndroid Build Coastguard Worker    je 2f
358*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(70), %al             // if (al == 'F') goto FOUND_FLOAT
359*795d594fSAndroid Build Coastguard Worker    je 3f
360*795d594fSAndroid Build Coastguard Worker    shrq MACRO_LITERAL(4), REG_VAR(inst)
361*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
362*795d594fSAndroid Build Coastguard Worker    //  Handle extra argument in arg array taken by a long.
363*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(74), %al   // if (al != 'J') goto LOOP
364*795d594fSAndroid Build Coastguard Worker    jne 1b
365*795d594fSAndroid Build Coastguard Worker    shrq MACRO_LITERAL(4), REG_VAR(inst)
366*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
367*795d594fSAndroid Build Coastguard Worker    jmp 1b                        // goto LOOP
368*795d594fSAndroid Build Coastguard Worker2:  // FOUND_DOUBLE
369*795d594fSAndroid Build Coastguard Worker    subq MACRO_LITERAL(8), %rsp
370*795d594fSAndroid Build Coastguard Worker    movq REG_VAR(inst), %rax
371*795d594fSAndroid Build Coastguard Worker    andq MACRO_LITERAL(0xf), %rax
372*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %rax
373*795d594fSAndroid Build Coastguard Worker    movl %eax, (%rsp)
374*795d594fSAndroid Build Coastguard Worker    shrq MACRO_LITERAL(4), REG_VAR(inst)
375*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
376*795d594fSAndroid Build Coastguard Worker    cmpq MACRO_LITERAL(4), REG_VAR(arg_index)
377*795d594fSAndroid Build Coastguard Worker    je 5f
378*795d594fSAndroid Build Coastguard Worker    movq REG_VAR(inst), %rax
379*795d594fSAndroid Build Coastguard Worker    andq MACRO_LITERAL(0xf), %rax
380*795d594fSAndroid Build Coastguard Worker    shrq MACRO_LITERAL(4), REG_VAR(inst)
381*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
382*795d594fSAndroid Build Coastguard Worker    jmp 6f
383*795d594fSAndroid Build Coastguard Worker5:
384*795d594fSAndroid Build Coastguard Worker    movzbl 1(rPC), %eax
385*795d594fSAndroid Build Coastguard Worker    andq MACRO_LITERAL(0xf), %rax
386*795d594fSAndroid Build Coastguard Worker6:
387*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %rax
388*795d594fSAndroid Build Coastguard Worker    movl %eax, 4(%rsp)
389*795d594fSAndroid Build Coastguard Worker    movsd (%rsp), REG_VAR(xmm_reg)
390*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(8), %rsp
391*795d594fSAndroid Build Coastguard Worker    jmp 4f
392*795d594fSAndroid Build Coastguard Worker3:  // FOUND_FLOAT
393*795d594fSAndroid Build Coastguard Worker    cmpq MACRO_LITERAL(4), REG_VAR(arg_index)
394*795d594fSAndroid Build Coastguard Worker    je 7f
395*795d594fSAndroid Build Coastguard Worker    movq REG_VAR(inst), %rax
396*795d594fSAndroid Build Coastguard Worker    andq MACRO_LITERAL(0xf), %rax
397*795d594fSAndroid Build Coastguard Worker    shrq MACRO_LITERAL(4), REG_VAR(inst)
398*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
399*795d594fSAndroid Build Coastguard Worker    jmp 8f
400*795d594fSAndroid Build Coastguard Worker7:
401*795d594fSAndroid Build Coastguard Worker    movzbl 1(rPC), %eax
402*795d594fSAndroid Build Coastguard Worker    andq MACRO_LITERAL(0xf), %rax
403*795d594fSAndroid Build Coastguard Worker8:
404*795d594fSAndroid Build Coastguard Worker    GET_VREG_XMMs REG_VAR(xmm_reg), %rax
405*795d594fSAndroid Build Coastguard Worker4:
406*795d594fSAndroid Build Coastguard Worker.endm
407*795d594fSAndroid Build Coastguard Worker
408*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object argument in the expected register,
409*795d594fSAndroid Build Coastguard Worker// fetching values based on a non-range invoke.
410*795d594fSAndroid Build Coastguard Worker// Uses rax as temporary.
411*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_SHORTY_LOADING_GPRS gpr_reg64, gpr_reg32, inst, shorty, arg_index, finished
412*795d594fSAndroid Build Coastguard Worker1: // LOOP
413*795d594fSAndroid Build Coastguard Worker    movb (REG_VAR(shorty)), %al   // al := *shorty
414*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(shorty)  // shorty++
415*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(0), %al    // if (al == '\0') goto finished
416*795d594fSAndroid Build Coastguard Worker    je  VAR(finished)
417*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(74), %al   // if (al == 'J') goto FOUND_LONG
418*795d594fSAndroid Build Coastguard Worker    je 2f
419*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(70), %al   // if (al == 'F') goto SKIP_FLOAT
420*795d594fSAndroid Build Coastguard Worker    je 3f
421*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(68), %al   // if (al == 'D') goto SKIP_DOUBLE
422*795d594fSAndroid Build Coastguard Worker    je 4f
423*795d594fSAndroid Build Coastguard Worker    cmpq MACRO_LITERAL(4), REG_VAR(arg_index)
424*795d594fSAndroid Build Coastguard Worker    je 7f
425*795d594fSAndroid Build Coastguard Worker    movq REG_VAR(inst), %rax
426*795d594fSAndroid Build Coastguard Worker    andq MACRO_LITERAL(0xf), %rax
427*795d594fSAndroid Build Coastguard Worker    shrq MACRO_LITERAL(4), REG_VAR(inst)
428*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
429*795d594fSAndroid Build Coastguard Worker    jmp 8f
430*795d594fSAndroid Build Coastguard Worker7:
431*795d594fSAndroid Build Coastguard Worker    movzbl 1(rPC), %eax
432*795d594fSAndroid Build Coastguard Worker    andq MACRO_LITERAL(0xf), %rax
433*795d594fSAndroid Build Coastguard Worker8:
434*795d594fSAndroid Build Coastguard Worker    GET_VREG REG_VAR(gpr_reg32), %rax
435*795d594fSAndroid Build Coastguard Worker    jmp 5f
436*795d594fSAndroid Build Coastguard Worker2:  // FOUND_LONG
437*795d594fSAndroid Build Coastguard Worker    subq MACRO_LITERAL(8), %rsp
438*795d594fSAndroid Build Coastguard Worker    movq REG_VAR(inst), %rax
439*795d594fSAndroid Build Coastguard Worker    andq MACRO_LITERAL(0xf), %rax
440*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %rax
441*795d594fSAndroid Build Coastguard Worker    movl %eax, (%rsp)
442*795d594fSAndroid Build Coastguard Worker    shrq MACRO_LITERAL(4), REG_VAR(inst)
443*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
444*795d594fSAndroid Build Coastguard Worker    cmpq MACRO_LITERAL(4), REG_VAR(arg_index)
445*795d594fSAndroid Build Coastguard Worker    je 9f
446*795d594fSAndroid Build Coastguard Worker    movq REG_VAR(inst), %rax
447*795d594fSAndroid Build Coastguard Worker    andq MACRO_LITERAL(0xf), %rax
448*795d594fSAndroid Build Coastguard Worker    shrq MACRO_LITERAL(4), REG_VAR(inst)
449*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
450*795d594fSAndroid Build Coastguard Worker    jmp 10f
451*795d594fSAndroid Build Coastguard Worker9:
452*795d594fSAndroid Build Coastguard Worker    movzbl 1(rPC), %eax
453*795d594fSAndroid Build Coastguard Worker    andq MACRO_LITERAL(0xf), %rax
454*795d594fSAndroid Build Coastguard Worker10:
455*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %rax
456*795d594fSAndroid Build Coastguard Worker    movl %eax, 4(%rsp)
457*795d594fSAndroid Build Coastguard Worker    movq (%rsp), REG_VAR(gpr_reg64)
458*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(8), %rsp
459*795d594fSAndroid Build Coastguard Worker    jmp 5f
460*795d594fSAndroid Build Coastguard Worker3:  // SKIP_FLOAT
461*795d594fSAndroid Build Coastguard Worker    shrq MACRO_LITERAL(4), REG_VAR(inst)
462*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
463*795d594fSAndroid Build Coastguard Worker    jmp 1b
464*795d594fSAndroid Build Coastguard Worker4:  // SKIP_DOUBLE
465*795d594fSAndroid Build Coastguard Worker    shrq MACRO_LITERAL(4), REG_VAR(inst)
466*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
467*795d594fSAndroid Build Coastguard Worker    cmpq MACRO_LITERAL(4), REG_VAR(arg_index)
468*795d594fSAndroid Build Coastguard Worker    je 1b
469*795d594fSAndroid Build Coastguard Worker    shrq MACRO_LITERAL(4), REG_VAR(inst)
470*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
471*795d594fSAndroid Build Coastguard Worker    jmp 1b
472*795d594fSAndroid Build Coastguard Worker5:
473*795d594fSAndroid Build Coastguard Worker.endm
474*795d594fSAndroid Build Coastguard Worker
475*795d594fSAndroid Build Coastguard Worker// Puts the next floating point argument into the expected register,
476*795d594fSAndroid Build Coastguard Worker// fetching values based on a range invoke.
477*795d594fSAndroid Build Coastguard Worker// Uses rax as temporary.
478*795d594fSAndroid Build Coastguard Worker.macro LOOP_RANGE_OVER_SHORTY_LOADING_XMMS xmm_reg, shorty, arg_index, stack_index, finished
479*795d594fSAndroid Build Coastguard Worker1: // LOOP
480*795d594fSAndroid Build Coastguard Worker    movb (REG_VAR(shorty)), %al             // al := *shorty
481*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(shorty)  // shorty++
482*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(0), %al              // if (al == '\0') goto finished
483*795d594fSAndroid Build Coastguard Worker    je VAR(finished)
484*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(68), %al             // if (al == 'D') goto FOUND_DOUBLE
485*795d594fSAndroid Build Coastguard Worker    je 2f
486*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(70), %al             // if (al == 'F') goto FOUND_FLOAT
487*795d594fSAndroid Build Coastguard Worker    je 3f
488*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
489*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(stack_index)
490*795d594fSAndroid Build Coastguard Worker    //  Handle extra argument in arg array taken by a long.
491*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(74), %al   // if (al != 'J') goto LOOP
492*795d594fSAndroid Build Coastguard Worker    jne 1b
493*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
494*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(stack_index)
495*795d594fSAndroid Build Coastguard Worker    jmp 1b                        // goto LOOP
496*795d594fSAndroid Build Coastguard Worker2:  // FOUND_DOUBLE
497*795d594fSAndroid Build Coastguard Worker    GET_VREG_XMMd REG_VAR(xmm_reg), REG_VAR(arg_index)
498*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(arg_index)
499*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(stack_index)
500*795d594fSAndroid Build Coastguard Worker    jmp 4f
501*795d594fSAndroid Build Coastguard Worker3:  // FOUND_FLOAT
502*795d594fSAndroid Build Coastguard Worker    GET_VREG_XMMs REG_VAR(xmm_reg), REG_VAR(arg_index)
503*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
504*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(stack_index)
505*795d594fSAndroid Build Coastguard Worker4:
506*795d594fSAndroid Build Coastguard Worker.endm
507*795d594fSAndroid Build Coastguard Worker
508*795d594fSAndroid Build Coastguard Worker// Puts the next floating point argument into the expected stack slot,
509*795d594fSAndroid Build Coastguard Worker// fetching values based on a range invoke.
510*795d594fSAndroid Build Coastguard Worker// Uses rax as temporary.
511*795d594fSAndroid Build Coastguard Worker//
512*795d594fSAndroid Build Coastguard Worker// TODO: We could just copy all the vregs to the stack slots in a simple loop
513*795d594fSAndroid Build Coastguard Worker// (or REP MOVSD) without looking at the shorty at all. (We could also drop
514*795d594fSAndroid Build Coastguard Worker// the "stack_index" from the macros for loading registers.) We could also do
515*795d594fSAndroid Build Coastguard Worker// that conditionally if argument word count > 6; otherwise we know that all
516*795d594fSAndroid Build Coastguard Worker// args fit into registers.
517*795d594fSAndroid Build Coastguard Worker.macro LOOP_RANGE_OVER_FPs shorty, arg_index, stack_index, finished
518*795d594fSAndroid Build Coastguard Worker1: // LOOP
519*795d594fSAndroid Build Coastguard Worker    movb (REG_VAR(shorty)), %al             // bl := *shorty
520*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(shorty)  // shorty++
521*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(0), %al              // if (al == '\0') goto finished
522*795d594fSAndroid Build Coastguard Worker    je VAR(finished)
523*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(68), %al             // if (al == 'D') goto FOUND_DOUBLE
524*795d594fSAndroid Build Coastguard Worker    je 2f
525*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(70), %al             // if (al == 'F') goto FOUND_FLOAT
526*795d594fSAndroid Build Coastguard Worker    je 3f
527*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
528*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(stack_index)
529*795d594fSAndroid Build Coastguard Worker    //  Handle extra argument in arg array taken by a long.
530*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(74), %al   // if (al != 'J') goto LOOP
531*795d594fSAndroid Build Coastguard Worker    jne 1b
532*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
533*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(stack_index)
534*795d594fSAndroid Build Coastguard Worker    jmp 1b                        // goto LOOP
535*795d594fSAndroid Build Coastguard Worker2:  // FOUND_DOUBLE
536*795d594fSAndroid Build Coastguard Worker    movq (rFP, REG_VAR(arg_index), 4), %rax
537*795d594fSAndroid Build Coastguard Worker    movq %rax, 8(%rsp, REG_VAR(stack_index), 4)
538*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(arg_index)
539*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(stack_index)
540*795d594fSAndroid Build Coastguard Worker    jmp 1b
541*795d594fSAndroid Build Coastguard Worker3:  // FOUND_FLOAT
542*795d594fSAndroid Build Coastguard Worker    movl (rFP, REG_VAR(arg_index), 4), %eax
543*795d594fSAndroid Build Coastguard Worker    movl %eax, 8(%rsp, REG_VAR(stack_index), 4)
544*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
545*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(stack_index)
546*795d594fSAndroid Build Coastguard Worker    jmp 1b
547*795d594fSAndroid Build Coastguard Worker.endm
548*795d594fSAndroid Build Coastguard Worker
549*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object argument in the expected register,
550*795d594fSAndroid Build Coastguard Worker// fetching values based on a range invoke.
551*795d594fSAndroid Build Coastguard Worker// Uses rax as temporary.
552*795d594fSAndroid Build Coastguard Worker.macro LOOP_RANGE_OVER_SHORTY_LOADING_GPRS gpr_reg64, gpr_reg32, shorty, arg_index, stack_index, finished
553*795d594fSAndroid Build Coastguard Worker1: // LOOP
554*795d594fSAndroid Build Coastguard Worker    movb (REG_VAR(shorty)), %al             // al := *shorty
555*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(shorty)  // shorty++
556*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(0), %al    // if (al == '\0') goto finished
557*795d594fSAndroid Build Coastguard Worker    je  VAR(finished)
558*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(74), %al   // if (al == 'J') goto FOUND_LONG
559*795d594fSAndroid Build Coastguard Worker    je 2f
560*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(70), %al   // if (al == 'F') goto SKIP_FLOAT
561*795d594fSAndroid Build Coastguard Worker    je 3f
562*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(68), %al   // if (al == 'D') goto SKIP_DOUBLE
563*795d594fSAndroid Build Coastguard Worker    je 4f
564*795d594fSAndroid Build Coastguard Worker    movl       (rFP, REG_VAR(arg_index), 4), REG_VAR(gpr_reg32)
565*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
566*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(stack_index)
567*795d594fSAndroid Build Coastguard Worker    jmp 5f
568*795d594fSAndroid Build Coastguard Worker2:  // FOUND_LONG
569*795d594fSAndroid Build Coastguard Worker    movq (rFP, REG_VAR(arg_index), 4), REG_VAR(gpr_reg64)
570*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(arg_index)
571*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(stack_index)
572*795d594fSAndroid Build Coastguard Worker    jmp 5f
573*795d594fSAndroid Build Coastguard Worker3:  // SKIP_FLOAT
574*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
575*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(stack_index)
576*795d594fSAndroid Build Coastguard Worker    jmp 1b
577*795d594fSAndroid Build Coastguard Worker4:  // SKIP_DOUBLE
578*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(arg_index)
579*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(stack_index)
580*795d594fSAndroid Build Coastguard Worker    jmp 1b
581*795d594fSAndroid Build Coastguard Worker5:
582*795d594fSAndroid Build Coastguard Worker.endm
583*795d594fSAndroid Build Coastguard Worker
584*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object argument in the expected stack slot,
585*795d594fSAndroid Build Coastguard Worker// fetching values based on a range invoke.
586*795d594fSAndroid Build Coastguard Worker// Uses rax as temporary.
587*795d594fSAndroid Build Coastguard Worker.macro LOOP_RANGE_OVER_INTs shorty, arg_index, stack_index, finished
588*795d594fSAndroid Build Coastguard Worker1: // LOOP
589*795d594fSAndroid Build Coastguard Worker    movb (REG_VAR(shorty)), %al             // al := *shorty
590*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(shorty)  // shorty++
591*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(0), %al    // if (al == '\0') goto finished
592*795d594fSAndroid Build Coastguard Worker    je  VAR(finished)
593*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(74), %al   // if (al == 'J') goto FOUND_LONG
594*795d594fSAndroid Build Coastguard Worker    je 2f
595*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(70), %al   // if (al == 'F') goto SKIP_FLOAT
596*795d594fSAndroid Build Coastguard Worker    je 3f
597*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(68), %al   // if (al == 'D') goto SKIP_DOUBLE
598*795d594fSAndroid Build Coastguard Worker    je 4f
599*795d594fSAndroid Build Coastguard Worker    movl (rFP, REG_VAR(arg_index), 4), %eax
600*795d594fSAndroid Build Coastguard Worker    movl %eax, 8(%rsp, REG_VAR(stack_index), 4)
601*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
602*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(stack_index)
603*795d594fSAndroid Build Coastguard Worker    jmp 1b
604*795d594fSAndroid Build Coastguard Worker2:  // FOUND_LONG
605*795d594fSAndroid Build Coastguard Worker    movq (rFP, REG_VAR(arg_index), 4), %rax
606*795d594fSAndroid Build Coastguard Worker    movq %rax, 8(%rsp, REG_VAR(stack_index), 4)
607*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(arg_index)
608*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(stack_index)
609*795d594fSAndroid Build Coastguard Worker    jmp 1b
610*795d594fSAndroid Build Coastguard Worker3:  // SKIP_FLOAT
611*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
612*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(stack_index)
613*795d594fSAndroid Build Coastguard Worker    jmp 1b
614*795d594fSAndroid Build Coastguard Worker4:  // SKIP_DOUBLE
615*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(arg_index)
616*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(stack_index)
617*795d594fSAndroid Build Coastguard Worker    jmp 1b
618*795d594fSAndroid Build Coastguard Worker.endm
619*795d594fSAndroid Build Coastguard Worker
620*795d594fSAndroid Build Coastguard Worker// Puts the next floating point parameter passed in physical register
621*795d594fSAndroid Build Coastguard Worker// in the expected dex register array entry.
622*795d594fSAndroid Build Coastguard Worker// Uses rax as temporary.
623*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_SHORTY_STORING_XMMS xmm_reg, shorty, arg_index, fp, finished
624*795d594fSAndroid Build Coastguard Worker1: // LOOP
625*795d594fSAndroid Build Coastguard Worker    movb (REG_VAR(shorty)), %al             // al := *shorty
626*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(shorty)  // shorty++
627*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(0), %al              // if (al == '\0') goto finished
628*795d594fSAndroid Build Coastguard Worker    je VAR(finished)
629*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(68), %al             // if (al == 'D') goto FOUND_DOUBLE
630*795d594fSAndroid Build Coastguard Worker    je 2f
631*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(70), %al             // if (al == 'F') goto FOUND_FLOAT
632*795d594fSAndroid Build Coastguard Worker    je 3f
633*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
634*795d594fSAndroid Build Coastguard Worker    //  Handle extra argument in arg array taken by a long.
635*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(74), %al   // if (al != 'J') goto LOOP
636*795d594fSAndroid Build Coastguard Worker    jne 1b
637*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
638*795d594fSAndroid Build Coastguard Worker    jmp 1b                        // goto LOOP
639*795d594fSAndroid Build Coastguard Worker2:  // FOUND_DOUBLE
640*795d594fSAndroid Build Coastguard Worker    movsd REG_VAR(xmm_reg),(REG_VAR(fp), REG_VAR(arg_index), 4)
641*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(arg_index)
642*795d594fSAndroid Build Coastguard Worker    jmp 4f
643*795d594fSAndroid Build Coastguard Worker3:  // FOUND_FLOAT
644*795d594fSAndroid Build Coastguard Worker    movss REG_VAR(xmm_reg), (REG_VAR(fp), REG_VAR(arg_index), 4)
645*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
646*795d594fSAndroid Build Coastguard Worker4:
647*795d594fSAndroid Build Coastguard Worker.endm
648*795d594fSAndroid Build Coastguard Worker
649*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object parameter passed in physical register
650*795d594fSAndroid Build Coastguard Worker// in the expected dex register array entry, and in case of object in the
651*795d594fSAndroid Build Coastguard Worker// expected reference array entry.
652*795d594fSAndroid Build Coastguard Worker// Uses rax as temporary.
653*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_SHORTY_STORING_GPRS gpr_reg64, gpr_reg32, shorty, arg_index, regs, refs, finished
654*795d594fSAndroid Build Coastguard Worker1: // LOOP
655*795d594fSAndroid Build Coastguard Worker    movb (REG_VAR(shorty)), %al             // al := *shorty
656*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(shorty)  // shorty++
657*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(0), %al    // if (al == '\0') goto finished
658*795d594fSAndroid Build Coastguard Worker    je  VAR(finished)
659*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(74), %al   // if (al == 'J') goto FOUND_LONG
660*795d594fSAndroid Build Coastguard Worker    je 2f
661*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(70), %al   // if (al == 'F') goto SKIP_FLOAT
662*795d594fSAndroid Build Coastguard Worker    je 3f
663*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(68), %al   // if (al == 'D') goto SKIP_DOUBLE
664*795d594fSAndroid Build Coastguard Worker    je 4f
665*795d594fSAndroid Build Coastguard Worker    movl REG_VAR(gpr_reg32), (REG_VAR(regs), REG_VAR(arg_index), 4)
666*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(76), %al   // if (al != 'L') goto NOT_REFERENCE
667*795d594fSAndroid Build Coastguard Worker    jne 6f
668*795d594fSAndroid Build Coastguard Worker    movl REG_VAR(gpr_reg32), (REG_VAR(refs), REG_VAR(arg_index), 4)
669*795d594fSAndroid Build Coastguard Worker6:  // NOT_REFERENCE
670*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
671*795d594fSAndroid Build Coastguard Worker    jmp 5f
672*795d594fSAndroid Build Coastguard Worker2:  // FOUND_LONG
673*795d594fSAndroid Build Coastguard Worker    movq REG_VAR(gpr_reg64), (REG_VAR(regs), REG_VAR(arg_index), 4)
674*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(arg_index)
675*795d594fSAndroid Build Coastguard Worker    jmp 5f
676*795d594fSAndroid Build Coastguard Worker3:  // SKIP_FLOAT
677*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
678*795d594fSAndroid Build Coastguard Worker    jmp 1b
679*795d594fSAndroid Build Coastguard Worker4:  // SKIP_DOUBLE
680*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(arg_index)
681*795d594fSAndroid Build Coastguard Worker    jmp 1b
682*795d594fSAndroid Build Coastguard Worker5:
683*795d594fSAndroid Build Coastguard Worker.endm
684*795d594fSAndroid Build Coastguard Worker
685*795d594fSAndroid Build Coastguard Worker// Puts the next floating point parameter passed in stack
686*795d594fSAndroid Build Coastguard Worker// in the expected dex register array entry.
687*795d594fSAndroid Build Coastguard Worker// Uses rax as temporary.
688*795d594fSAndroid Build Coastguard Worker//
689*795d594fSAndroid Build Coastguard Worker// TODO: Or we could just spill regs to the reserved slots in the caller's
690*795d594fSAndroid Build Coastguard Worker// frame and copy all regs in a simple loop. This time, however, we would
691*795d594fSAndroid Build Coastguard Worker// need to look at the shorty anyway to look for the references.
692*795d594fSAndroid Build Coastguard Worker// (The trade-off is different for passing arguments and receiving them.)
693*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_FPs shorty, arg_index, regs, stack_ptr, finished
694*795d594fSAndroid Build Coastguard Worker1: // LOOP
695*795d594fSAndroid Build Coastguard Worker    movb (REG_VAR(shorty)), %al             // al := *shorty
696*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(shorty)  // shorty++
697*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(0), %al              // if (al == '\0') goto finished
698*795d594fSAndroid Build Coastguard Worker    je VAR(finished)
699*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(68), %al             // if (al == 'D') goto FOUND_DOUBLE
700*795d594fSAndroid Build Coastguard Worker    je 2f
701*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(70), %al             // if (al == 'F') goto FOUND_FLOAT
702*795d594fSAndroid Build Coastguard Worker    je 3f
703*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
704*795d594fSAndroid Build Coastguard Worker    //  Handle extra argument in arg array taken by a long.
705*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(74), %al   // if (al != 'J') goto LOOP
706*795d594fSAndroid Build Coastguard Worker    jne 1b
707*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
708*795d594fSAndroid Build Coastguard Worker    jmp 1b                        // goto LOOP
709*795d594fSAndroid Build Coastguard Worker2:  // FOUND_DOUBLE
710*795d594fSAndroid Build Coastguard Worker    movq OFFSET_TO_FIRST_ARGUMENT_IN_STACK(REG_VAR(stack_ptr), REG_VAR(arg_index), 4), %rax
711*795d594fSAndroid Build Coastguard Worker    movq %rax, (REG_VAR(regs), REG_VAR(arg_index), 4)
712*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(arg_index)
713*795d594fSAndroid Build Coastguard Worker    jmp 1b
714*795d594fSAndroid Build Coastguard Worker3:  // FOUND_FLOAT
715*795d594fSAndroid Build Coastguard Worker    movl OFFSET_TO_FIRST_ARGUMENT_IN_STACK(REG_VAR(stack_ptr), REG_VAR(arg_index), 4), %eax
716*795d594fSAndroid Build Coastguard Worker    movl %eax, (REG_VAR(regs), REG_VAR(arg_index), 4)
717*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
718*795d594fSAndroid Build Coastguard Worker    jmp 1b
719*795d594fSAndroid Build Coastguard Worker.endm
720*795d594fSAndroid Build Coastguard Worker
721*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object parameter passed in stack
722*795d594fSAndroid Build Coastguard Worker// in the expected dex register array entry, and in case of object in the
723*795d594fSAndroid Build Coastguard Worker// expected reference array entry.
724*795d594fSAndroid Build Coastguard Worker// Uses rax as temporary.
725*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_INTs shorty, arg_index, regs, refs, stack_ptr, finished
726*795d594fSAndroid Build Coastguard Worker1: // LOOP
727*795d594fSAndroid Build Coastguard Worker    movb (REG_VAR(shorty)), %al             // al := *shorty
728*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(shorty)  // shorty++
729*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(0), %al    // if (al == '\0') goto finished
730*795d594fSAndroid Build Coastguard Worker    je  VAR(finished)
731*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(74), %al   // if (al == 'J') goto FOUND_LONG
732*795d594fSAndroid Build Coastguard Worker    je 2f
733*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(76), %al   // if (al == 'L') goto FOUND_REFERENCE
734*795d594fSAndroid Build Coastguard Worker    je 6f
735*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(70), %al   // if (al == 'F') goto SKIP_FLOAT
736*795d594fSAndroid Build Coastguard Worker    je 3f
737*795d594fSAndroid Build Coastguard Worker    cmpb MACRO_LITERAL(68), %al   // if (al == 'D') goto SKIP_DOUBLE
738*795d594fSAndroid Build Coastguard Worker    je 4f
739*795d594fSAndroid Build Coastguard Worker    movl OFFSET_TO_FIRST_ARGUMENT_IN_STACK(REG_VAR(stack_ptr), REG_VAR(arg_index), 4), %eax
740*795d594fSAndroid Build Coastguard Worker    movl %eax, (REG_VAR(regs), REG_VAR(arg_index), 4)
741*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
742*795d594fSAndroid Build Coastguard Worker    jmp 1b
743*795d594fSAndroid Build Coastguard Worker6:  // FOUND_REFERENCE
744*795d594fSAndroid Build Coastguard Worker    movl OFFSET_TO_FIRST_ARGUMENT_IN_STACK(REG_VAR(stack_ptr), REG_VAR(arg_index), 4), %eax
745*795d594fSAndroid Build Coastguard Worker    movl %eax, (REG_VAR(regs), REG_VAR(arg_index), 4)
746*795d594fSAndroid Build Coastguard Worker    movl %eax, (REG_VAR(refs), REG_VAR(arg_index), 4)
747*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
748*795d594fSAndroid Build Coastguard Worker    jmp 1b
749*795d594fSAndroid Build Coastguard Worker2:  // FOUND_LONG
750*795d594fSAndroid Build Coastguard Worker    movq OFFSET_TO_FIRST_ARGUMENT_IN_STACK(REG_VAR(stack_ptr), REG_VAR(arg_index), 4), %rax
751*795d594fSAndroid Build Coastguard Worker    movq %rax, (REG_VAR(regs), REG_VAR(arg_index), 4)
752*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(arg_index)
753*795d594fSAndroid Build Coastguard Worker    jmp 1b
754*795d594fSAndroid Build Coastguard Worker3:  // SKIP_FLOAT
755*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(1), REG_VAR(arg_index)
756*795d594fSAndroid Build Coastguard Worker    jmp 1b
757*795d594fSAndroid Build Coastguard Worker4:  // SKIP_DOUBLE
758*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(2), REG_VAR(arg_index)
759*795d594fSAndroid Build Coastguard Worker    jmp 1b
760*795d594fSAndroid Build Coastguard Worker.endm
761*795d594fSAndroid Build Coastguard Worker
762*795d594fSAndroid Build Coastguard Worker// Increase method hotness and do suspend check before starting executing the method.
763*795d594fSAndroid Build Coastguard Worker.macro START_EXECUTING_INSTRUCTIONS
764*795d594fSAndroid Build Coastguard Worker   movq (%rsp), %rdi
765*795d594fSAndroid Build Coastguard Worker   movzwl ART_METHOD_HOTNESS_COUNT_OFFSET(%rdi), %esi
766*795d594fSAndroid Build Coastguard Worker#if (NTERP_HOTNESS_VALUE != 0)
767*795d594fSAndroid Build Coastguard Worker#error Expected 0 for hotness value
768*795d594fSAndroid Build Coastguard Worker#endif
769*795d594fSAndroid Build Coastguard Worker   // If the counter is at zero, handle this in the runtime.
770*795d594fSAndroid Build Coastguard Worker   testl %esi, %esi
771*795d594fSAndroid Build Coastguard Worker   je 3f
772*795d594fSAndroid Build Coastguard Worker   // Update counter.
773*795d594fSAndroid Build Coastguard Worker   addl $$-1, %esi
774*795d594fSAndroid Build Coastguard Worker   movw %si, ART_METHOD_HOTNESS_COUNT_OFFSET(%rdi)
775*795d594fSAndroid Build Coastguard Worker1:
776*795d594fSAndroid Build Coastguard Worker   DO_SUSPEND_CHECK continue_label=2f
777*795d594fSAndroid Build Coastguard Worker2:
778*795d594fSAndroid Build Coastguard Worker   FETCH_INST
779*795d594fSAndroid Build Coastguard Worker   GOTO_NEXT
780*795d594fSAndroid Build Coastguard Worker3:
781*795d594fSAndroid Build Coastguard Worker   CHECK_AND_UPDATE_SHARED_MEMORY_METHOD if_hot=4f, if_not_hot=1b
782*795d594fSAndroid Build Coastguard Worker4:
783*795d594fSAndroid Build Coastguard Worker   movq $$0, %rsi
784*795d594fSAndroid Build Coastguard Worker   movq rFP, %rdx
785*795d594fSAndroid Build Coastguard Worker   call nterp_hot_method
786*795d594fSAndroid Build Coastguard Worker   jmp 2b
787*795d594fSAndroid Build Coastguard Worker.endm
788*795d594fSAndroid Build Coastguard Worker
789*795d594fSAndroid Build Coastguard Worker.macro SPILL_ALL_CALLEE_SAVES
790*795d594fSAndroid Build Coastguard Worker    PUSH r15
791*795d594fSAndroid Build Coastguard Worker    PUSH r14
792*795d594fSAndroid Build Coastguard Worker    PUSH r13
793*795d594fSAndroid Build Coastguard Worker    PUSH r12
794*795d594fSAndroid Build Coastguard Worker    PUSH rbp
795*795d594fSAndroid Build Coastguard Worker    PUSH rbx
796*795d594fSAndroid Build Coastguard Worker    SETUP_FP_CALLEE_SAVE_FRAME
797*795d594fSAndroid Build Coastguard Worker.endm
798*795d594fSAndroid Build Coastguard Worker
799*795d594fSAndroid Build Coastguard Worker.macro RESTORE_ALL_CALLEE_SAVES
800*795d594fSAndroid Build Coastguard Worker    RESTORE_FP_CALLEE_SAVE_FRAME
801*795d594fSAndroid Build Coastguard Worker    POP rbx
802*795d594fSAndroid Build Coastguard Worker    POP rbp
803*795d594fSAndroid Build Coastguard Worker    POP r12
804*795d594fSAndroid Build Coastguard Worker    POP r13
805*795d594fSAndroid Build Coastguard Worker    POP r14
806*795d594fSAndroid Build Coastguard Worker    POP r15
807*795d594fSAndroid Build Coastguard Worker.endm
808*795d594fSAndroid Build Coastguard Worker
809*795d594fSAndroid Build Coastguard Worker// Helper to setup the stack after doing a nterp to nterp call. This will setup:
810*795d594fSAndroid Build Coastguard Worker// - rNEW_FP: the new pointer to dex registers
811*795d594fSAndroid Build Coastguard Worker// - rNEW_REFS: the new pointer to references
812*795d594fSAndroid Build Coastguard Worker// - rPC: the new PC pointer to execute
813*795d594fSAndroid Build Coastguard Worker// - edi: number of arguments
814*795d594fSAndroid Build Coastguard Worker// - ecx: first dex register
815*795d594fSAndroid Build Coastguard Worker//
816*795d594fSAndroid Build Coastguard Worker// This helper expects:
817*795d594fSAndroid Build Coastguard Worker// - rax to contain the code item
818*795d594fSAndroid Build Coastguard Worker.macro SETUP_STACK_FOR_INVOKE
819*795d594fSAndroid Build Coastguard Worker   // We do the same stack overflow check as the compiler. See CanMethodUseNterp
820*795d594fSAndroid Build Coastguard Worker   // in how we limit the maximum nterp frame size.
821*795d594fSAndroid Build Coastguard Worker   testq %rax, -STACK_OVERFLOW_RESERVED_BYTES(%rsp)
822*795d594fSAndroid Build Coastguard Worker
823*795d594fSAndroid Build Coastguard Worker   // Spill all callee saves to have a consistent stack frame whether we
824*795d594fSAndroid Build Coastguard Worker   // are called by compiled code or nterp.
825*795d594fSAndroid Build Coastguard Worker   SPILL_ALL_CALLEE_SAVES
826*795d594fSAndroid Build Coastguard Worker
827*795d594fSAndroid Build Coastguard Worker   // Setup the frame.
828*795d594fSAndroid Build Coastguard Worker   SETUP_STACK_FRAME %rax, rNEW_REFS, rNEW_REFS32, rNEW_FP, CFI_NEW_REFS, load_ins=0
829*795d594fSAndroid Build Coastguard Worker   // Make r11 point to the top of the dex register array.
830*795d594fSAndroid Build Coastguard Worker   leaq (rNEW_FP, %rbx, 4), %r11
831*795d594fSAndroid Build Coastguard Worker
832*795d594fSAndroid Build Coastguard Worker   // Fetch instruction information before replacing rPC.
833*795d594fSAndroid Build Coastguard Worker   movzbl 1(rPC), %edi
834*795d594fSAndroid Build Coastguard Worker   movzwl 4(rPC), %ecx
835*795d594fSAndroid Build Coastguard Worker
836*795d594fSAndroid Build Coastguard Worker   // Set the dex pc pointer.
837*795d594fSAndroid Build Coastguard Worker   movq %rax, rPC
838*795d594fSAndroid Build Coastguard Worker   CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
839*795d594fSAndroid Build Coastguard Worker.endm
840*795d594fSAndroid Build Coastguard Worker
841*795d594fSAndroid Build Coastguard Worker// Setup arguments based on a non-range nterp to nterp call, and start executing
842*795d594fSAndroid Build Coastguard Worker// the method. We expect:
843*795d594fSAndroid Build Coastguard Worker// - rNEW_FP: the new pointer to dex registers
844*795d594fSAndroid Build Coastguard Worker// - rNEW_REFS: the new pointer to references
845*795d594fSAndroid Build Coastguard Worker// - rPC: the new PC pointer to execute
846*795d594fSAndroid Build Coastguard Worker// - edi: number of arguments
847*795d594fSAndroid Build Coastguard Worker// - ecx: first dex register
848*795d594fSAndroid Build Coastguard Worker// - r11: top of dex register array
849*795d594fSAndroid Build Coastguard Worker// - esi: receiver if non-static.
850*795d594fSAndroid Build Coastguard Worker.macro SETUP_NON_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=0
851*795d594fSAndroid Build Coastguard Worker   // Now all temporary registers (except r11 containing top of registers array)
852*795d594fSAndroid Build Coastguard Worker   // are available, copy the parameters.
853*795d594fSAndroid Build Coastguard Worker   // /* op vA, vB, {vC...vG} */
854*795d594fSAndroid Build Coastguard Worker   movl %edi, %eax
855*795d594fSAndroid Build Coastguard Worker   shrl $$4, %eax # Number of arguments
856*795d594fSAndroid Build Coastguard Worker   jz 6f  # shl sets the Z flag
857*795d594fSAndroid Build Coastguard Worker   movq MACRO_LITERAL(-1), %r10
858*795d594fSAndroid Build Coastguard Worker   cmpl MACRO_LITERAL(2), %eax
859*795d594fSAndroid Build Coastguard Worker   jl 1f
860*795d594fSAndroid Build Coastguard Worker   je 2f
861*795d594fSAndroid Build Coastguard Worker   cmpl MACRO_LITERAL(4), %eax
862*795d594fSAndroid Build Coastguard Worker   jl 3f
863*795d594fSAndroid Build Coastguard Worker   je 4f
864*795d594fSAndroid Build Coastguard Worker
865*795d594fSAndroid Build Coastguard Worker  // We use a decrementing r10 to store references relative
866*795d594fSAndroid Build Coastguard Worker  // to rNEW_FP and dex registers relative to r11.
867*795d594fSAndroid Build Coastguard Worker  //
868*795d594fSAndroid Build Coastguard Worker  // TODO: We could set up r10 as the number of registers (this can be an additional output from
869*795d594fSAndroid Build Coastguard Worker  // SETUP_STACK_FOR_INVOKE) and then just decrement it by one before copying each arg to
870*795d594fSAndroid Build Coastguard Worker  // (rNEW_FP, r10, 4) and (rNEW_REFS, r10, 4).
871*795d594fSAndroid Build Coastguard Worker  // Maybe even introduce macros NEW_VREG_ADDRESS/NEW_VREG_REF_ADDRESS.
872*795d594fSAndroid Build Coastguard Worker5:
873*795d594fSAndroid Build Coastguard Worker   andq        MACRO_LITERAL(15), %rdi
874*795d594fSAndroid Build Coastguard Worker   GET_VREG_OBJECT %edx, %rdi
875*795d594fSAndroid Build Coastguard Worker   movl        %edx, (rNEW_FP, %r10, 4)
876*795d594fSAndroid Build Coastguard Worker   GET_VREG    %edx, %rdi
877*795d594fSAndroid Build Coastguard Worker   movl        %edx, (%r11, %r10, 4)
878*795d594fSAndroid Build Coastguard Worker   subq        MACRO_LITERAL(1), %r10
879*795d594fSAndroid Build Coastguard Worker4:
880*795d594fSAndroid Build Coastguard Worker   movl        %ecx, %eax
881*795d594fSAndroid Build Coastguard Worker   shrl        MACRO_LITERAL(12), %eax
882*795d594fSAndroid Build Coastguard Worker   GET_VREG_OBJECT %edx, %rax
883*795d594fSAndroid Build Coastguard Worker   movl        %edx, (rNEW_FP, %r10, 4)
884*795d594fSAndroid Build Coastguard Worker   GET_VREG    %edx, %rax
885*795d594fSAndroid Build Coastguard Worker   movl        %edx, (%r11, %r10, 4)
886*795d594fSAndroid Build Coastguard Worker   subq        MACRO_LITERAL(1), %r10
887*795d594fSAndroid Build Coastguard Worker3:
888*795d594fSAndroid Build Coastguard Worker   movl        %ecx, %eax
889*795d594fSAndroid Build Coastguard Worker   shrl        MACRO_LITERAL(8), %eax
890*795d594fSAndroid Build Coastguard Worker   andl        MACRO_LITERAL(0xf), %eax
891*795d594fSAndroid Build Coastguard Worker   GET_VREG_OBJECT %edx, %rax
892*795d594fSAndroid Build Coastguard Worker   movl        %edx, (rNEW_FP, %r10, 4)
893*795d594fSAndroid Build Coastguard Worker   GET_VREG    %edx, %rax
894*795d594fSAndroid Build Coastguard Worker   movl        %edx, (%r11, %r10, 4)
895*795d594fSAndroid Build Coastguard Worker   subq        MACRO_LITERAL(1), %r10
896*795d594fSAndroid Build Coastguard Worker2:
897*795d594fSAndroid Build Coastguard Worker   movl        %ecx, %eax
898*795d594fSAndroid Build Coastguard Worker   shrl        MACRO_LITERAL(4), %eax
899*795d594fSAndroid Build Coastguard Worker   andl        MACRO_LITERAL(0xf), %eax
900*795d594fSAndroid Build Coastguard Worker   GET_VREG_OBJECT %edx, %rax
901*795d594fSAndroid Build Coastguard Worker   movl        %edx, (rNEW_FP, %r10, 4)
902*795d594fSAndroid Build Coastguard Worker   GET_VREG    %edx, %rax
903*795d594fSAndroid Build Coastguard Worker   movl        %edx, (%r11, %r10, 4)
904*795d594fSAndroid Build Coastguard Worker   subq        MACRO_LITERAL(1), %r10
905*795d594fSAndroid Build Coastguard Worker1:
906*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
907*795d594fSAndroid Build Coastguard Worker   // Ignore the first argument
908*795d594fSAndroid Build Coastguard Worker   .elseif \is_static
909*795d594fSAndroid Build Coastguard Worker   movl        %ecx, %eax
910*795d594fSAndroid Build Coastguard Worker   andq        MACRO_LITERAL(0x000f), %rax
911*795d594fSAndroid Build Coastguard Worker   GET_VREG_OBJECT %edx, %rax
912*795d594fSAndroid Build Coastguard Worker   movl        %edx, (rNEW_FP, %r10, 4)
913*795d594fSAndroid Build Coastguard Worker   GET_VREG    %edx, %rax
914*795d594fSAndroid Build Coastguard Worker   movl        %edx, (%r11, %r10, 4)
915*795d594fSAndroid Build Coastguard Worker   .else
916*795d594fSAndroid Build Coastguard Worker   movl        %esi, (rNEW_FP, %r10, 4)
917*795d594fSAndroid Build Coastguard Worker   movl        %esi, (%r11, %r10, 4)
918*795d594fSAndroid Build Coastguard Worker   .endif
919*795d594fSAndroid Build Coastguard Worker
920*795d594fSAndroid Build Coastguard Worker6:
921*795d594fSAndroid Build Coastguard Worker   // Start executing the method.
922*795d594fSAndroid Build Coastguard Worker   movq rNEW_FP, rFP
923*795d594fSAndroid Build Coastguard Worker   movq rNEW_REFS, rREFS
924*795d594fSAndroid Build Coastguard Worker   CFI_DEF_CFA_BREG_PLUS_UCONST CFI_REFS, -8, ((6 + 4 + 1) * 8)
925*795d594fSAndroid Build Coastguard Worker   START_EXECUTING_INSTRUCTIONS
926*795d594fSAndroid Build Coastguard Worker.endm
927*795d594fSAndroid Build Coastguard Worker
928*795d594fSAndroid Build Coastguard Worker// Setup arguments based on a range nterp to nterp call, and start executing
929*795d594fSAndroid Build Coastguard Worker// the method.
930*795d594fSAndroid Build Coastguard Worker.macro SETUP_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=0
931*795d594fSAndroid Build Coastguard Worker   // edi is number of arguments
932*795d594fSAndroid Build Coastguard Worker   // ecx is first register
933*795d594fSAndroid Build Coastguard Worker   movq MACRO_LITERAL(-4), %r10
934*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
935*795d594fSAndroid Build Coastguard Worker   // Ignore the first argument
936*795d594fSAndroid Build Coastguard Worker   subl $$1, %edi
937*795d594fSAndroid Build Coastguard Worker   addl $$1, %ecx
938*795d594fSAndroid Build Coastguard Worker   .elseif !\is_static
939*795d594fSAndroid Build Coastguard Worker   subl $$1, %edi
940*795d594fSAndroid Build Coastguard Worker   addl $$1, %ecx
941*795d594fSAndroid Build Coastguard Worker   .endif
942*795d594fSAndroid Build Coastguard Worker
943*795d594fSAndroid Build Coastguard Worker   testl %edi, %edi
944*795d594fSAndroid Build Coastguard Worker   je 2f
945*795d594fSAndroid Build Coastguard Worker   leaq  (rREFS, %rcx, 4), %rax  # pointer to first argument in reference array
946*795d594fSAndroid Build Coastguard Worker   leaq  (%rax, %rdi, 4), %rax   # pointer to last argument in reference array
947*795d594fSAndroid Build Coastguard Worker   leaq  (rFP, %rcx, 4), %rcx    # pointer to first argument in register array
948*795d594fSAndroid Build Coastguard Worker   leaq  (%rcx, %rdi, 4), %rdi   # pointer to last argument in register array
949*795d594fSAndroid Build Coastguard Worker   // TODO: Same comment for copying arguments as in SETUP_NON_RANGE_ARGUMENTS_AND_EXECUTE.
950*795d594fSAndroid Build Coastguard Worker1:
951*795d594fSAndroid Build Coastguard Worker   movl  -4(%rax), %edx
952*795d594fSAndroid Build Coastguard Worker   movl  %edx, (rNEW_FP, %r10, 1)
953*795d594fSAndroid Build Coastguard Worker   movl  -4(%rdi), %edx
954*795d594fSAndroid Build Coastguard Worker   movl  %edx, (%r11, %r10, 1)
955*795d594fSAndroid Build Coastguard Worker   subq  MACRO_LITERAL(4), %r10
956*795d594fSAndroid Build Coastguard Worker   subq  MACRO_LITERAL(4), %rax
957*795d594fSAndroid Build Coastguard Worker   subq  MACRO_LITERAL(4), %rdi
958*795d594fSAndroid Build Coastguard Worker   cmpq  %rcx, %rdi
959*795d594fSAndroid Build Coastguard Worker   jne 1b
960*795d594fSAndroid Build Coastguard Worker
961*795d594fSAndroid Build Coastguard Worker2:
962*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
963*795d594fSAndroid Build Coastguard Worker   // Ignore first argument
964*795d594fSAndroid Build Coastguard Worker   .elseif !\is_static
965*795d594fSAndroid Build Coastguard Worker   movl        %esi, (rNEW_FP, %r10, 1)
966*795d594fSAndroid Build Coastguard Worker   movl        %esi, (%r11, %r10, 1)
967*795d594fSAndroid Build Coastguard Worker   .endif
968*795d594fSAndroid Build Coastguard Worker   movq rNEW_FP, rFP
969*795d594fSAndroid Build Coastguard Worker   movq rNEW_REFS, rREFS
970*795d594fSAndroid Build Coastguard Worker   CFI_DEF_CFA_BREG_PLUS_UCONST CFI_REFS, -8, ((6 + 4 + 1) * 8)
971*795d594fSAndroid Build Coastguard Worker   START_EXECUTING_INSTRUCTIONS
972*795d594fSAndroid Build Coastguard Worker.endm
973*795d594fSAndroid Build Coastguard Worker
974*795d594fSAndroid Build Coastguard Worker.macro GET_SHORTY dest, is_interface, is_polymorphic, is_custom
975*795d594fSAndroid Build Coastguard Worker   push %rdi
976*795d594fSAndroid Build Coastguard Worker   push %rsi
977*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
978*795d594fSAndroid Build Coastguard Worker   movq 16(%rsp), %rdi
979*795d594fSAndroid Build Coastguard Worker   movq rPC, %rsi
980*795d594fSAndroid Build Coastguard Worker   call SYMBOL(NterpGetShortyFromInvokePolymorphic)
981*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
982*795d594fSAndroid Build Coastguard Worker   movq 16(%rsp), %rdi
983*795d594fSAndroid Build Coastguard Worker   movq rPC, %rsi
984*795d594fSAndroid Build Coastguard Worker   call SYMBOL(NterpGetShortyFromInvokeCustom)
985*795d594fSAndroid Build Coastguard Worker   .elseif \is_interface
986*795d594fSAndroid Build Coastguard Worker   movq 16(%rsp), %rdi
987*795d594fSAndroid Build Coastguard Worker   movzwl 2(rPC), %esi
988*795d594fSAndroid Build Coastguard Worker   call SYMBOL(NterpGetShortyFromMethodId)
989*795d594fSAndroid Build Coastguard Worker   .else
990*795d594fSAndroid Build Coastguard Worker   call SYMBOL(NterpGetShorty)
991*795d594fSAndroid Build Coastguard Worker   .endif
992*795d594fSAndroid Build Coastguard Worker   pop %rsi
993*795d594fSAndroid Build Coastguard Worker   pop %rdi
994*795d594fSAndroid Build Coastguard Worker   movq %rax, \dest
995*795d594fSAndroid Build Coastguard Worker.endm
996*795d594fSAndroid Build Coastguard Worker
997*795d594fSAndroid Build Coastguard Worker.macro GET_SHORTY_SLOW_PATH dest, is_interface
998*795d594fSAndroid Build Coastguard Worker   // Save all registers that can hold arguments in the fast path.
999*795d594fSAndroid Build Coastguard Worker   push %rdi
1000*795d594fSAndroid Build Coastguard Worker   push %rsi
1001*795d594fSAndroid Build Coastguard Worker   push %rdx
1002*795d594fSAndroid Build Coastguard Worker   subq MACRO_LITERAL(8), %rsp
1003*795d594fSAndroid Build Coastguard Worker   mov %xmm0, (%rsp)
1004*795d594fSAndroid Build Coastguard Worker   .if \is_interface
1005*795d594fSAndroid Build Coastguard Worker   movq 32(%rsp), %rdi
1006*795d594fSAndroid Build Coastguard Worker   movzwl 2(rPC), %esi
1007*795d594fSAndroid Build Coastguard Worker   call SYMBOL(NterpGetShortyFromMethodId)
1008*795d594fSAndroid Build Coastguard Worker   .else
1009*795d594fSAndroid Build Coastguard Worker   call SYMBOL(NterpGetShorty)
1010*795d594fSAndroid Build Coastguard Worker   .endif
1011*795d594fSAndroid Build Coastguard Worker   mov (%rsp), %xmm0
1012*795d594fSAndroid Build Coastguard Worker   addq MACRO_LITERAL(8), %rsp
1013*795d594fSAndroid Build Coastguard Worker   pop %rdx
1014*795d594fSAndroid Build Coastguard Worker   pop %rsi
1015*795d594fSAndroid Build Coastguard Worker   pop %rdi
1016*795d594fSAndroid Build Coastguard Worker   movq %rax, \dest
1017*795d594fSAndroid Build Coastguard Worker.endm
1018*795d594fSAndroid Build Coastguard Worker
1019*795d594fSAndroid Build Coastguard Worker// Uses r9 as temporary.
1020*795d594fSAndroid Build Coastguard Worker.macro DO_ENTRY_POINT_CHECK call_compiled_code
1021*795d594fSAndroid Build Coastguard Worker   // On entry, the method is %rdi, the instance is %rsi
1022*795d594fSAndroid Build Coastguard Worker   leaq ExecuteNterpImpl(%rip), %r9
1023*795d594fSAndroid Build Coastguard Worker   cmpq %r9, ART_METHOD_QUICK_CODE_OFFSET_64(%rdi)
1024*795d594fSAndroid Build Coastguard Worker   jne  VAR(call_compiled_code)
1025*795d594fSAndroid Build Coastguard Worker
1026*795d594fSAndroid Build Coastguard Worker   movq ART_METHOD_DATA_OFFSET_64(%rdi), %rax
1027*795d594fSAndroid Build Coastguard Worker.endm
1028*795d594fSAndroid Build Coastguard Worker
1029*795d594fSAndroid Build Coastguard Worker// Uses r9 and r10 as temporary
1030*795d594fSAndroid Build Coastguard Worker.macro UPDATE_REGISTERS_FOR_STRING_INIT old_value, new_value
1031*795d594fSAndroid Build Coastguard Worker   movq rREFS, %r9
1032*795d594fSAndroid Build Coastguard Worker   movq rFP, %r10
1033*795d594fSAndroid Build Coastguard Worker1:
1034*795d594fSAndroid Build Coastguard Worker   cmpl (%r9), \old_value
1035*795d594fSAndroid Build Coastguard Worker   jne 2f
1036*795d594fSAndroid Build Coastguard Worker   movl \new_value, (%r9)
1037*795d594fSAndroid Build Coastguard Worker   movl \new_value, (%r10)
1038*795d594fSAndroid Build Coastguard Worker2:
1039*795d594fSAndroid Build Coastguard Worker   addq $$4, %r9
1040*795d594fSAndroid Build Coastguard Worker   addq $$4, %r10
1041*795d594fSAndroid Build Coastguard Worker   cmpq %r9, rFP
1042*795d594fSAndroid Build Coastguard Worker   jne 1b
1043*795d594fSAndroid Build Coastguard Worker.endm
1044*795d594fSAndroid Build Coastguard Worker
1045*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
1046*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
1047*795d594fSAndroid Build Coastguard Worker   // We always go to compiled code for polymorphic calls.
1048*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
1049*795d594fSAndroid Build Coastguard Worker   // We always go to compiled code for custom calls.
1050*795d594fSAndroid Build Coastguard Worker   .else
1051*795d594fSAndroid Build Coastguard Worker     DO_ENTRY_POINT_CHECK .Lcall_compiled_code_\suffix
1052*795d594fSAndroid Build Coastguard Worker     .if \is_string_init
1053*795d594fSAndroid Build Coastguard Worker     call nterp_to_nterp_string_init_non_range
1054*795d594fSAndroid Build Coastguard Worker     .elseif \is_static
1055*795d594fSAndroid Build Coastguard Worker     call nterp_to_nterp_static_non_range
1056*795d594fSAndroid Build Coastguard Worker     .else
1057*795d594fSAndroid Build Coastguard Worker     call nterp_to_nterp_instance_non_range
1058*795d594fSAndroid Build Coastguard Worker     .endif
1059*795d594fSAndroid Build Coastguard Worker     jmp .Ldone_return_\suffix
1060*795d594fSAndroid Build Coastguard Worker   .endif
1061*795d594fSAndroid Build Coastguard Worker
1062*795d594fSAndroid Build Coastguard Worker.Lcall_compiled_code_\suffix:
1063*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
1064*795d594fSAndroid Build Coastguard Worker   // No fast path for polymorphic calls.
1065*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
1066*795d594fSAndroid Build Coastguard Worker   // No fast path for custom calls.
1067*795d594fSAndroid Build Coastguard Worker   .elseif \is_string_init
1068*795d594fSAndroid Build Coastguard Worker   // No fast path for string.init.
1069*795d594fSAndroid Build Coastguard Worker   .else
1070*795d594fSAndroid Build Coastguard Worker     testl $$ART_METHOD_NTERP_INVOKE_FAST_PATH_FLAG, ART_METHOD_ACCESS_FLAGS_OFFSET(%rdi)
1071*795d594fSAndroid Build Coastguard Worker     je .Lfast_path_with_few_args_\suffix
1072*795d594fSAndroid Build Coastguard Worker     movzbl 1(rPC), %r9d
1073*795d594fSAndroid Build Coastguard Worker     movl %r9d, %ebp
1074*795d594fSAndroid Build Coastguard Worker     shrl MACRO_LITERAL(4), %ebp # Number of arguments
1075*795d594fSAndroid Build Coastguard Worker     .if \is_static
1076*795d594fSAndroid Build Coastguard Worker     jz .Linvoke_fast_path_\suffix  # shl sets the Z flag
1077*795d594fSAndroid Build Coastguard Worker     .else
1078*795d594fSAndroid Build Coastguard Worker     cmpl MACRO_LITERAL(1), %ebp
1079*795d594fSAndroid Build Coastguard Worker     je .Linvoke_fast_path_\suffix
1080*795d594fSAndroid Build Coastguard Worker     .endif
1081*795d594fSAndroid Build Coastguard Worker     movzwl 4(rPC), %r11d
1082*795d594fSAndroid Build Coastguard Worker     cmpl MACRO_LITERAL(2), %ebp
1083*795d594fSAndroid Build Coastguard Worker     .if \is_static
1084*795d594fSAndroid Build Coastguard Worker     jl .Lone_arg_fast_path_\suffix
1085*795d594fSAndroid Build Coastguard Worker     .endif
1086*795d594fSAndroid Build Coastguard Worker     je .Ltwo_args_fast_path_\suffix
1087*795d594fSAndroid Build Coastguard Worker     cmpl MACRO_LITERAL(4), %ebp
1088*795d594fSAndroid Build Coastguard Worker     jl .Lthree_args_fast_path_\suffix
1089*795d594fSAndroid Build Coastguard Worker     je .Lfour_args_fast_path_\suffix
1090*795d594fSAndroid Build Coastguard Worker
1091*795d594fSAndroid Build Coastguard Worker     andl        MACRO_LITERAL(0xf), %r9d
1092*795d594fSAndroid Build Coastguard Worker     GET_VREG    %r9d, %r9
1093*795d594fSAndroid Build Coastguard Worker.Lfour_args_fast_path_\suffix:
1094*795d594fSAndroid Build Coastguard Worker     movl        %r11d, %r8d
1095*795d594fSAndroid Build Coastguard Worker     shrl        MACRO_LITERAL(12), %r8d
1096*795d594fSAndroid Build Coastguard Worker     GET_VREG    %r8d, %r8
1097*795d594fSAndroid Build Coastguard Worker.Lthree_args_fast_path_\suffix:
1098*795d594fSAndroid Build Coastguard Worker     movl        %r11d, %ecx
1099*795d594fSAndroid Build Coastguard Worker     shrl        MACRO_LITERAL(8), %ecx
1100*795d594fSAndroid Build Coastguard Worker     andl        MACRO_LITERAL(0xf), %ecx
1101*795d594fSAndroid Build Coastguard Worker     GET_VREG    %ecx, %rcx
1102*795d594fSAndroid Build Coastguard Worker.Ltwo_args_fast_path_\suffix:
1103*795d594fSAndroid Build Coastguard Worker     movl        %r11d, %edx
1104*795d594fSAndroid Build Coastguard Worker     shrl        MACRO_LITERAL(4), %edx
1105*795d594fSAndroid Build Coastguard Worker     andl        MACRO_LITERAL(0xf), %edx
1106*795d594fSAndroid Build Coastguard Worker     GET_VREG    %edx, %rdx
1107*795d594fSAndroid Build Coastguard Worker.Lone_arg_fast_path_\suffix:
1108*795d594fSAndroid Build Coastguard Worker     .if \is_static
1109*795d594fSAndroid Build Coastguard Worker     andl        MACRO_LITERAL(0xf), %r11d
1110*795d594fSAndroid Build Coastguard Worker     GET_VREG    %esi, %r11
1111*795d594fSAndroid Build Coastguard Worker     .else
1112*795d594fSAndroid Build Coastguard Worker     // First argument already in %esi.
1113*795d594fSAndroid Build Coastguard Worker     .endif
1114*795d594fSAndroid Build Coastguard Worker.Linvoke_fast_path_\suffix:
1115*795d594fSAndroid Build Coastguard Worker     call *ART_METHOD_QUICK_CODE_OFFSET_64(%rdi) // Call the method.
1116*795d594fSAndroid Build Coastguard Worker     ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
1117*795d594fSAndroid Build Coastguard Worker
1118*795d594fSAndroid Build Coastguard Worker.Lfast_path_with_few_args_\suffix:
1119*795d594fSAndroid Build Coastguard Worker     // Fast path when we have zero or one argument (modulo 'this'). If there
1120*795d594fSAndroid Build Coastguard Worker     // is one argument, we can put it in both floating point and core register.
1121*795d594fSAndroid Build Coastguard Worker     movzbl 1(rPC), %r9d
1122*795d594fSAndroid Build Coastguard Worker     shrl MACRO_LITERAL(4), %r9d # Number of arguments
1123*795d594fSAndroid Build Coastguard Worker     .if \is_static
1124*795d594fSAndroid Build Coastguard Worker     cmpl MACRO_LITERAL(1), %r9d
1125*795d594fSAndroid Build Coastguard Worker     jl .Linvoke_with_few_args_\suffix
1126*795d594fSAndroid Build Coastguard Worker     jne .Lget_shorty_\suffix
1127*795d594fSAndroid Build Coastguard Worker     movzwl 4(rPC), %r9d
1128*795d594fSAndroid Build Coastguard Worker     andl MACRO_LITERAL(0xf), %r9d  // dex register of first argument
1129*795d594fSAndroid Build Coastguard Worker     GET_VREG %esi, %r9
1130*795d594fSAndroid Build Coastguard Worker     movd %esi, %xmm0
1131*795d594fSAndroid Build Coastguard Worker     .else
1132*795d594fSAndroid Build Coastguard Worker     cmpl MACRO_LITERAL(2), %r9d
1133*795d594fSAndroid Build Coastguard Worker     jl .Linvoke_with_few_args_\suffix
1134*795d594fSAndroid Build Coastguard Worker     jne .Lget_shorty_\suffix
1135*795d594fSAndroid Build Coastguard Worker     movzwl 4(rPC), %r9d
1136*795d594fSAndroid Build Coastguard Worker     shrl MACRO_LITERAL(4), %r9d
1137*795d594fSAndroid Build Coastguard Worker     andl MACRO_LITERAL(0xf), %r9d  // dex register of second argument
1138*795d594fSAndroid Build Coastguard Worker     GET_VREG %edx, %r9
1139*795d594fSAndroid Build Coastguard Worker     movd %edx, %xmm0
1140*795d594fSAndroid Build Coastguard Worker     .endif
1141*795d594fSAndroid Build Coastguard Worker.Linvoke_with_few_args_\suffix:
1142*795d594fSAndroid Build Coastguard Worker     // Check if the next instruction is move-result or move-result-wide.
1143*795d594fSAndroid Build Coastguard Worker     // If it is, we fetch the shorty and jump to the regular invocation.
1144*795d594fSAndroid Build Coastguard Worker     movzwq  6(rPC), %r9
1145*795d594fSAndroid Build Coastguard Worker     andl MACRO_LITERAL(0xfe), %r9d
1146*795d594fSAndroid Build Coastguard Worker     cmpl MACRO_LITERAL(0x0a), %r9d
1147*795d594fSAndroid Build Coastguard Worker     je .Lget_shorty_and_invoke_\suffix
1148*795d594fSAndroid Build Coastguard Worker     call *ART_METHOD_QUICK_CODE_OFFSET_64(%rdi) // Call the method.
1149*795d594fSAndroid Build Coastguard Worker     ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
1150*795d594fSAndroid Build Coastguard Worker.Lget_shorty_and_invoke_\suffix:
1151*795d594fSAndroid Build Coastguard Worker     .if \is_interface
1152*795d594fSAndroid Build Coastguard Worker     // Save interface method, used for conflict resolution, in a callee-save register.
1153*795d594fSAndroid Build Coastguard Worker     movq %rax, %xmm12
1154*795d594fSAndroid Build Coastguard Worker     .endif
1155*795d594fSAndroid Build Coastguard Worker     GET_SHORTY_SLOW_PATH rINSTq, \is_interface
1156*795d594fSAndroid Build Coastguard Worker     jmp .Lgpr_setup_finished_\suffix
1157*795d594fSAndroid Build Coastguard Worker   .endif
1158*795d594fSAndroid Build Coastguard Worker
1159*795d594fSAndroid Build Coastguard Worker.Lget_shorty_\suffix:
1160*795d594fSAndroid Build Coastguard Worker   .if \is_interface
1161*795d594fSAndroid Build Coastguard Worker   // Save interface method, used for conflict resolution, in a callee-save register.
1162*795d594fSAndroid Build Coastguard Worker   movq %rax, %xmm12
1163*795d594fSAndroid Build Coastguard Worker   .endif
1164*795d594fSAndroid Build Coastguard Worker   GET_SHORTY rINSTq, \is_interface, \is_polymorphic, \is_custom
1165*795d594fSAndroid Build Coastguard Worker   // From this point:
1166*795d594fSAndroid Build Coastguard Worker   // - rISNTq contains shorty (in callee-save to switch over return value after call).
1167*795d594fSAndroid Build Coastguard Worker   // - rdi contains method
1168*795d594fSAndroid Build Coastguard Worker   // - rsi contains 'this' pointer for instance method.
1169*795d594fSAndroid Build Coastguard Worker   leaq 1(rINSTq), %r9  // shorty + 1  ; ie skip return arg character
1170*795d594fSAndroid Build Coastguard Worker   movzwl 4(rPC), %r11d // arguments
1171*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
1172*795d594fSAndroid Build Coastguard Worker   shrq MACRO_LITERAL(4), %r11
1173*795d594fSAndroid Build Coastguard Worker   movq $$1, %r10       // ignore first argument
1174*795d594fSAndroid Build Coastguard Worker   .elseif \is_static
1175*795d594fSAndroid Build Coastguard Worker   movq $$0, %r10       // arg_index
1176*795d594fSAndroid Build Coastguard Worker   .else
1177*795d594fSAndroid Build Coastguard Worker   shrq MACRO_LITERAL(4), %r11
1178*795d594fSAndroid Build Coastguard Worker   movq $$1, %r10       // arg_index
1179*795d594fSAndroid Build Coastguard Worker   .endif
1180*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_XMMS xmm0, r11, r9, r10, .Lxmm_setup_finished_\suffix
1181*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_XMMS xmm1, r11, r9, r10, .Lxmm_setup_finished_\suffix
1182*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_XMMS xmm2, r11, r9, r10, .Lxmm_setup_finished_\suffix
1183*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_XMMS xmm3, r11, r9, r10, .Lxmm_setup_finished_\suffix
1184*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_XMMS xmm4, r11, r9, r10, .Lxmm_setup_finished_\suffix
1185*795d594fSAndroid Build Coastguard Worker.Lxmm_setup_finished_\suffix:
1186*795d594fSAndroid Build Coastguard Worker   leaq 1(rINSTq), %r9  // shorty + 1  ; ie skip return arg character
1187*795d594fSAndroid Build Coastguard Worker   movzwl 4(rPC), %r11d // arguments
1188*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
1189*795d594fSAndroid Build Coastguard Worker   movq $$1, %r10       // ignore first argument
1190*795d594fSAndroid Build Coastguard Worker   shrq MACRO_LITERAL(4), %r11
1191*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_GPRS rsi, esi, r11, r9, r10, .Lgpr_setup_finished_\suffix
1192*795d594fSAndroid Build Coastguard Worker   .elseif \is_static
1193*795d594fSAndroid Build Coastguard Worker   movq $$0, %r10       // arg_index
1194*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_GPRS rsi, esi, r11, r9, r10, .Lgpr_setup_finished_\suffix
1195*795d594fSAndroid Build Coastguard Worker   .else
1196*795d594fSAndroid Build Coastguard Worker   shrq MACRO_LITERAL(4), %r11
1197*795d594fSAndroid Build Coastguard Worker   movq $$1, %r10       // arg_index
1198*795d594fSAndroid Build Coastguard Worker   .endif
1199*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_GPRS rdx, edx, r11, r9, r10, .Lgpr_setup_finished_\suffix
1200*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_GPRS rcx, ecx, r11, r9, r10, .Lgpr_setup_finished_\suffix
1201*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_GPRS r8, r8d, r11, r9, r10, .Lgpr_setup_finished_\suffix
1202*795d594fSAndroid Build Coastguard Worker   LOOP_OVER_SHORTY_LOADING_GPRS r9, r9d, r11, r9, r10, .Lgpr_setup_finished_\suffix
1203*795d594fSAndroid Build Coastguard Worker.Lgpr_setup_finished_\suffix:
1204*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
1205*795d594fSAndroid Build Coastguard Worker   call SYMBOL(art_quick_invoke_polymorphic)
1206*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
1207*795d594fSAndroid Build Coastguard Worker   call SYMBOL(art_quick_invoke_custom)
1208*795d594fSAndroid Build Coastguard Worker   .else
1209*795d594fSAndroid Build Coastguard Worker      .if \is_interface
1210*795d594fSAndroid Build Coastguard Worker      movq %xmm12, %rax
1211*795d594fSAndroid Build Coastguard Worker      .endif
1212*795d594fSAndroid Build Coastguard Worker      call *ART_METHOD_QUICK_CODE_OFFSET_64(%rdi) // Call the method.
1213*795d594fSAndroid Build Coastguard Worker   .endif
1214*795d594fSAndroid Build Coastguard Worker   cmpb LITERAL(68), (rINSTq)       // Test if result type char == 'D'.
1215*795d594fSAndroid Build Coastguard Worker   je .Lreturn_double_\suffix
1216*795d594fSAndroid Build Coastguard Worker   cmpb LITERAL(70), (rINSTq)       // Test if result type char == 'F'.
1217*795d594fSAndroid Build Coastguard Worker   jne .Ldone_return_\suffix
1218*795d594fSAndroid Build Coastguard Worker.Lreturn_float_\suffix:
1219*795d594fSAndroid Build Coastguard Worker   movd %xmm0, %eax
1220*795d594fSAndroid Build Coastguard Worker   jmp .Ldone_return_\suffix
1221*795d594fSAndroid Build Coastguard Worker.Lreturn_double_\suffix:
1222*795d594fSAndroid Build Coastguard Worker   movq %xmm0, %rax
1223*795d594fSAndroid Build Coastguard Worker.Ldone_return_\suffix:
1224*795d594fSAndroid Build Coastguard Worker   /* resume execution of caller */
1225*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
1226*795d594fSAndroid Build Coastguard Worker   movzwl 4(rPC), %r11d // arguments
1227*795d594fSAndroid Build Coastguard Worker   andq $$0xf, %r11
1228*795d594fSAndroid Build Coastguard Worker   GET_VREG %esi, %r11
1229*795d594fSAndroid Build Coastguard Worker   UPDATE_REGISTERS_FOR_STRING_INIT %esi, %eax
1230*795d594fSAndroid Build Coastguard Worker   .endif
1231*795d594fSAndroid Build Coastguard Worker
1232*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
1233*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 4
1234*795d594fSAndroid Build Coastguard Worker   .else
1235*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
1236*795d594fSAndroid Build Coastguard Worker   .endif
1237*795d594fSAndroid Build Coastguard Worker.endm
1238*795d594fSAndroid Build Coastguard Worker
1239*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
1240*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
1241*795d594fSAndroid Build Coastguard Worker   // We always go to compiled code for polymorphic calls.
1242*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
1243*795d594fSAndroid Build Coastguard Worker   // We always go to compiled code for custom calls.
1244*795d594fSAndroid Build Coastguard Worker   .else
1245*795d594fSAndroid Build Coastguard Worker     DO_ENTRY_POINT_CHECK .Lcall_compiled_code_range_\suffix
1246*795d594fSAndroid Build Coastguard Worker     .if \is_string_init
1247*795d594fSAndroid Build Coastguard Worker     call nterp_to_nterp_string_init_range
1248*795d594fSAndroid Build Coastguard Worker     .elseif \is_static
1249*795d594fSAndroid Build Coastguard Worker     call nterp_to_nterp_static_range
1250*795d594fSAndroid Build Coastguard Worker     .else
1251*795d594fSAndroid Build Coastguard Worker     call nterp_to_nterp_instance_range
1252*795d594fSAndroid Build Coastguard Worker     .endif
1253*795d594fSAndroid Build Coastguard Worker     jmp .Ldone_return_range_\suffix
1254*795d594fSAndroid Build Coastguard Worker   .endif
1255*795d594fSAndroid Build Coastguard Worker
1256*795d594fSAndroid Build Coastguard Worker.Lcall_compiled_code_range_\suffix:
1257*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
1258*795d594fSAndroid Build Coastguard Worker   // No fast path for polymorphic calls.
1259*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
1260*795d594fSAndroid Build Coastguard Worker   // No fast path for custom calls.
1261*795d594fSAndroid Build Coastguard Worker   .elseif \is_string_init
1262*795d594fSAndroid Build Coastguard Worker   // No fast path for string.init.
1263*795d594fSAndroid Build Coastguard Worker   .else
1264*795d594fSAndroid Build Coastguard Worker     testl $$ART_METHOD_NTERP_INVOKE_FAST_PATH_FLAG, ART_METHOD_ACCESS_FLAGS_OFFSET(%rdi)
1265*795d594fSAndroid Build Coastguard Worker     je .Lfast_path_with_few_args_range_\suffix
1266*795d594fSAndroid Build Coastguard Worker     movzbl 1(rPC), %r9d  // number of arguments
1267*795d594fSAndroid Build Coastguard Worker     .if \is_static
1268*795d594fSAndroid Build Coastguard Worker     testl %r9d, %r9d
1269*795d594fSAndroid Build Coastguard Worker     je .Linvoke_fast_path_range_\suffix
1270*795d594fSAndroid Build Coastguard Worker     .else
1271*795d594fSAndroid Build Coastguard Worker     cmpl MACRO_LITERAL(1), %r9d
1272*795d594fSAndroid Build Coastguard Worker     je .Linvoke_fast_path_range_\suffix
1273*795d594fSAndroid Build Coastguard Worker     .endif
1274*795d594fSAndroid Build Coastguard Worker     movzwl 4(rPC), %r11d  // dex register of first argument
1275*795d594fSAndroid Build Coastguard Worker     leaq (rFP, %r11, 4), %r11  // location of first dex register value
1276*795d594fSAndroid Build Coastguard Worker     cmpl MACRO_LITERAL(2), %r9d
1277*795d594fSAndroid Build Coastguard Worker     .if \is_static
1278*795d594fSAndroid Build Coastguard Worker     jl .Lone_arg_fast_path_range_\suffix
1279*795d594fSAndroid Build Coastguard Worker     .endif
1280*795d594fSAndroid Build Coastguard Worker     je .Ltwo_args_fast_path_range_\suffix
1281*795d594fSAndroid Build Coastguard Worker     cmp MACRO_LITERAL(4), %r9d
1282*795d594fSAndroid Build Coastguard Worker     jl .Lthree_args_fast_path_range_\suffix
1283*795d594fSAndroid Build Coastguard Worker     je .Lfour_args_fast_path_range_\suffix
1284*795d594fSAndroid Build Coastguard Worker     cmp MACRO_LITERAL(5), %r9d
1285*795d594fSAndroid Build Coastguard Worker     je .Lfive_args_fast_path_range_\suffix
1286*795d594fSAndroid Build Coastguard Worker
1287*795d594fSAndroid Build Coastguard Worker.Lloop_over_fast_path_range_\suffix:
1288*795d594fSAndroid Build Coastguard Worker     subl MACRO_LITERAL(1), %r9d
1289*795d594fSAndroid Build Coastguard Worker     movl (%r11, %r9, 4), %r8d
1290*795d594fSAndroid Build Coastguard Worker     movl %r8d, 8(%rsp, %r9, 4)  // Add 8 for the ArtMethod
1291*795d594fSAndroid Build Coastguard Worker     cmpl MACRO_LITERAL(5), %r9d
1292*795d594fSAndroid Build Coastguard Worker     jne .Lloop_over_fast_path_range_\suffix
1293*795d594fSAndroid Build Coastguard Worker
1294*795d594fSAndroid Build Coastguard Worker.Lfive_args_fast_path_range_\suffix:
1295*795d594fSAndroid Build Coastguard Worker     movl 16(%r11), %r9d
1296*795d594fSAndroid Build Coastguard Worker.Lfour_args_fast_path_range_\suffix:
1297*795d594fSAndroid Build Coastguard Worker     movl 12(%r11), %r8d
1298*795d594fSAndroid Build Coastguard Worker.Lthree_args_fast_path_range_\suffix:
1299*795d594fSAndroid Build Coastguard Worker     movl 8(%r11), %ecx
1300*795d594fSAndroid Build Coastguard Worker.Ltwo_args_fast_path_range_\suffix:
1301*795d594fSAndroid Build Coastguard Worker     movl 4(%r11), %edx
1302*795d594fSAndroid Build Coastguard Worker.Lone_arg_fast_path_range_\suffix:
1303*795d594fSAndroid Build Coastguard Worker     .if \is_static
1304*795d594fSAndroid Build Coastguard Worker     movl 0(%r11), %esi
1305*795d594fSAndroid Build Coastguard Worker     .else
1306*795d594fSAndroid Build Coastguard Worker     // First argument already in %esi.
1307*795d594fSAndroid Build Coastguard Worker     .endif
1308*795d594fSAndroid Build Coastguard Worker.Linvoke_fast_path_range_\suffix:
1309*795d594fSAndroid Build Coastguard Worker     call *ART_METHOD_QUICK_CODE_OFFSET_64(%rdi) // Call the method.
1310*795d594fSAndroid Build Coastguard Worker     ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
1311*795d594fSAndroid Build Coastguard Worker
1312*795d594fSAndroid Build Coastguard Worker.Lfast_path_with_few_args_range_\suffix:
1313*795d594fSAndroid Build Coastguard Worker     // Fast path when we have zero or one argument (modulo 'this'). If there
1314*795d594fSAndroid Build Coastguard Worker     // is one argument, we can put it in both floating point and core register.
1315*795d594fSAndroid Build Coastguard Worker     movzbl 1(rPC), %r9d # Number of arguments
1316*795d594fSAndroid Build Coastguard Worker     .if \is_static
1317*795d594fSAndroid Build Coastguard Worker     cmpl MACRO_LITERAL(1), %r9d
1318*795d594fSAndroid Build Coastguard Worker     jl .Linvoke_with_few_args_range_\suffix
1319*795d594fSAndroid Build Coastguard Worker     jne .Lget_shorty_range_\suffix
1320*795d594fSAndroid Build Coastguard Worker     movzwl 4(rPC), %r9d  // Dex register of first argument
1321*795d594fSAndroid Build Coastguard Worker     GET_VREG %esi, %r9
1322*795d594fSAndroid Build Coastguard Worker     movd %esi, %xmm0
1323*795d594fSAndroid Build Coastguard Worker     .else
1324*795d594fSAndroid Build Coastguard Worker     cmpl MACRO_LITERAL(2), %r9d
1325*795d594fSAndroid Build Coastguard Worker     jl .Linvoke_with_few_args_range_\suffix
1326*795d594fSAndroid Build Coastguard Worker     jne .Lget_shorty_range_\suffix
1327*795d594fSAndroid Build Coastguard Worker     movzwl 4(rPC), %r9d
1328*795d594fSAndroid Build Coastguard Worker     addl MACRO_LITERAL(1), %r9d  // dex register of second argument
1329*795d594fSAndroid Build Coastguard Worker     GET_VREG %edx, %r9
1330*795d594fSAndroid Build Coastguard Worker     movd %edx, %xmm0
1331*795d594fSAndroid Build Coastguard Worker     .endif
1332*795d594fSAndroid Build Coastguard Worker.Linvoke_with_few_args_range_\suffix:
1333*795d594fSAndroid Build Coastguard Worker     // Check if the next instruction is move-result or move-result-wide.
1334*795d594fSAndroid Build Coastguard Worker     // If it is, we fetch the shorty and jump to the regular invocation.
1335*795d594fSAndroid Build Coastguard Worker     movzwq  6(rPC), %r9
1336*795d594fSAndroid Build Coastguard Worker     and MACRO_LITERAL(0xfe), %r9d
1337*795d594fSAndroid Build Coastguard Worker     cmpl MACRO_LITERAL(0x0a), %r9d
1338*795d594fSAndroid Build Coastguard Worker     je .Lget_shorty_and_invoke_range_\suffix
1339*795d594fSAndroid Build Coastguard Worker     call *ART_METHOD_QUICK_CODE_OFFSET_64(%rdi) // Call the method.
1340*795d594fSAndroid Build Coastguard Worker     ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
1341*795d594fSAndroid Build Coastguard Worker.Lget_shorty_and_invoke_range_\suffix:
1342*795d594fSAndroid Build Coastguard Worker     .if \is_interface
1343*795d594fSAndroid Build Coastguard Worker     // Save interface method, used for conflict resolution, in a callee-save register.
1344*795d594fSAndroid Build Coastguard Worker     movq %rax, %xmm12
1345*795d594fSAndroid Build Coastguard Worker     .endif
1346*795d594fSAndroid Build Coastguard Worker     GET_SHORTY_SLOW_PATH rINSTq, \is_interface
1347*795d594fSAndroid Build Coastguard Worker     jmp .Lgpr_setup_finished_range_\suffix
1348*795d594fSAndroid Build Coastguard Worker   .endif
1349*795d594fSAndroid Build Coastguard Worker
1350*795d594fSAndroid Build Coastguard Worker.Lget_shorty_range_\suffix:
1351*795d594fSAndroid Build Coastguard Worker   .if \is_interface
1352*795d594fSAndroid Build Coastguard Worker   // Save interface method, used for conflict resolution, in a callee-saved register.
1353*795d594fSAndroid Build Coastguard Worker   movq %rax, %xmm12
1354*795d594fSAndroid Build Coastguard Worker   .endif
1355*795d594fSAndroid Build Coastguard Worker   GET_SHORTY rINSTq, \is_interface, \is_polymorphic, \is_custom
1356*795d594fSAndroid Build Coastguard Worker   // From this point:
1357*795d594fSAndroid Build Coastguard Worker   // - rINSTq contains shorty (in callee-save to switch over return value after call).
1358*795d594fSAndroid Build Coastguard Worker   // - rdi contains method
1359*795d594fSAndroid Build Coastguard Worker   // - rsi contains 'this' pointer for instance method.
1360*795d594fSAndroid Build Coastguard Worker   leaq 1(rINSTq), %r9  // shorty + 1  ; ie skip return arg character
1361*795d594fSAndroid Build Coastguard Worker   movzwl 4(rPC), %r10d // arg start index
1362*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
1363*795d594fSAndroid Build Coastguard Worker   addq $$1, %r10       // arg start index
1364*795d594fSAndroid Build Coastguard Worker   movq $$1, %rbp       // index in stack
1365*795d594fSAndroid Build Coastguard Worker   .elseif \is_static
1366*795d594fSAndroid Build Coastguard Worker   movq $$0, %rbp       // index in stack
1367*795d594fSAndroid Build Coastguard Worker   .else
1368*795d594fSAndroid Build Coastguard Worker   addq $$1, %r10       // arg start index
1369*795d594fSAndroid Build Coastguard Worker   movq $$1, %rbp       // index in stack
1370*795d594fSAndroid Build Coastguard Worker   .endif
1371*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_XMMS xmm0, r9, r10, rbp, .Lxmm_setup_finished_range_\suffix
1372*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_XMMS xmm1, r9, r10, rbp, .Lxmm_setup_finished_range_\suffix
1373*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_XMMS xmm2, r9, r10, rbp, .Lxmm_setup_finished_range_\suffix
1374*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_XMMS xmm3, r9, r10, rbp, .Lxmm_setup_finished_range_\suffix
1375*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_XMMS xmm4, r9, r10, rbp, .Lxmm_setup_finished_range_\suffix
1376*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_XMMS xmm5, r9, r10, rbp, .Lxmm_setup_finished_range_\suffix
1377*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_XMMS xmm6, r9, r10, rbp, .Lxmm_setup_finished_range_\suffix
1378*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_XMMS xmm7, r9, r10, rbp, .Lxmm_setup_finished_range_\suffix
1379*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_FPs r9, r10, rbp, .Lxmm_setup_finished_range_\suffix
1380*795d594fSAndroid Build Coastguard Worker.Lxmm_setup_finished_range_\suffix:
1381*795d594fSAndroid Build Coastguard Worker   leaq 1(%rbx), %r11  // shorty + 1  ; ie skip return arg character
1382*795d594fSAndroid Build Coastguard Worker   movzwl 4(rPC), %r10d // arg start index
1383*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
1384*795d594fSAndroid Build Coastguard Worker   addq $$1, %r10       // arg start index
1385*795d594fSAndroid Build Coastguard Worker   movq $$1, %rbp       // index in stack
1386*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS rsi, esi, r11, r10, rbp, .Lgpr_setup_finished_range_\suffix
1387*795d594fSAndroid Build Coastguard Worker   .elseif \is_static
1388*795d594fSAndroid Build Coastguard Worker   movq $$0, %rbp // index in stack
1389*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS rsi, esi, r11, r10, rbp, .Lgpr_setup_finished_range_\suffix
1390*795d594fSAndroid Build Coastguard Worker   .else
1391*795d594fSAndroid Build Coastguard Worker   addq $$1, %r10       // arg start index
1392*795d594fSAndroid Build Coastguard Worker   movq $$1, %rbp // index in stack
1393*795d594fSAndroid Build Coastguard Worker   .endif
1394*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS rdx, edx, r11, r10, rbp, .Lgpr_setup_finished_range_\suffix
1395*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS rcx, ecx, r11, r10, rbp, .Lgpr_setup_finished_range_\suffix
1396*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS r8, r8d, r11, r10, rbp, .Lgpr_setup_finished_range_\suffix
1397*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_SHORTY_LOADING_GPRS r9, r9d, r11, r10, rbp, .Lgpr_setup_finished_range_\suffix
1398*795d594fSAndroid Build Coastguard Worker   LOOP_RANGE_OVER_INTs r11, r10, rbp, .Lgpr_setup_finished_range_\suffix
1399*795d594fSAndroid Build Coastguard Worker
1400*795d594fSAndroid Build Coastguard Worker.Lgpr_setup_finished_range_\suffix:
1401*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
1402*795d594fSAndroid Build Coastguard Worker   call SYMBOL(art_quick_invoke_polymorphic)
1403*795d594fSAndroid Build Coastguard Worker   .elseif \is_custom
1404*795d594fSAndroid Build Coastguard Worker   call SYMBOL(art_quick_invoke_custom)
1405*795d594fSAndroid Build Coastguard Worker   .else
1406*795d594fSAndroid Build Coastguard Worker     .if \is_interface
1407*795d594fSAndroid Build Coastguard Worker     // Set the hidden argument for conflict resolution.
1408*795d594fSAndroid Build Coastguard Worker     movq %xmm12, %rax
1409*795d594fSAndroid Build Coastguard Worker     .endif
1410*795d594fSAndroid Build Coastguard Worker     call *ART_METHOD_QUICK_CODE_OFFSET_64(%rdi) // Call the method.
1411*795d594fSAndroid Build Coastguard Worker   .endif
1412*795d594fSAndroid Build Coastguard Worker   cmpb LITERAL(68), (%rbx)       // Test if result type char == 'D'.
1413*795d594fSAndroid Build Coastguard Worker   je .Lreturn_range_double_\suffix
1414*795d594fSAndroid Build Coastguard Worker   cmpb LITERAL(70), (%rbx)       // Test if result type char == 'F'.
1415*795d594fSAndroid Build Coastguard Worker   je .Lreturn_range_float_\suffix
1416*795d594fSAndroid Build Coastguard Worker   /* resume execution of caller */
1417*795d594fSAndroid Build Coastguard Worker.Ldone_return_range_\suffix:
1418*795d594fSAndroid Build Coastguard Worker   .if \is_string_init
1419*795d594fSAndroid Build Coastguard Worker   movzwl 4(rPC), %r11d // arguments
1420*795d594fSAndroid Build Coastguard Worker   GET_VREG %esi, %r11
1421*795d594fSAndroid Build Coastguard Worker   UPDATE_REGISTERS_FOR_STRING_INIT %esi, %eax
1422*795d594fSAndroid Build Coastguard Worker   .endif
1423*795d594fSAndroid Build Coastguard Worker
1424*795d594fSAndroid Build Coastguard Worker   .if \is_polymorphic
1425*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 4
1426*795d594fSAndroid Build Coastguard Worker   .else
1427*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
1428*795d594fSAndroid Build Coastguard Worker   .endif
1429*795d594fSAndroid Build Coastguard Worker.Lreturn_range_double_\suffix:
1430*795d594fSAndroid Build Coastguard Worker    movq %xmm0, %rax
1431*795d594fSAndroid Build Coastguard Worker    jmp .Ldone_return_range_\suffix
1432*795d594fSAndroid Build Coastguard Worker.Lreturn_range_float_\suffix:
1433*795d594fSAndroid Build Coastguard Worker    movd %xmm0, %eax
1434*795d594fSAndroid Build Coastguard Worker    jmp .Ldone_return_range_\suffix
1435*795d594fSAndroid Build Coastguard Worker.endm
1436*795d594fSAndroid Build Coastguard Worker
1437*795d594fSAndroid Build Coastguard Worker// Helper for static field get.
1438*795d594fSAndroid Build Coastguard Worker.macro OP_SGET load="movl", wide="0"
1439*795d594fSAndroid Build Coastguard Worker   // Fast-path which gets the field from thread-local cache.
1440*795d594fSAndroid Build Coastguard Worker%  fetch_from_thread_cache("%rax", miss_label="2f")
1441*795d594fSAndroid Build Coastguard Worker1:
1442*795d594fSAndroid Build Coastguard Worker   movl ART_FIELD_OFFSET_OFFSET(%rax), %edx
1443*795d594fSAndroid Build Coastguard Worker   movl ART_FIELD_DECLARING_CLASS_OFFSET(%rax), %eax
1444*795d594fSAndroid Build Coastguard Worker   cmpq $$0, rSELF:THREAD_READ_BARRIER_MARK_REG00_OFFSET
1445*795d594fSAndroid Build Coastguard Worker   jne 3f
1446*795d594fSAndroid Build Coastguard Worker4:
1447*795d594fSAndroid Build Coastguard Worker   .if \wide
1448*795d594fSAndroid Build Coastguard Worker   movq (%eax,%edx,1), %rax
1449*795d594fSAndroid Build Coastguard Worker   SET_WIDE_VREG %rax, rINSTq              # fp[A] <- value
1450*795d594fSAndroid Build Coastguard Worker   .else
1451*795d594fSAndroid Build Coastguard Worker   \load (%eax, %edx, 1), %eax
1452*795d594fSAndroid Build Coastguard Worker   SET_VREG %eax, rINSTq            # fp[A] <- value
1453*795d594fSAndroid Build Coastguard Worker   .endif
1454*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
1455*795d594fSAndroid Build Coastguard Worker2:
1456*795d594fSAndroid Build Coastguard Worker   EXPORT_PC
1457*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_SELF_OFFSET, %rdi
1458*795d594fSAndroid Build Coastguard Worker   movq 0(%rsp), %rsi
1459*795d594fSAndroid Build Coastguard Worker   movq rPC, %rdx
1460*795d594fSAndroid Build Coastguard Worker   movq $$0, %rcx
1461*795d594fSAndroid Build Coastguard Worker   call nterp_get_static_field
1462*795d594fSAndroid Build Coastguard Worker   // Clear the marker that we put for volatile fields. The x86 memory
1463*795d594fSAndroid Build Coastguard Worker   // model doesn't require a barrier.
1464*795d594fSAndroid Build Coastguard Worker   andq $$-2, %rax
1465*795d594fSAndroid Build Coastguard Worker   jmp 1b
1466*795d594fSAndroid Build Coastguard Worker3:
1467*795d594fSAndroid Build Coastguard Worker   call art_quick_read_barrier_mark_reg00
1468*795d594fSAndroid Build Coastguard Worker   jmp 4b
1469*795d594fSAndroid Build Coastguard Worker.endm
1470*795d594fSAndroid Build Coastguard Worker
1471*795d594fSAndroid Build Coastguard Worker// Helper for static field put.
1472*795d594fSAndroid Build Coastguard Worker.macro OP_SPUT rINST_reg="rINST", store="movl", wide="0":
1473*795d594fSAndroid Build Coastguard Worker   // Fast-path which gets the field from thread-local cache.
1474*795d594fSAndroid Build Coastguard Worker%  fetch_from_thread_cache("%rax", miss_label="2f")
1475*795d594fSAndroid Build Coastguard Worker1:
1476*795d594fSAndroid Build Coastguard Worker   movl ART_FIELD_OFFSET_OFFSET(%rax), %edx
1477*795d594fSAndroid Build Coastguard Worker   movl ART_FIELD_DECLARING_CLASS_OFFSET(%rax), %eax
1478*795d594fSAndroid Build Coastguard Worker   cmpq $$0, rSELF:THREAD_READ_BARRIER_MARK_REG00_OFFSET
1479*795d594fSAndroid Build Coastguard Worker   jne 3f
1480*795d594fSAndroid Build Coastguard Worker4:
1481*795d594fSAndroid Build Coastguard Worker   .if \wide
1482*795d594fSAndroid Build Coastguard Worker   GET_WIDE_VREG rINSTq, rINSTq           # rINST <- v[A]
1483*795d594fSAndroid Build Coastguard Worker   .else
1484*795d594fSAndroid Build Coastguard Worker   GET_VREG rINST, rINSTq                  # rINST <- v[A]
1485*795d594fSAndroid Build Coastguard Worker   .endif
1486*795d594fSAndroid Build Coastguard Worker   \store    \rINST_reg, (%rax,%rdx,1)
1487*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
1488*795d594fSAndroid Build Coastguard Worker2:
1489*795d594fSAndroid Build Coastguard Worker   EXPORT_PC
1490*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_SELF_OFFSET, %rdi
1491*795d594fSAndroid Build Coastguard Worker   movq 0(%rsp), %rsi
1492*795d594fSAndroid Build Coastguard Worker   movq rPC, %rdx
1493*795d594fSAndroid Build Coastguard Worker   movq $$0, %rcx
1494*795d594fSAndroid Build Coastguard Worker   call nterp_get_static_field
1495*795d594fSAndroid Build Coastguard Worker   testq MACRO_LITERAL(1), %rax
1496*795d594fSAndroid Build Coastguard Worker   je 1b
1497*795d594fSAndroid Build Coastguard Worker   // Clear the marker that we put for volatile fields. The x86 memory
1498*795d594fSAndroid Build Coastguard Worker   // model doesn't require a barrier.
1499*795d594fSAndroid Build Coastguard Worker   CLEAR_VOLATILE_MARKER %rax
1500*795d594fSAndroid Build Coastguard Worker   movl ART_FIELD_OFFSET_OFFSET(%rax), %edx
1501*795d594fSAndroid Build Coastguard Worker   movl ART_FIELD_DECLARING_CLASS_OFFSET(%rax), %eax
1502*795d594fSAndroid Build Coastguard Worker   cmpq $$0, rSELF:THREAD_READ_BARRIER_MARK_REG00_OFFSET
1503*795d594fSAndroid Build Coastguard Worker   jne 6f
1504*795d594fSAndroid Build Coastguard Worker5:
1505*795d594fSAndroid Build Coastguard Worker   .if \wide
1506*795d594fSAndroid Build Coastguard Worker   GET_WIDE_VREG rINSTq, rINSTq           # rINST <- v[A]
1507*795d594fSAndroid Build Coastguard Worker   .else
1508*795d594fSAndroid Build Coastguard Worker   GET_VREG rINST, rINSTq                  # rINST <- v[A]
1509*795d594fSAndroid Build Coastguard Worker   .endif
1510*795d594fSAndroid Build Coastguard Worker   \store    \rINST_reg, (%rax,%rdx,1)
1511*795d594fSAndroid Build Coastguard Worker   lock addl $$0, (%rsp)
1512*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
1513*795d594fSAndroid Build Coastguard Worker3:
1514*795d594fSAndroid Build Coastguard Worker   call art_quick_read_barrier_mark_reg00
1515*795d594fSAndroid Build Coastguard Worker   jmp 4b
1516*795d594fSAndroid Build Coastguard Worker6:
1517*795d594fSAndroid Build Coastguard Worker   call art_quick_read_barrier_mark_reg00
1518*795d594fSAndroid Build Coastguard Worker   jmp 5b
1519*795d594fSAndroid Build Coastguard Worker.endm
1520*795d594fSAndroid Build Coastguard Worker
1521*795d594fSAndroid Build Coastguard Worker
1522*795d594fSAndroid Build Coastguard Worker.macro OP_IPUT_INTERNAL rINST_reg="rINST", store="movl", wide="0":
1523*795d594fSAndroid Build Coastguard Worker   movzbq  rINSTbl, %rcx                   # rcx <- BA
1524*795d594fSAndroid Build Coastguard Worker   sarl    $$4, %ecx                       # ecx <- B
1525*795d594fSAndroid Build Coastguard Worker   GET_VREG %ecx, %rcx                     # vB (object we're operating on)
1526*795d594fSAndroid Build Coastguard Worker   testl   %ecx, %ecx                      # is object null?
1527*795d594fSAndroid Build Coastguard Worker   je      common_errNullObject
1528*795d594fSAndroid Build Coastguard Worker   andb    $$0xf, rINSTbl                  # rINST <- A
1529*795d594fSAndroid Build Coastguard Worker   .if \wide
1530*795d594fSAndroid Build Coastguard Worker   GET_WIDE_VREG rINSTq, rINSTq              # rax<- fp[A]/fp[A+1]
1531*795d594fSAndroid Build Coastguard Worker   .else
1532*795d594fSAndroid Build Coastguard Worker   GET_VREG rINST, rINSTq                  # rINST <- v[A]
1533*795d594fSAndroid Build Coastguard Worker   .endif
1534*795d594fSAndroid Build Coastguard Worker   \store \rINST_reg, (%rcx,%rax,1)
1535*795d594fSAndroid Build Coastguard Worker.endm
1536*795d594fSAndroid Build Coastguard Worker
1537*795d594fSAndroid Build Coastguard Worker// Helper for instance field put.
1538*795d594fSAndroid Build Coastguard Worker.macro OP_IPUT rINST_reg="rINST", store="movl", wide="0":
1539*795d594fSAndroid Build Coastguard Worker   // Fast-path which gets the field from thread-local cache.
1540*795d594fSAndroid Build Coastguard Worker%  fetch_from_thread_cache("%rax", miss_label="2f")
1541*795d594fSAndroid Build Coastguard Worker1:
1542*795d594fSAndroid Build Coastguard Worker   OP_IPUT_INTERNAL \rINST_reg, \store, \wide
1543*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
1544*795d594fSAndroid Build Coastguard Worker2:
1545*795d594fSAndroid Build Coastguard Worker   EXPORT_PC
1546*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_SELF_OFFSET, %rdi
1547*795d594fSAndroid Build Coastguard Worker   movq 0(%rsp), %rsi
1548*795d594fSAndroid Build Coastguard Worker   movq rPC, %rdx
1549*795d594fSAndroid Build Coastguard Worker   movq $$0, %rcx
1550*795d594fSAndroid Build Coastguard Worker   call nterp_get_instance_field_offset
1551*795d594fSAndroid Build Coastguard Worker   testl %eax, %eax
1552*795d594fSAndroid Build Coastguard Worker   jns 1b
1553*795d594fSAndroid Build Coastguard Worker   negl %eax
1554*795d594fSAndroid Build Coastguard Worker   OP_IPUT_INTERNAL \rINST_reg, \store, \wide
1555*795d594fSAndroid Build Coastguard Worker   lock addl $$0, (%rsp)
1556*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
1557*795d594fSAndroid Build Coastguard Worker.endm
1558*795d594fSAndroid Build Coastguard Worker
1559*795d594fSAndroid Build Coastguard Worker// Helper for instance field get.
1560*795d594fSAndroid Build Coastguard Worker.macro OP_IGET load="movl", wide="0"
1561*795d594fSAndroid Build Coastguard Worker   // Fast-path which gets the field from thread-local cache.
1562*795d594fSAndroid Build Coastguard Worker%  fetch_from_thread_cache("%rax", miss_label="2f")
1563*795d594fSAndroid Build Coastguard Worker1:
1564*795d594fSAndroid Build Coastguard Worker   movl    rINST, %ecx                     # rcx <- BA
1565*795d594fSAndroid Build Coastguard Worker   sarl    $$4, %ecx                       # ecx <- B
1566*795d594fSAndroid Build Coastguard Worker   GET_VREG %ecx, %rcx                     # vB (object we're operating on)
1567*795d594fSAndroid Build Coastguard Worker   testl   %ecx, %ecx                      # is object null?
1568*795d594fSAndroid Build Coastguard Worker   je      common_errNullObject
1569*795d594fSAndroid Build Coastguard Worker   andb    $$0xf,rINSTbl                   # rINST <- A
1570*795d594fSAndroid Build Coastguard Worker   .if \wide
1571*795d594fSAndroid Build Coastguard Worker   movq (%rcx,%rax,1), %rax
1572*795d594fSAndroid Build Coastguard Worker   SET_WIDE_VREG %rax, rINSTq              # fp[A] <- value
1573*795d594fSAndroid Build Coastguard Worker   .else
1574*795d594fSAndroid Build Coastguard Worker   \load (%rcx,%rax,1), %eax
1575*795d594fSAndroid Build Coastguard Worker   SET_VREG %eax, rINSTq                   # fp[A] <- value
1576*795d594fSAndroid Build Coastguard Worker   .endif
1577*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
1578*795d594fSAndroid Build Coastguard Worker2:
1579*795d594fSAndroid Build Coastguard Worker   EXPORT_PC
1580*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_SELF_OFFSET, %rdi
1581*795d594fSAndroid Build Coastguard Worker   movq 0(%rsp), %rsi
1582*795d594fSAndroid Build Coastguard Worker   movq rPC, %rdx
1583*795d594fSAndroid Build Coastguard Worker   movq $$0, %rcx
1584*795d594fSAndroid Build Coastguard Worker   call nterp_get_instance_field_offset
1585*795d594fSAndroid Build Coastguard Worker   testl %eax, %eax
1586*795d594fSAndroid Build Coastguard Worker   jns 1b
1587*795d594fSAndroid Build Coastguard Worker   negl %eax
1588*795d594fSAndroid Build Coastguard Worker   jmp 1b
1589*795d594fSAndroid Build Coastguard Worker.endm
1590*795d594fSAndroid Build Coastguard Worker
1591*795d594fSAndroid Build Coastguard Worker.macro SETUP_REFERENCE_PARAMETER_IN_GPR gpr32, regs, refs, ins, arg_offset, finished
1592*795d594fSAndroid Build Coastguard Worker    movl REG_VAR(gpr32), (REG_VAR(regs), REG_VAR(arg_offset))
1593*795d594fSAndroid Build Coastguard Worker    movl REG_VAR(gpr32), (REG_VAR(refs), REG_VAR(arg_offset))
1594*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(4), REG_VAR(arg_offset)
1595*795d594fSAndroid Build Coastguard Worker    subl MACRO_LITERAL(1), REG_VAR(ins)
1596*795d594fSAndroid Build Coastguard Worker    je \finished
1597*795d594fSAndroid Build Coastguard Worker.endm
1598*795d594fSAndroid Build Coastguard Worker
1599*795d594fSAndroid Build Coastguard Worker// Uses eax as temporary
1600*795d594fSAndroid Build Coastguard Worker.macro SETUP_REFERENCE_PARAMETERS_IN_STACK regs, refs, ins, stack_ptr, arg_offset
1601*795d594fSAndroid Build Coastguard Worker1:
1602*795d594fSAndroid Build Coastguard Worker    movl OFFSET_TO_FIRST_ARGUMENT_IN_STACK(REG_VAR(stack_ptr), REG_VAR(arg_offset)), %eax
1603*795d594fSAndroid Build Coastguard Worker    movl %eax, (REG_VAR(regs), REG_VAR(arg_offset))
1604*795d594fSAndroid Build Coastguard Worker    movl %eax, (REG_VAR(refs), REG_VAR(arg_offset))
1605*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(4), REG_VAR(arg_offset)
1606*795d594fSAndroid Build Coastguard Worker    subl MACRO_LITERAL(1), REG_VAR(ins)
1607*795d594fSAndroid Build Coastguard Worker    jne 1b
1608*795d594fSAndroid Build Coastguard Worker.endm
1609*795d594fSAndroid Build Coastguard Worker
1610*795d594fSAndroid Build Coastguard Worker.macro CHECK_AND_UPDATE_SHARED_MEMORY_METHOD if_hot, if_not_hot
1611*795d594fSAndroid Build Coastguard Worker    testl $$ART_METHOD_IS_MEMORY_SHARED_FLAG, ART_METHOD_ACCESS_FLAGS_OFFSET(%rdi)
1612*795d594fSAndroid Build Coastguard Worker    jz \if_hot
1613*795d594fSAndroid Build Coastguard Worker    // Intrinsics are always in the boot image and considered hot.
1614*795d594fSAndroid Build Coastguard Worker    testl $$ART_METHOD_IS_INTRINSIC_FLAG, ART_METHOD_ACCESS_FLAGS_OFFSET(%rdi)
1615*795d594fSAndroid Build Coastguard Worker    jnz \if_hot
1616*795d594fSAndroid Build Coastguard Worker    movzwl rSELF:THREAD_SHARED_METHOD_HOTNESS_OFFSET, %esi
1617*795d594fSAndroid Build Coastguard Worker    testl %esi, %esi
1618*795d594fSAndroid Build Coastguard Worker    je \if_hot
1619*795d594fSAndroid Build Coastguard Worker    addl $$-1, %esi
1620*795d594fSAndroid Build Coastguard Worker    movw %si, rSELF:THREAD_SHARED_METHOD_HOTNESS_OFFSET
1621*795d594fSAndroid Build Coastguard Worker    jmp \if_not_hot
1622*795d594fSAndroid Build Coastguard Worker.endm
1623*795d594fSAndroid Build Coastguard Worker
1624*795d594fSAndroid Build Coastguard Worker.macro DO_SUSPEND_CHECK continue_label
1625*795d594fSAndroid Build Coastguard Worker    testl   $$(THREAD_SUSPEND_OR_CHECKPOINT_REQUEST), rSELF:THREAD_FLAGS_OFFSET
1626*795d594fSAndroid Build Coastguard Worker    jz      \continue_label
1627*795d594fSAndroid Build Coastguard Worker    EXPORT_PC
1628*795d594fSAndroid Build Coastguard Worker    call    SYMBOL(art_quick_test_suspend)
1629*795d594fSAndroid Build Coastguard Worker.endm
1630*795d594fSAndroid Build Coastguard Worker
1631*795d594fSAndroid Build Coastguard Worker%def entry():
1632*795d594fSAndroid Build Coastguard Worker/*
1633*795d594fSAndroid Build Coastguard Worker * ArtMethod entry point.
1634*795d594fSAndroid Build Coastguard Worker *
1635*795d594fSAndroid Build Coastguard Worker * On entry:
1636*795d594fSAndroid Build Coastguard Worker *  rdi   ArtMethod* callee
1637*795d594fSAndroid Build Coastguard Worker *  rest  method parameters
1638*795d594fSAndroid Build Coastguard Worker */
1639*795d594fSAndroid Build Coastguard Worker
1640*795d594fSAndroid Build Coastguard WorkerOAT_ENTRY ExecuteNterpWithClinitImpl
1641*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
1642*795d594fSAndroid Build Coastguard Worker    // For simplicity, we don't do a read barrier here, but instead rely
1643*795d594fSAndroid Build Coastguard Worker    // on art_quick_resolution_trampoline to always have a suspend point before
1644*795d594fSAndroid Build Coastguard Worker    // calling back here.
1645*795d594fSAndroid Build Coastguard Worker    movl ART_METHOD_DECLARING_CLASS_OFFSET(%rdi), %r10d
1646*795d594fSAndroid Build Coastguard Worker    cmpl $$(MIRROR_CLASS_STATUS_VISIBLY_INITIALIZED_SHIFTED), MIRROR_CLASS_STATUS_OFFSET(%r10d)
1647*795d594fSAndroid Build Coastguard Worker    jae ExecuteNterpImpl
1648*795d594fSAndroid Build Coastguard Worker    cmpl $$(MIRROR_CLASS_STATUS_INITIALIZING_SHIFTED), MIRROR_CLASS_STATUS_OFFSET(%r10d)
1649*795d594fSAndroid Build Coastguard Worker    jb art_quick_resolution_trampoline
1650*795d594fSAndroid Build Coastguard Worker    movl MIRROR_CLASS_CLINIT_THREAD_ID_OFFSET(%r10d), %r10d
1651*795d594fSAndroid Build Coastguard Worker    cmpl %r10d, rSELF:THREAD_TID_OFFSET
1652*795d594fSAndroid Build Coastguard Worker    je ExecuteNterpImpl
1653*795d594fSAndroid Build Coastguard Worker    jmp art_quick_resolution_trampoline
1654*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
1655*795d594fSAndroid Build Coastguard Worker    .global SYMBOL(EndExecuteNterpWithClinitImpl)
1656*795d594fSAndroid Build Coastguard WorkerSYMBOL(EndExecuteNterpWithClinitImpl):
1657*795d594fSAndroid Build Coastguard Worker
1658*795d594fSAndroid Build Coastguard WorkerOAT_ENTRY ExecuteNterpImpl
1659*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
1660*795d594fSAndroid Build Coastguard Worker    .cfi_def_cfa rsp, 8
1661*795d594fSAndroid Build Coastguard Worker    testq %rax, -STACK_OVERFLOW_RESERVED_BYTES(%rsp)
1662*795d594fSAndroid Build Coastguard Worker    /* Spill callee save regs */
1663*795d594fSAndroid Build Coastguard Worker    SPILL_ALL_CALLEE_SAVES
1664*795d594fSAndroid Build Coastguard Worker
1665*795d594fSAndroid Build Coastguard Worker    movq ART_METHOD_DATA_OFFSET_64(%rdi), rPC
1666*795d594fSAndroid Build Coastguard Worker
1667*795d594fSAndroid Build Coastguard Worker    // Setup the stack for executing the method.
1668*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FRAME rPC, rREFS, rREFS32, rFP, CFI_REFS, load_ins=1
1669*795d594fSAndroid Build Coastguard Worker
1670*795d594fSAndroid Build Coastguard Worker    // Setup the parameters
1671*795d594fSAndroid Build Coastguard Worker    testl %r14d, %r14d
1672*795d594fSAndroid Build Coastguard Worker    je .Lxmm_setup_finished
1673*795d594fSAndroid Build Coastguard Worker
1674*795d594fSAndroid Build Coastguard Worker    subq %r14, %rbx
1675*795d594fSAndroid Build Coastguard Worker    salq $$2, %rbx // rbx is now the offset for inputs into the registers array.
1676*795d594fSAndroid Build Coastguard Worker
1677*795d594fSAndroid Build Coastguard Worker    testl $$ART_METHOD_NTERP_ENTRY_POINT_FAST_PATH_FLAG, ART_METHOD_ACCESS_FLAGS_OFFSET(%rdi)
1678*795d594fSAndroid Build Coastguard Worker    je .Lsetup_slow_path
1679*795d594fSAndroid Build Coastguard Worker    leaq (rFP, %rbx, 1), %rdi
1680*795d594fSAndroid Build Coastguard Worker    leaq (rREFS, %rbx, 1), %rbx
1681*795d594fSAndroid Build Coastguard Worker    movq $$0, %r10
1682*795d594fSAndroid Build Coastguard Worker
1683*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETER_IN_GPR esi, rdi, rbx, r14d, r10, .Lxmm_setup_finished
1684*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETER_IN_GPR edx, rdi, rbx, r14d, r10, .Lxmm_setup_finished
1685*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETER_IN_GPR ecx, rdi, rbx, r14d, r10, .Lxmm_setup_finished
1686*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETER_IN_GPR r8d, rdi, rbx, r14d, r10, .Lxmm_setup_finished
1687*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETER_IN_GPR r9d, rdi, rbx, r14d, r10, .Lxmm_setup_finished
1688*795d594fSAndroid Build Coastguard Worker    SETUP_REFERENCE_PARAMETERS_IN_STACK rdi, rbx, r14d, r11, r10
1689*795d594fSAndroid Build Coastguard Worker    jmp .Lxmm_setup_finished
1690*795d594fSAndroid Build Coastguard Worker
1691*795d594fSAndroid Build Coastguard Worker.Lsetup_slow_path:
1692*795d594fSAndroid Build Coastguard Worker    // If the method is not static and there is one argument ('this'), we don't need to fetch the
1693*795d594fSAndroid Build Coastguard Worker    // shorty.
1694*795d594fSAndroid Build Coastguard Worker    testl $$ART_METHOD_IS_STATIC_FLAG, ART_METHOD_ACCESS_FLAGS_OFFSET(%rdi)
1695*795d594fSAndroid Build Coastguard Worker    jne .Lsetup_with_shorty
1696*795d594fSAndroid Build Coastguard Worker
1697*795d594fSAndroid Build Coastguard Worker    movl %esi, (rFP, %rbx)
1698*795d594fSAndroid Build Coastguard Worker    movl %esi, (rREFS, %rbx)
1699*795d594fSAndroid Build Coastguard Worker
1700*795d594fSAndroid Build Coastguard Worker    cmpl $$1, %r14d
1701*795d594fSAndroid Build Coastguard Worker    je .Lxmm_setup_finished
1702*795d594fSAndroid Build Coastguard Worker
1703*795d594fSAndroid Build Coastguard Worker.Lsetup_with_shorty:
1704*795d594fSAndroid Build Coastguard Worker    // TODO: Get shorty in a better way and remove below
1705*795d594fSAndroid Build Coastguard Worker    push %rdi
1706*795d594fSAndroid Build Coastguard Worker    push %rsi
1707*795d594fSAndroid Build Coastguard Worker    push %rdx
1708*795d594fSAndroid Build Coastguard Worker    push %rcx
1709*795d594fSAndroid Build Coastguard Worker    push %r8
1710*795d594fSAndroid Build Coastguard Worker    push %r9
1711*795d594fSAndroid Build Coastguard Worker
1712*795d594fSAndroid Build Coastguard Worker    // Save xmm registers + alignment.
1713*795d594fSAndroid Build Coastguard Worker    subq MACRO_LITERAL(8 * 8 + 8), %rsp
1714*795d594fSAndroid Build Coastguard Worker    movq %xmm0, 0(%rsp)
1715*795d594fSAndroid Build Coastguard Worker    movq %xmm1, 8(%rsp)
1716*795d594fSAndroid Build Coastguard Worker    movq %xmm2, 16(%rsp)
1717*795d594fSAndroid Build Coastguard Worker    movq %xmm3, 24(%rsp)
1718*795d594fSAndroid Build Coastguard Worker    movq %xmm4, 32(%rsp)
1719*795d594fSAndroid Build Coastguard Worker    movq %xmm5, 40(%rsp)
1720*795d594fSAndroid Build Coastguard Worker    movq %xmm6, 48(%rsp)
1721*795d594fSAndroid Build Coastguard Worker    movq %xmm7, 56(%rsp)
1722*795d594fSAndroid Build Coastguard Worker
1723*795d594fSAndroid Build Coastguard Worker    call SYMBOL(NterpGetShorty)
1724*795d594fSAndroid Build Coastguard Worker    // Save shorty in callee-save rbp.
1725*795d594fSAndroid Build Coastguard Worker    movq %rax, %rbp
1726*795d594fSAndroid Build Coastguard Worker
1727*795d594fSAndroid Build Coastguard Worker    // Restore xmm registers + alignment.
1728*795d594fSAndroid Build Coastguard Worker    movq 0(%rsp), %xmm0
1729*795d594fSAndroid Build Coastguard Worker    movq 8(%rsp), %xmm1
1730*795d594fSAndroid Build Coastguard Worker    movq 16(%rsp), %xmm2
1731*795d594fSAndroid Build Coastguard Worker    movq 24(%rsp), %xmm3
1732*795d594fSAndroid Build Coastguard Worker    movq 32(%rsp), %xmm4
1733*795d594fSAndroid Build Coastguard Worker    movq 40(%rsp), %xmm5
1734*795d594fSAndroid Build Coastguard Worker    movq 48(%rsp), %xmm6
1735*795d594fSAndroid Build Coastguard Worker    movq 56(%rsp), %xmm7
1736*795d594fSAndroid Build Coastguard Worker    addq MACRO_LITERAL(8 * 8 + 8), %rsp
1737*795d594fSAndroid Build Coastguard Worker
1738*795d594fSAndroid Build Coastguard Worker    pop %r9
1739*795d594fSAndroid Build Coastguard Worker    pop %r8
1740*795d594fSAndroid Build Coastguard Worker    pop %rcx
1741*795d594fSAndroid Build Coastguard Worker    pop %rdx
1742*795d594fSAndroid Build Coastguard Worker    pop %rsi
1743*795d594fSAndroid Build Coastguard Worker    pop %rdi
1744*795d594fSAndroid Build Coastguard Worker    // Reload the old stack pointer, which used to be stored in %r11, which is not callee-saved.
1745*795d594fSAndroid Build Coastguard Worker    movq -8(rREFS), %r11
1746*795d594fSAndroid Build Coastguard Worker    // TODO: Get shorty in a better way and remove above
1747*795d594fSAndroid Build Coastguard Worker
1748*795d594fSAndroid Build Coastguard Worker    movq $$0, %r14
1749*795d594fSAndroid Build Coastguard Worker    testl $$ART_METHOD_IS_STATIC_FLAG, ART_METHOD_ACCESS_FLAGS_OFFSET(%rdi)
1750*795d594fSAndroid Build Coastguard Worker
1751*795d594fSAndroid Build Coastguard Worker    // Available: rdi, r10
1752*795d594fSAndroid Build Coastguard Worker    // Note the leaq below don't change the flags.
1753*795d594fSAndroid Build Coastguard Worker    leaq 1(%rbp), %r10  // shorty + 1  ; ie skip return arg character
1754*795d594fSAndroid Build Coastguard Worker    leaq (rFP, %rbx, 1), %rdi
1755*795d594fSAndroid Build Coastguard Worker    leaq (rREFS, %rbx, 1), %rbx
1756*795d594fSAndroid Build Coastguard Worker    jne .Lhandle_static_method
1757*795d594fSAndroid Build Coastguard Worker    addq $$4, %rdi
1758*795d594fSAndroid Build Coastguard Worker    addq $$4, %rbx
1759*795d594fSAndroid Build Coastguard Worker    addq $$4, %r11
1760*795d594fSAndroid Build Coastguard Worker    jmp .Lcontinue_setup_gprs
1761*795d594fSAndroid Build Coastguard Worker.Lhandle_static_method:
1762*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_GPRS rsi, esi, r10, r14, rdi, rbx, .Lgpr_setup_finished
1763*795d594fSAndroid Build Coastguard Worker.Lcontinue_setup_gprs:
1764*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_GPRS rdx, edx, r10, r14, rdi, rbx, .Lgpr_setup_finished
1765*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_GPRS rcx, ecx, r10, r14, rdi, rbx, .Lgpr_setup_finished
1766*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_GPRS r8, r8d, r10, r14, rdi, rbx, .Lgpr_setup_finished
1767*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_GPRS r9, r9d, r10, r14, rdi, rbx, .Lgpr_setup_finished
1768*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_INTs r10, r14, rdi, rbx, r11, .Lgpr_setup_finished
1769*795d594fSAndroid Build Coastguard Worker.Lgpr_setup_finished:
1770*795d594fSAndroid Build Coastguard Worker    leaq 1(%rbp), %r10  // shorty + 1  ; ie skip return arg character
1771*795d594fSAndroid Build Coastguard Worker    movq $$0, %r14 // reset counter
1772*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_XMMS xmm0, r10, r14, rdi, .Lxmm_setup_finished
1773*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_XMMS xmm1, r10, r14, rdi, .Lxmm_setup_finished
1774*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_XMMS xmm2, r10, r14, rdi, .Lxmm_setup_finished
1775*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_XMMS xmm3, r10, r14, rdi, .Lxmm_setup_finished
1776*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_XMMS xmm4, r10, r14, rdi, .Lxmm_setup_finished
1777*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_XMMS xmm5, r10, r14, rdi, .Lxmm_setup_finished
1778*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_XMMS xmm6, r10, r14, rdi, .Lxmm_setup_finished
1779*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_SHORTY_STORING_XMMS xmm7, r10, r14, rdi, .Lxmm_setup_finished
1780*795d594fSAndroid Build Coastguard Worker    LOOP_OVER_FPs r10, r14, rdi, r11, .Lxmm_setup_finished
1781*795d594fSAndroid Build Coastguard Worker.Lxmm_setup_finished:
1782*795d594fSAndroid Build Coastguard Worker    CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0)
1783*795d594fSAndroid Build Coastguard Worker
1784*795d594fSAndroid Build Coastguard Worker    // Set rIBASE
1785*795d594fSAndroid Build Coastguard Worker    leaq artNterpAsmInstructionStart(%rip), rIBASE
1786*795d594fSAndroid Build Coastguard Worker    /* start executing the instruction at rPC */
1787*795d594fSAndroid Build Coastguard Worker    START_EXECUTING_INSTRUCTIONS
1788*795d594fSAndroid Build Coastguard Worker    /* NOTE: no fallthrough */
1789*795d594fSAndroid Build Coastguard Worker    // cfi info continues, and covers the whole nterp implementation.
1790*795d594fSAndroid Build Coastguard Worker    END ExecuteNterpImpl
1791*795d594fSAndroid Build Coastguard Worker
1792*795d594fSAndroid Build Coastguard Worker%def opcode_pre():
1793*795d594fSAndroid Build Coastguard Worker
1794*795d594fSAndroid Build Coastguard Worker%def fetch_from_thread_cache(dest_reg, miss_label):
1795*795d594fSAndroid Build Coastguard Worker   // Fetch some information from the thread cache.
1796*795d594fSAndroid Build Coastguard Worker   // Uses rax, rdx, rcx as temporaries.
1797*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_SELF_OFFSET, %rax
1798*795d594fSAndroid Build Coastguard Worker   movq rPC, %rdx
1799*795d594fSAndroid Build Coastguard Worker   salq MACRO_LITERAL(THREAD_INTERPRETER_CACHE_SIZE_SHIFT), %rdx
1800*795d594fSAndroid Build Coastguard Worker   andq MACRO_LITERAL(THREAD_INTERPRETER_CACHE_SIZE_MASK), %rdx
1801*795d594fSAndroid Build Coastguard Worker   cmpq THREAD_INTERPRETER_CACHE_OFFSET(%rax, %rdx, 1), rPC
1802*795d594fSAndroid Build Coastguard Worker   jne ${miss_label}
1803*795d594fSAndroid Build Coastguard Worker   movq __SIZEOF_POINTER__+THREAD_INTERPRETER_CACHE_OFFSET(%rax, %rdx, 1), ${dest_reg}
1804*795d594fSAndroid Build Coastguard Worker
1805*795d594fSAndroid Build Coastguard Worker%def footer():
1806*795d594fSAndroid Build Coastguard Worker/*
1807*795d594fSAndroid Build Coastguard Worker * ===========================================================================
1808*795d594fSAndroid Build Coastguard Worker *  Common subroutines and data
1809*795d594fSAndroid Build Coastguard Worker * ===========================================================================
1810*795d594fSAndroid Build Coastguard Worker */
1811*795d594fSAndroid Build Coastguard Worker
1812*795d594fSAndroid Build Coastguard Worker    .text
1813*795d594fSAndroid Build Coastguard Worker    .align  2
1814*795d594fSAndroid Build Coastguard Worker
1815*795d594fSAndroid Build Coastguard Worker// Enclose all code below in a symbol (which gets printed in backtraces).
1816*795d594fSAndroid Build Coastguard WorkerENTRY nterp_helper
1817*795d594fSAndroid Build Coastguard Worker
1818*795d594fSAndroid Build Coastguard Worker// Note: mterp also uses the common_* names below for helpers, but that's OK
1819*795d594fSAndroid Build Coastguard Worker// as the C compiler compiled each interpreter separately.
1820*795d594fSAndroid Build Coastguard Workercommon_errDivideByZero:
1821*795d594fSAndroid Build Coastguard Worker    EXPORT_PC
1822*795d594fSAndroid Build Coastguard Worker    call art_quick_throw_div_zero
1823*795d594fSAndroid Build Coastguard Worker
1824*795d594fSAndroid Build Coastguard Worker// Expect array in edi, index in esi.
1825*795d594fSAndroid Build Coastguard Workercommon_errArrayIndex:
1826*795d594fSAndroid Build Coastguard Worker    EXPORT_PC
1827*795d594fSAndroid Build Coastguard Worker    movl MIRROR_ARRAY_LENGTH_OFFSET(%edi), %eax
1828*795d594fSAndroid Build Coastguard Worker    movl %esi, %edi
1829*795d594fSAndroid Build Coastguard Worker    movl %eax, %esi
1830*795d594fSAndroid Build Coastguard Worker    call art_quick_throw_array_bounds
1831*795d594fSAndroid Build Coastguard Worker
1832*795d594fSAndroid Build Coastguard Workercommon_errNullObject:
1833*795d594fSAndroid Build Coastguard Worker    EXPORT_PC
1834*795d594fSAndroid Build Coastguard Worker    call art_quick_throw_null_pointer_exception
1835*795d594fSAndroid Build Coastguard Worker
1836*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeStatic:
1837*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_NON_RANGE is_static=1, is_interface=0, suffix="invokeStatic"
1838*795d594fSAndroid Build Coastguard Worker
1839*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeStaticRange:
1840*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_RANGE is_static=1, is_interface=0, suffix="invokeStatic"
1841*795d594fSAndroid Build Coastguard Worker
1842*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeInstance:
1843*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_NON_RANGE is_static=0, is_interface=0, suffix="invokeInstance"
1844*795d594fSAndroid Build Coastguard Worker
1845*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeInstanceRange:
1846*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_RANGE is_static=0, is_interface=0, suffix="invokeInstance"
1847*795d594fSAndroid Build Coastguard Worker
1848*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeInterface:
1849*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_NON_RANGE is_static=0, is_interface=1, suffix="invokeInterface"
1850*795d594fSAndroid Build Coastguard Worker
1851*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeInterfaceRange:
1852*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_RANGE is_static=0, is_interface=1, suffix="invokeInterface"
1853*795d594fSAndroid Build Coastguard Worker
1854*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokePolymorphic:
1855*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_NON_RANGE is_static=0, is_interface=0, is_string_init=0, is_polymorphic=1, suffix="invokePolymorphic"
1856*795d594fSAndroid Build Coastguard Worker
1857*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokePolymorphicRange:
1858*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_RANGE is_static=0, is_interface=0, is_polymorphic=1, suffix="invokePolymorphic"
1859*795d594fSAndroid Build Coastguard Worker
1860*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeCustom:
1861*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_NON_RANGE is_static=1, is_interface=0, is_string_init=0, is_polymorphic=0, is_custom=1, suffix="invokeCustom"
1862*795d594fSAndroid Build Coastguard Worker
1863*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeCustomRange:
1864*795d594fSAndroid Build Coastguard Worker    COMMON_INVOKE_RANGE is_static=1, is_interface=0, is_polymorphic=0, is_custom=1, suffix="invokeCustom"
1865*795d594fSAndroid Build Coastguard Worker
1866*795d594fSAndroid Build Coastguard WorkerNterpHandleStringInit:
1867*795d594fSAndroid Build Coastguard Worker   COMMON_INVOKE_NON_RANGE is_static=0, is_interface=0, is_string_init=1, suffix="stringInit"
1868*795d594fSAndroid Build Coastguard Worker
1869*795d594fSAndroid Build Coastguard WorkerNterpHandleStringInitRange:
1870*795d594fSAndroid Build Coastguard Worker   COMMON_INVOKE_RANGE is_static=0, is_interface=0, is_string_init=1, suffix="stringInit"
1871*795d594fSAndroid Build Coastguard Worker
1872*795d594fSAndroid Build Coastguard WorkerNterpNewInstance:
1873*795d594fSAndroid Build Coastguard Worker   EXPORT_PC
1874*795d594fSAndroid Build Coastguard Worker   // Fast-path which gets the class from thread-local cache.
1875*795d594fSAndroid Build Coastguard Worker%  fetch_from_thread_cache("%rdi", miss_label="2f")
1876*795d594fSAndroid Build Coastguard Worker   cmpq $$0, rSELF:THREAD_READ_BARRIER_MARK_REG00_OFFSET
1877*795d594fSAndroid Build Coastguard Worker   jne 3f
1878*795d594fSAndroid Build Coastguard Worker4:
1879*795d594fSAndroid Build Coastguard Worker   callq *rSELF:THREAD_ALLOC_OBJECT_ENTRYPOINT_OFFSET
1880*795d594fSAndroid Build Coastguard Worker1:
1881*795d594fSAndroid Build Coastguard Worker   SET_VREG_OBJECT %eax, rINSTq            # fp[A] <- value
1882*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
1883*795d594fSAndroid Build Coastguard Worker2:
1884*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_SELF_OFFSET, %rdi
1885*795d594fSAndroid Build Coastguard Worker   movq 0(%rsp), %rsi
1886*795d594fSAndroid Build Coastguard Worker   movq rPC, %rdx
1887*795d594fSAndroid Build Coastguard Worker   call nterp_allocate_object
1888*795d594fSAndroid Build Coastguard Worker   jmp 1b
1889*795d594fSAndroid Build Coastguard Worker3:
1890*795d594fSAndroid Build Coastguard Worker   // 07 is %rdi
1891*795d594fSAndroid Build Coastguard Worker   call art_quick_read_barrier_mark_reg07
1892*795d594fSAndroid Build Coastguard Worker   jmp 4b
1893*795d594fSAndroid Build Coastguard Worker
1894*795d594fSAndroid Build Coastguard WorkerNterpNewArray:
1895*795d594fSAndroid Build Coastguard Worker   /* new-array vA, vB, class@CCCC */
1896*795d594fSAndroid Build Coastguard Worker   EXPORT_PC
1897*795d594fSAndroid Build Coastguard Worker   // Fast-path which gets the class from thread-local cache.
1898*795d594fSAndroid Build Coastguard Worker%  fetch_from_thread_cache("%rdi", miss_label="2f")
1899*795d594fSAndroid Build Coastguard Worker   cmpq $$0, rSELF:THREAD_READ_BARRIER_MARK_REG00_OFFSET
1900*795d594fSAndroid Build Coastguard Worker   jne 3f
1901*795d594fSAndroid Build Coastguard Worker1:
1902*795d594fSAndroid Build Coastguard Worker   movzbl  rINSTbl,%esi
1903*795d594fSAndroid Build Coastguard Worker   sarl    $$4,%esi                          # esi<- B
1904*795d594fSAndroid Build Coastguard Worker   GET_VREG %esi %rsi                        # esi<- vB (array length)
1905*795d594fSAndroid Build Coastguard Worker   andb    $$0xf,rINSTbl                     # rINST<- A
1906*795d594fSAndroid Build Coastguard Worker   callq *rSELF:THREAD_ALLOC_ARRAY_ENTRYPOINT_OFFSET
1907*795d594fSAndroid Build Coastguard Worker   SET_VREG_OBJECT %eax, rINSTq            # fp[A] <- value
1908*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
1909*795d594fSAndroid Build Coastguard Worker2:
1910*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_SELF_OFFSET, %rdi
1911*795d594fSAndroid Build Coastguard Worker   movq 0(%rsp), %rsi
1912*795d594fSAndroid Build Coastguard Worker   movq rPC, %rdx
1913*795d594fSAndroid Build Coastguard Worker   call nterp_get_class
1914*795d594fSAndroid Build Coastguard Worker   movq %rax, %rdi
1915*795d594fSAndroid Build Coastguard Worker   jmp 1b
1916*795d594fSAndroid Build Coastguard Worker3:
1917*795d594fSAndroid Build Coastguard Worker   // 07 is %rdi
1918*795d594fSAndroid Build Coastguard Worker   call art_quick_read_barrier_mark_reg07
1919*795d594fSAndroid Build Coastguard Worker   jmp 1b
1920*795d594fSAndroid Build Coastguard Worker
1921*795d594fSAndroid Build Coastguard WorkerNterpPutObjectInstanceField:
1922*795d594fSAndroid Build Coastguard Worker   movl    rINST, %ebp                     # rbp <- BA
1923*795d594fSAndroid Build Coastguard Worker   andl    $$0xf, %ebp                     # rbp <- A
1924*795d594fSAndroid Build Coastguard Worker   GET_VREG %ecx, %rbp                     # ecx <- v[A]
1925*795d594fSAndroid Build Coastguard Worker   sarl    $$4, rINST
1926*795d594fSAndroid Build Coastguard Worker   // Fast-path which gets the field from thread-local cache.
1927*795d594fSAndroid Build Coastguard Worker%  fetch_from_thread_cache("%rax", miss_label="2f")
1928*795d594fSAndroid Build Coastguard Worker1:
1929*795d594fSAndroid Build Coastguard Worker   GET_VREG rINST, rINSTq                  # vB (object we're operating on)
1930*795d594fSAndroid Build Coastguard Worker   testl   rINST, rINST                    # is object null?
1931*795d594fSAndroid Build Coastguard Worker   je      common_errNullObject
1932*795d594fSAndroid Build Coastguard Worker   POISON_HEAP_REF ecx
1933*795d594fSAndroid Build Coastguard Worker   movl %ecx, (rINSTq,%rax,1)
1934*795d594fSAndroid Build Coastguard Worker   testl %ecx, %ecx
1935*795d594fSAndroid Build Coastguard Worker   je 4f
1936*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_CARD_TABLE_OFFSET, %rax
1937*795d594fSAndroid Build Coastguard Worker   shrq $$CARD_TABLE_CARD_SHIFT, rINSTq
1938*795d594fSAndroid Build Coastguard Worker   movb %al, (%rax, rINSTq, 1)
1939*795d594fSAndroid Build Coastguard Worker4:
1940*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
1941*795d594fSAndroid Build Coastguard Worker2:
1942*795d594fSAndroid Build Coastguard Worker   EXPORT_PC
1943*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_SELF_OFFSET, %rdi
1944*795d594fSAndroid Build Coastguard Worker   movq 0(%rsp), %rsi
1945*795d594fSAndroid Build Coastguard Worker   movq rPC, %rdx
1946*795d594fSAndroid Build Coastguard Worker   // %rcx is already set.
1947*795d594fSAndroid Build Coastguard Worker   call nterp_get_instance_field_offset
1948*795d594fSAndroid Build Coastguard Worker   // Reload the value as it may have moved.
1949*795d594fSAndroid Build Coastguard Worker   GET_VREG %ecx, %rbp                     # ecx <- v[A]
1950*795d594fSAndroid Build Coastguard Worker   testl %eax, %eax
1951*795d594fSAndroid Build Coastguard Worker   jns 1b
1952*795d594fSAndroid Build Coastguard Worker   GET_VREG rINST, rINSTq                  # vB (object we're operating on)
1953*795d594fSAndroid Build Coastguard Worker   testl   rINST, rINST                    # is object null?
1954*795d594fSAndroid Build Coastguard Worker   je      common_errNullObject
1955*795d594fSAndroid Build Coastguard Worker   negl %eax
1956*795d594fSAndroid Build Coastguard Worker   POISON_HEAP_REF ecx
1957*795d594fSAndroid Build Coastguard Worker   movl %ecx, (rINSTq,%rax,1)
1958*795d594fSAndroid Build Coastguard Worker   testl %ecx, %ecx
1959*795d594fSAndroid Build Coastguard Worker   je 5f
1960*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_CARD_TABLE_OFFSET, %rax
1961*795d594fSAndroid Build Coastguard Worker   shrq $$CARD_TABLE_CARD_SHIFT, rINSTq
1962*795d594fSAndroid Build Coastguard Worker   movb %al, (%rax, rINSTq, 1)
1963*795d594fSAndroid Build Coastguard Worker5:
1964*795d594fSAndroid Build Coastguard Worker   lock addl $$0, (%rsp)
1965*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
1966*795d594fSAndroid Build Coastguard Worker
1967*795d594fSAndroid Build Coastguard WorkerNterpGetObjectInstanceField:
1968*795d594fSAndroid Build Coastguard Worker   // Fast-path which gets the field from thread-local cache.
1969*795d594fSAndroid Build Coastguard Worker%  fetch_from_thread_cache("%rax", miss_label="2f")
1970*795d594fSAndroid Build Coastguard Worker1:
1971*795d594fSAndroid Build Coastguard Worker   movl    rINST, %ecx                     # rcx <- BA
1972*795d594fSAndroid Build Coastguard Worker   sarl    $$4, %ecx                       # ecx <- B
1973*795d594fSAndroid Build Coastguard Worker   GET_VREG %ecx, %rcx                     # vB (object we're operating on)
1974*795d594fSAndroid Build Coastguard Worker   testl   %ecx, %ecx                      # is object null?
1975*795d594fSAndroid Build Coastguard Worker   je      common_errNullObject
1976*795d594fSAndroid Build Coastguard Worker   testb $$READ_BARRIER_TEST_VALUE, GRAY_BYTE_OFFSET(%ecx)
1977*795d594fSAndroid Build Coastguard Worker   movl (%rcx,%rax,1), %eax
1978*795d594fSAndroid Build Coastguard Worker   jnz 3f
1979*795d594fSAndroid Build Coastguard Worker   UNPOISON_HEAP_REF eax  // Affects flags, so we cannot unpoison before the jnz.
1980*795d594fSAndroid Build Coastguard Worker4:
1981*795d594fSAndroid Build Coastguard Worker   andb    $$0xf,rINSTbl                   # rINST <- A
1982*795d594fSAndroid Build Coastguard Worker   SET_VREG_OBJECT %eax, rINSTq            # fp[A] <- value
1983*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
1984*795d594fSAndroid Build Coastguard Worker2:
1985*795d594fSAndroid Build Coastguard Worker   EXPORT_PC
1986*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_SELF_OFFSET, %rdi
1987*795d594fSAndroid Build Coastguard Worker   movq 0(%rsp), %rsi
1988*795d594fSAndroid Build Coastguard Worker   movq rPC, %rdx
1989*795d594fSAndroid Build Coastguard Worker   movq $$0, %rcx
1990*795d594fSAndroid Build Coastguard Worker   call nterp_get_instance_field_offset
1991*795d594fSAndroid Build Coastguard Worker   testl %eax, %eax
1992*795d594fSAndroid Build Coastguard Worker   jns 1b
1993*795d594fSAndroid Build Coastguard Worker   // For volatile fields, we return a negative offset. Remove the sign
1994*795d594fSAndroid Build Coastguard Worker   // and no need for any barrier thanks to the memory model.
1995*795d594fSAndroid Build Coastguard Worker   negl %eax
1996*795d594fSAndroid Build Coastguard Worker   jmp 1b
1997*795d594fSAndroid Build Coastguard Worker3:
1998*795d594fSAndroid Build Coastguard Worker   UNPOISON_HEAP_REF eax
1999*795d594fSAndroid Build Coastguard Worker   // reg00 is eax
2000*795d594fSAndroid Build Coastguard Worker   call art_quick_read_barrier_mark_reg00
2001*795d594fSAndroid Build Coastguard Worker   jmp 4b
2002*795d594fSAndroid Build Coastguard Worker
2003*795d594fSAndroid Build Coastguard WorkerNterpPutObjectStaticField:
2004*795d594fSAndroid Build Coastguard Worker   GET_VREG %ebp, rINSTq
2005*795d594fSAndroid Build Coastguard Worker   // Fast-path which gets the field from thread-local cache.
2006*795d594fSAndroid Build Coastguard Worker%  fetch_from_thread_cache("%rax", miss_label="2f")
2007*795d594fSAndroid Build Coastguard Worker1:
2008*795d594fSAndroid Build Coastguard Worker   movl ART_FIELD_OFFSET_OFFSET(%rax), %edx
2009*795d594fSAndroid Build Coastguard Worker   movl ART_FIELD_DECLARING_CLASS_OFFSET(%rax), %eax
2010*795d594fSAndroid Build Coastguard Worker   cmpq $$0, rSELF:THREAD_READ_BARRIER_MARK_REG00_OFFSET
2011*795d594fSAndroid Build Coastguard Worker   jne 3f
2012*795d594fSAndroid Build Coastguard Worker5:
2013*795d594fSAndroid Build Coastguard Worker   POISON_HEAP_REF ebp
2014*795d594fSAndroid Build Coastguard Worker   movl %ebp, (%eax, %edx, 1)
2015*795d594fSAndroid Build Coastguard Worker   testl %ebp, %ebp
2016*795d594fSAndroid Build Coastguard Worker   je 4f
2017*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_CARD_TABLE_OFFSET, %rcx
2018*795d594fSAndroid Build Coastguard Worker   shrq $$CARD_TABLE_CARD_SHIFT, %rax
2019*795d594fSAndroid Build Coastguard Worker   movb %cl, (%rax, %rcx, 1)
2020*795d594fSAndroid Build Coastguard Worker4:
2021*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
2022*795d594fSAndroid Build Coastguard Worker2:
2023*795d594fSAndroid Build Coastguard Worker   EXPORT_PC
2024*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_SELF_OFFSET, %rdi
2025*795d594fSAndroid Build Coastguard Worker   movq 0(%rsp), %rsi
2026*795d594fSAndroid Build Coastguard Worker   movq rPC, %rdx
2027*795d594fSAndroid Build Coastguard Worker   movq %rbp, %rcx
2028*795d594fSAndroid Build Coastguard Worker   call nterp_get_static_field
2029*795d594fSAndroid Build Coastguard Worker   // Reload the value as it may have moved.
2030*795d594fSAndroid Build Coastguard Worker   GET_VREG %ebp, rINSTq
2031*795d594fSAndroid Build Coastguard Worker   testq MACRO_LITERAL(1), %rax
2032*795d594fSAndroid Build Coastguard Worker   je 1b
2033*795d594fSAndroid Build Coastguard Worker   CLEAR_VOLATILE_MARKER %rax
2034*795d594fSAndroid Build Coastguard Worker   movl ART_FIELD_OFFSET_OFFSET(%rax), %edx
2035*795d594fSAndroid Build Coastguard Worker   movl ART_FIELD_DECLARING_CLASS_OFFSET(%rax), %eax
2036*795d594fSAndroid Build Coastguard Worker   cmpq $$0, rSELF:THREAD_READ_BARRIER_MARK_REG00_OFFSET
2037*795d594fSAndroid Build Coastguard Worker   jne 7f
2038*795d594fSAndroid Build Coastguard Worker6:
2039*795d594fSAndroid Build Coastguard Worker   POISON_HEAP_REF ebp
2040*795d594fSAndroid Build Coastguard Worker   movl %ebp, (%eax, %edx, 1)
2041*795d594fSAndroid Build Coastguard Worker   testl %ebp, %ebp
2042*795d594fSAndroid Build Coastguard Worker   je 8f
2043*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_CARD_TABLE_OFFSET, %rcx
2044*795d594fSAndroid Build Coastguard Worker   shrq $$CARD_TABLE_CARD_SHIFT, %rax
2045*795d594fSAndroid Build Coastguard Worker   movb %cl, (%rax, %rcx, 1)
2046*795d594fSAndroid Build Coastguard Worker8:
2047*795d594fSAndroid Build Coastguard Worker   lock addl $$0, (%rsp)
2048*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
2049*795d594fSAndroid Build Coastguard Worker3:
2050*795d594fSAndroid Build Coastguard Worker   call art_quick_read_barrier_mark_reg00
2051*795d594fSAndroid Build Coastguard Worker   jmp 5b
2052*795d594fSAndroid Build Coastguard Worker7:
2053*795d594fSAndroid Build Coastguard Worker   call art_quick_read_barrier_mark_reg00
2054*795d594fSAndroid Build Coastguard Worker   jmp 6b
2055*795d594fSAndroid Build Coastguard Worker
2056*795d594fSAndroid Build Coastguard WorkerNterpGetObjectStaticField:
2057*795d594fSAndroid Build Coastguard Worker   // Fast-path which gets the field from thread-local cache.
2058*795d594fSAndroid Build Coastguard Worker%  fetch_from_thread_cache("%rax", miss_label="2f")
2059*795d594fSAndroid Build Coastguard Worker1:
2060*795d594fSAndroid Build Coastguard Worker   movl ART_FIELD_OFFSET_OFFSET(%rax), %edx
2061*795d594fSAndroid Build Coastguard Worker   movl ART_FIELD_DECLARING_CLASS_OFFSET(%rax), %eax
2062*795d594fSAndroid Build Coastguard Worker   cmpq $$0, rSELF:THREAD_READ_BARRIER_MARK_REG00_OFFSET
2063*795d594fSAndroid Build Coastguard Worker   jne 5f
2064*795d594fSAndroid Build Coastguard Worker6:
2065*795d594fSAndroid Build Coastguard Worker   testb $$READ_BARRIER_TEST_VALUE, GRAY_BYTE_OFFSET(%eax)
2066*795d594fSAndroid Build Coastguard Worker   movl (%eax, %edx, 1), %eax
2067*795d594fSAndroid Build Coastguard Worker   jnz 3f
2068*795d594fSAndroid Build Coastguard Worker   UNPOISON_HEAP_REF eax  // Affects flags, so we cannot unpoison before the jnz.
2069*795d594fSAndroid Build Coastguard Worker4:
2070*795d594fSAndroid Build Coastguard Worker   SET_VREG_OBJECT %eax, rINSTq            # fp[A] <- value
2071*795d594fSAndroid Build Coastguard Worker   ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
2072*795d594fSAndroid Build Coastguard Worker2:
2073*795d594fSAndroid Build Coastguard Worker   EXPORT_PC
2074*795d594fSAndroid Build Coastguard Worker   movq rSELF:THREAD_SELF_OFFSET, %rdi
2075*795d594fSAndroid Build Coastguard Worker   movq 0(%rsp), %rsi
2076*795d594fSAndroid Build Coastguard Worker   movq rPC, %rdx
2077*795d594fSAndroid Build Coastguard Worker   movq $$0, %rcx
2078*795d594fSAndroid Build Coastguard Worker   call nterp_get_static_field
2079*795d594fSAndroid Build Coastguard Worker   andq $$-2, %rax
2080*795d594fSAndroid Build Coastguard Worker   jmp 1b
2081*795d594fSAndroid Build Coastguard Worker3:
2082*795d594fSAndroid Build Coastguard Worker   UNPOISON_HEAP_REF eax
2083*795d594fSAndroid Build Coastguard Worker   call art_quick_read_barrier_mark_reg00
2084*795d594fSAndroid Build Coastguard Worker   jmp 4b
2085*795d594fSAndroid Build Coastguard Worker5:
2086*795d594fSAndroid Build Coastguard Worker   call art_quick_read_barrier_mark_reg00
2087*795d594fSAndroid Build Coastguard Worker   jmp 6b
2088*795d594fSAndroid Build Coastguard Worker
2089*795d594fSAndroid Build Coastguard WorkerNterpGetBooleanStaticField:
2090*795d594fSAndroid Build Coastguard Worker  OP_SGET load="movsbl", wide=0
2091*795d594fSAndroid Build Coastguard Worker
2092*795d594fSAndroid Build Coastguard WorkerNterpGetByteStaticField:
2093*795d594fSAndroid Build Coastguard Worker  OP_SGET load="movsbl", wide=0
2094*795d594fSAndroid Build Coastguard Worker
2095*795d594fSAndroid Build Coastguard WorkerNterpGetCharStaticField:
2096*795d594fSAndroid Build Coastguard Worker  OP_SGET load="movzwl", wide=0
2097*795d594fSAndroid Build Coastguard Worker
2098*795d594fSAndroid Build Coastguard WorkerNterpGetShortStaticField:
2099*795d594fSAndroid Build Coastguard Worker  OP_SGET load="movswl", wide=0
2100*795d594fSAndroid Build Coastguard Worker
2101*795d594fSAndroid Build Coastguard WorkerNterpGetWideStaticField:
2102*795d594fSAndroid Build Coastguard Worker  OP_SGET load="movq", wide=1
2103*795d594fSAndroid Build Coastguard Worker
2104*795d594fSAndroid Build Coastguard WorkerNterpGetIntStaticField:
2105*795d594fSAndroid Build Coastguard Worker  OP_SGET load="movl", wide=0
2106*795d594fSAndroid Build Coastguard Worker
2107*795d594fSAndroid Build Coastguard WorkerNterpPutStaticField:
2108*795d594fSAndroid Build Coastguard Worker  OP_SPUT rINST_reg=rINST, store="movl", wide=0
2109*795d594fSAndroid Build Coastguard Worker
2110*795d594fSAndroid Build Coastguard WorkerNterpPutBooleanStaticField:
2111*795d594fSAndroid Build Coastguard WorkerNterpPutByteStaticField:
2112*795d594fSAndroid Build Coastguard Worker  OP_SPUT rINST_reg=rINSTbl, store="movb", wide=0
2113*795d594fSAndroid Build Coastguard Worker
2114*795d594fSAndroid Build Coastguard WorkerNterpPutCharStaticField:
2115*795d594fSAndroid Build Coastguard WorkerNterpPutShortStaticField:
2116*795d594fSAndroid Build Coastguard Worker  OP_SPUT rINST_reg=rINSTw, store="movw", wide=0
2117*795d594fSAndroid Build Coastguard Worker
2118*795d594fSAndroid Build Coastguard WorkerNterpPutWideStaticField:
2119*795d594fSAndroid Build Coastguard Worker  OP_SPUT rINST_reg=rINSTq, store="movq", wide=1
2120*795d594fSAndroid Build Coastguard Worker
2121*795d594fSAndroid Build Coastguard WorkerNterpPutInstanceField:
2122*795d594fSAndroid Build Coastguard Worker  OP_IPUT rINST_reg=rINST, store="movl", wide=0
2123*795d594fSAndroid Build Coastguard Worker
2124*795d594fSAndroid Build Coastguard WorkerNterpPutBooleanInstanceField:
2125*795d594fSAndroid Build Coastguard WorkerNterpPutByteInstanceField:
2126*795d594fSAndroid Build Coastguard Worker  OP_IPUT rINST_reg=rINSTbl, store="movb", wide=0
2127*795d594fSAndroid Build Coastguard Worker
2128*795d594fSAndroid Build Coastguard WorkerNterpPutCharInstanceField:
2129*795d594fSAndroid Build Coastguard WorkerNterpPutShortInstanceField:
2130*795d594fSAndroid Build Coastguard Worker  OP_IPUT rINST_reg=rINSTw, store="movw", wide=0
2131*795d594fSAndroid Build Coastguard Worker
2132*795d594fSAndroid Build Coastguard WorkerNterpPutWideInstanceField:
2133*795d594fSAndroid Build Coastguard Worker  OP_IPUT rINST_reg=rINSTq, store="movq", wide=1
2134*795d594fSAndroid Build Coastguard Worker
2135*795d594fSAndroid Build Coastguard WorkerNterpGetBooleanInstanceField:
2136*795d594fSAndroid Build Coastguard Worker  OP_IGET load="movzbl", wide=0
2137*795d594fSAndroid Build Coastguard Worker
2138*795d594fSAndroid Build Coastguard WorkerNterpGetByteInstanceField:
2139*795d594fSAndroid Build Coastguard Worker  OP_IGET load="movsbl", wide=0
2140*795d594fSAndroid Build Coastguard Worker
2141*795d594fSAndroid Build Coastguard WorkerNterpGetCharInstanceField:
2142*795d594fSAndroid Build Coastguard Worker  OP_IGET load="movzwl", wide=0
2143*795d594fSAndroid Build Coastguard Worker
2144*795d594fSAndroid Build Coastguard WorkerNterpGetShortInstanceField:
2145*795d594fSAndroid Build Coastguard Worker  OP_IGET load="movswl", wide=0
2146*795d594fSAndroid Build Coastguard Worker
2147*795d594fSAndroid Build Coastguard WorkerNterpGetWideInstanceField:
2148*795d594fSAndroid Build Coastguard Worker  OP_IGET load="movq", wide=1
2149*795d594fSAndroid Build Coastguard Worker
2150*795d594fSAndroid Build Coastguard WorkerNterpGetInstanceField:
2151*795d594fSAndroid Build Coastguard Worker  OP_IGET load="movl", wide=0
2152*795d594fSAndroid Build Coastguard Worker
2153*795d594fSAndroid Build Coastguard WorkerNterpHandleHotnessOverflow:
2154*795d594fSAndroid Build Coastguard Worker    CHECK_AND_UPDATE_SHARED_MEMORY_METHOD if_hot=1f, if_not_hot=4f
2155*795d594fSAndroid Build Coastguard Worker1:
2156*795d594fSAndroid Build Coastguard Worker    movq rPC, %rsi
2157*795d594fSAndroid Build Coastguard Worker    movq rFP, %rdx
2158*795d594fSAndroid Build Coastguard Worker    call nterp_hot_method
2159*795d594fSAndroid Build Coastguard Worker    testq %rax, %rax
2160*795d594fSAndroid Build Coastguard Worker    jne 3f
2161*795d594fSAndroid Build Coastguard Worker2:
2162*795d594fSAndroid Build Coastguard Worker    FETCH_INST
2163*795d594fSAndroid Build Coastguard Worker    GOTO_NEXT
2164*795d594fSAndroid Build Coastguard Worker3:
2165*795d594fSAndroid Build Coastguard Worker    // Drop the current frame.
2166*795d594fSAndroid Build Coastguard Worker    movq -8(rREFS), %rsp
2167*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA(rsp, CALLEE_SAVES_SIZE)
2168*795d594fSAndroid Build Coastguard Worker
2169*795d594fSAndroid Build Coastguard Worker    // Setup the new frame
2170*795d594fSAndroid Build Coastguard Worker    movq OSR_DATA_FRAME_SIZE(%rax), %rcx
2171*795d594fSAndroid Build Coastguard Worker    // Given stack size contains all callee saved registers, remove them.
2172*795d594fSAndroid Build Coastguard Worker    subq $$CALLEE_SAVES_SIZE, %rcx
2173*795d594fSAndroid Build Coastguard Worker
2174*795d594fSAndroid Build Coastguard Worker    // Remember CFA.
2175*795d594fSAndroid Build Coastguard Worker    movq %rsp, %rbp
2176*795d594fSAndroid Build Coastguard Worker    CFI_DEF_CFA_REGISTER(rbp)
2177*795d594fSAndroid Build Coastguard Worker
2178*795d594fSAndroid Build Coastguard Worker    subq %rcx, %rsp
2179*795d594fSAndroid Build Coastguard Worker    movq %rsp, %rdi               // rdi := beginning of stack
2180*795d594fSAndroid Build Coastguard Worker    leaq OSR_DATA_MEMORY(%rax), %rsi  // rsi := memory to copy
2181*795d594fSAndroid Build Coastguard Worker    rep movsb                     // while (rcx--) { *rdi++ = *rsi++ }
2182*795d594fSAndroid Build Coastguard Worker
2183*795d594fSAndroid Build Coastguard Worker    // Fetch the native PC to jump to and save it in a callee-save register.
2184*795d594fSAndroid Build Coastguard Worker    movq OSR_DATA_NATIVE_PC(%rax), %rbx
2185*795d594fSAndroid Build Coastguard Worker
2186*795d594fSAndroid Build Coastguard Worker    // Free the memory holding OSR Data.
2187*795d594fSAndroid Build Coastguard Worker    movq %rax, %rdi
2188*795d594fSAndroid Build Coastguard Worker    call free
2189*795d594fSAndroid Build Coastguard Worker
2190*795d594fSAndroid Build Coastguard Worker    // Jump to the compiled code.
2191*795d594fSAndroid Build Coastguard Worker    jmp *%rbx
2192*795d594fSAndroid Build Coastguard Worker4:
2193*795d594fSAndroid Build Coastguard Worker    DO_SUSPEND_CHECK continue_label=2b
2194*795d594fSAndroid Build Coastguard Worker    jmp 2b
2195*795d594fSAndroid Build Coastguard Worker
2196*795d594fSAndroid Build Coastguard WorkerNterpHandleInvokeInterfaceOnObjectMethodRange:
2197*795d594fSAndroid Build Coastguard Worker   shrl $$16, %eax
2198*795d594fSAndroid Build Coastguard Worker   movq MIRROR_CLASS_VTABLE_OFFSET_64(%edx, %eax, 8), %rdi
2199*795d594fSAndroid Build Coastguard Worker   jmp NterpCommonInvokeInstanceRange
2200*795d594fSAndroid Build Coastguard Worker
2201*795d594fSAndroid Build Coastguard WorkerNterpHandleInvokeInterfaceOnObjectMethod:
2202*795d594fSAndroid Build Coastguard Worker   shrl $$16, %eax
2203*795d594fSAndroid Build Coastguard Worker   movq MIRROR_CLASS_VTABLE_OFFSET_64(%edx, %eax, 8), %rdi
2204*795d594fSAndroid Build Coastguard Worker   jmp NterpCommonInvokeInstance
2205*795d594fSAndroid Build Coastguard Worker
2206*795d594fSAndroid Build Coastguard Worker// This is the logical end of ExecuteNterpImpl, where the frame info applies.
2207*795d594fSAndroid Build Coastguard Worker// EndExecuteNterpImpl includes the methods below as we want the runtime to
2208*795d594fSAndroid Build Coastguard Worker// see them as part of the Nterp PCs.
2209*795d594fSAndroid Build Coastguard Worker.cfi_endproc
2210*795d594fSAndroid Build Coastguard Worker
2211*795d594fSAndroid Build Coastguard Workernterp_to_nterp_static_non_range:
2212*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
2213*795d594fSAndroid Build Coastguard Worker    .cfi_def_cfa rsp, 8
2214*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FOR_INVOKE
2215*795d594fSAndroid Build Coastguard Worker    SETUP_NON_RANGE_ARGUMENTS_AND_EXECUTE is_static=1, is_string_init=0
2216*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
2217*795d594fSAndroid Build Coastguard Worker
2218*795d594fSAndroid Build Coastguard Workernterp_to_nterp_string_init_non_range:
2219*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
2220*795d594fSAndroid Build Coastguard Worker    .cfi_def_cfa rsp, 8
2221*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FOR_INVOKE
2222*795d594fSAndroid Build Coastguard Worker    SETUP_NON_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=1
2223*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
2224*795d594fSAndroid Build Coastguard Worker
2225*795d594fSAndroid Build Coastguard Workernterp_to_nterp_instance_non_range:
2226*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
2227*795d594fSAndroid Build Coastguard Worker    .cfi_def_cfa rsp, 8
2228*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FOR_INVOKE
2229*795d594fSAndroid Build Coastguard Worker    SETUP_NON_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=0
2230*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
2231*795d594fSAndroid Build Coastguard Worker
2232*795d594fSAndroid Build Coastguard Workernterp_to_nterp_static_range:
2233*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
2234*795d594fSAndroid Build Coastguard Worker    .cfi_def_cfa rsp, 8
2235*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FOR_INVOKE
2236*795d594fSAndroid Build Coastguard Worker    SETUP_RANGE_ARGUMENTS_AND_EXECUTE is_static=1
2237*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
2238*795d594fSAndroid Build Coastguard Worker
2239*795d594fSAndroid Build Coastguard Workernterp_to_nterp_instance_range:
2240*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
2241*795d594fSAndroid Build Coastguard Worker    .cfi_def_cfa rsp, 8
2242*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FOR_INVOKE
2243*795d594fSAndroid Build Coastguard Worker    SETUP_RANGE_ARGUMENTS_AND_EXECUTE is_static=0
2244*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
2245*795d594fSAndroid Build Coastguard Worker
2246*795d594fSAndroid Build Coastguard Workernterp_to_nterp_string_init_range:
2247*795d594fSAndroid Build Coastguard Worker    .cfi_startproc
2248*795d594fSAndroid Build Coastguard Worker    .cfi_def_cfa rsp, 8
2249*795d594fSAndroid Build Coastguard Worker    SETUP_STACK_FOR_INVOKE
2250*795d594fSAndroid Build Coastguard Worker    SETUP_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=1
2251*795d594fSAndroid Build Coastguard Worker    .cfi_endproc
2252*795d594fSAndroid Build Coastguard Worker
2253*795d594fSAndroid Build Coastguard WorkerEND nterp_helper
2254*795d594fSAndroid Build Coastguard Worker
2255*795d594fSAndroid Build Coastguard Worker// This is the end of PCs contained by the OatQuickMethodHeader created for the interpreter
2256*795d594fSAndroid Build Coastguard Worker// entry point.
2257*795d594fSAndroid Build Coastguard Worker    FUNCTION_TYPE(EndExecuteNterpImpl)
2258*795d594fSAndroid Build Coastguard Worker    ASM_HIDDEN SYMBOL(EndExecuteNterpImpl)
2259*795d594fSAndroid Build Coastguard Worker    .global SYMBOL(EndExecuteNterpImpl)
2260*795d594fSAndroid Build Coastguard WorkerSYMBOL(EndExecuteNterpImpl):
2261*795d594fSAndroid Build Coastguard Worker
2262*795d594fSAndroid Build Coastguard Worker// Entrypoints into runtime.
2263*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_get_static_field, NterpGetStaticField
2264*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_get_instance_field_offset, NterpGetInstanceFieldOffset
2265*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_filled_new_array, NterpFilledNewArray
2266*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_filled_new_array_range, NterpFilledNewArrayRange
2267*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_get_class, NterpGetClass
2268*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_allocate_object, NterpAllocateObject
2269*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_get_method, NterpGetMethod
2270*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_hot_method, NterpHotMethod
2271*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_load_object, NterpLoadObject
2272*795d594fSAndroid Build Coastguard Worker
2273*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION nterp_deliver_pending_exception
2274*795d594fSAndroid Build Coastguard Worker    DELIVER_PENDING_EXCEPTION
2275*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION nterp_deliver_pending_exception
2276*795d594fSAndroid Build Coastguard Worker
2277*795d594fSAndroid Build Coastguard Worker// gen_mterp.py will inline the following definitions
2278*795d594fSAndroid Build Coastguard Worker// within [ExecuteNterpImpl, EndExecuteNterpImpl).
2279*795d594fSAndroid Build Coastguard Worker%def instruction_end():
2280*795d594fSAndroid Build Coastguard Worker
2281*795d594fSAndroid Build Coastguard Worker    FUNCTION_TYPE(artNterpAsmInstructionEnd)
2282*795d594fSAndroid Build Coastguard Worker    ASM_HIDDEN SYMBOL(artNterpAsmInstructionEnd)
2283*795d594fSAndroid Build Coastguard Worker    .global SYMBOL(artNterpAsmInstructionEnd)
2284*795d594fSAndroid Build Coastguard WorkerSYMBOL(artNterpAsmInstructionEnd):
2285*795d594fSAndroid Build Coastguard Worker    // artNterpAsmInstructionEnd is used as landing pad for exception handling.
2286*795d594fSAndroid Build Coastguard Worker    FETCH_INST
2287*795d594fSAndroid Build Coastguard Worker    GOTO_NEXT
2288*795d594fSAndroid Build Coastguard Worker
2289*795d594fSAndroid Build Coastguard Worker%def instruction_start():
2290*795d594fSAndroid Build Coastguard Worker
2291*795d594fSAndroid Build Coastguard Worker    FUNCTION_TYPE(artNterpAsmInstructionStart)
2292*795d594fSAndroid Build Coastguard Worker    ASM_HIDDEN SYMBOL(artNterpAsmInstructionStart)
2293*795d594fSAndroid Build Coastguard Worker    .global SYMBOL(artNterpAsmInstructionStart)
2294*795d594fSAndroid Build Coastguard WorkerSYMBOL(artNterpAsmInstructionStart) = .L_op_nop
2295*795d594fSAndroid Build Coastguard Worker    .text
2296*795d594fSAndroid Build Coastguard Worker
2297*795d594fSAndroid Build Coastguard Worker%def opcode_name_prefix():
2298*795d594fSAndroid Build Coastguard Worker%   return "nterp_"
2299*795d594fSAndroid Build Coastguard Worker%def opcode_start():
2300*795d594fSAndroid Build Coastguard Worker    ENTRY nterp_${opcode}
2301*795d594fSAndroid Build Coastguard Worker%def opcode_end():
2302*795d594fSAndroid Build Coastguard Worker    END nterp_${opcode}
2303*795d594fSAndroid Build Coastguard Worker    // Advance to the end of this handler. Causes error if we are past that point.
2304*795d594fSAndroid Build Coastguard Worker    .org nterp_${opcode} + NTERP_HANDLER_SIZE  // ${opcode} handler is too big!
2305*795d594fSAndroid Build Coastguard Worker%def opcode_slow_path_start(name):
2306*795d594fSAndroid Build Coastguard Worker    ENTRY ${name}
2307*795d594fSAndroid Build Coastguard Worker%def opcode_slow_path_end(name):
2308*795d594fSAndroid Build Coastguard Worker    END ${name}
2309