blob: 4951ad0e989a7d46121e601a4ad86b055d48eef7 [file] [log] [blame]
Ian Rogersef7d42f2014-01-06 12:55:46 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "asm_support_x86_64.S"
18
19// For x86, the CFA is esp+4, the address above the pushed return address on the stack.
20
21 /*
22 * Macro that sets up the callee save frame to conform with
23 * Runtime::CreateCalleeSaveMethod(kSaveAll)
24 */
25MACRO0(SETUP_SAVE_ALL_CALLEE_SAVE_FRAME)
Andreas Gampebf6b92a2014-03-05 16:11:04 -080026 // R10 := Runtime::Current()
27 movq _ZN3art7Runtime9instance_E@GOTPCREL(%rip), %r10
28 movq (%r10), %r10
Ian Rogers47d00c02014-04-16 17:33:27 -070029 // Save callee save registers to agree with core spills bitmap.
Andreas Gampebf6b92a2014-03-05 16:11:04 -080030 PUSH r15 // Callee save.
31 PUSH r14 // Callee save.
32 PUSH r13 // Callee save.
33 PUSH r12 // Callee save.
34 PUSH rbp // Callee save.
35 PUSH rbx // Callee save.
Ian Rogers44d6ff12014-03-06 23:11:11 -080036 subq MACRO_LITERAL(8), %rsp // Space for Method* (also aligns the frame).
Andreas Gampebf6b92a2014-03-05 16:11:04 -080037 CFI_ADJUST_CFA_OFFSET(8)
Ian Rogers47d00c02014-04-16 17:33:27 -070038 // R10 := ArtMethod* for save all callee save frame method.
Andreas Gampebf6b92a2014-03-05 16:11:04 -080039 movq RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET(%r10), %r10
40 // Store ArtMethod* to bottom of stack.
41 movq %r10, 0(%rsp)
Ian Rogersef7d42f2014-01-06 12:55:46 -080042END_MACRO
43
44 /*
45 * Macro that sets up the callee save frame to conform with
46 * Runtime::CreateCalleeSaveMethod(kRefsOnly)
47 */
48MACRO0(SETUP_REF_ONLY_CALLEE_SAVE_FRAME)
Ian Rogers47d00c02014-04-16 17:33:27 -070049 UNTESTED
50 // R10 := Runtime::Current()
51 movq _ZN3art7Runtime9instance_E@GOTPCREL(%rip), %r10
52 movq (%r10), %r10
53 // Save callee and GPR args, mixed together to agree with core spills bitmap.
54 PUSH r15 // Callee save.
55 PUSH r14 // Callee save.
56 PUSH r13 // Callee save.
57 PUSH r12 // Callee save.
58 PUSH rbp // Callee save.
59 PUSH rbx // Callee save.
60 subq MACRO_LITERAL(8), %rsp // Space for Method* (also aligns the frame).
61 CFI_ADJUST_CFA_OFFSET(8)
62 // R10 := ArtMethod* for refs only callee save frame method.
63 movq RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET(%r10), %r10
64 // Store ArtMethod* to bottom of stack.
65 movq %r10, 0(%rsp)
Ian Rogersef7d42f2014-01-06 12:55:46 -080066END_MACRO
67
68MACRO0(RESTORE_REF_ONLY_CALLEE_SAVE_FRAME)
Ian Rogers47d00c02014-04-16 17:33:27 -070069 UNTESTED
70 addq MACRO_LITERAL(8), %rsp
71 CFI_ADJUST_CFA_OFFSET(-8)
72 // TODO: optimize by not restoring callee-saves restored by the ABI
73 POP rbx
74 POP rbp
75 POP r12
76 POP r13
77 POP r14
78 POP r15
Ian Rogersef7d42f2014-01-06 12:55:46 -080079END_MACRO
80
81 /*
82 * Macro that sets up the callee save frame to conform with
83 * Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
84 */
85MACRO0(SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME)
Ian Rogers936b37f2014-02-14 00:52:24 -080086 // R10 := Runtime::Current()
87 movq _ZN3art7Runtime9instance_E@GOTPCREL(%rip), %r10
88 movq (%r10), %r10
89 // Save callee and GPR args, mixed together to agree with core spills bitmap.
90 PUSH r15 // Callee save.
91 PUSH r14 // Callee save.
92 PUSH r13 // Callee save.
93 PUSH r12 // Callee save.
Andreas Gampebf6b92a2014-03-05 16:11:04 -080094 PUSH r9 // Quick arg 5.
95 PUSH r8 // Quick arg 4.
96 PUSH rsi // Quick arg 1.
Ian Rogers936b37f2014-02-14 00:52:24 -080097 PUSH rbp // Callee save.
98 PUSH rbx // Callee save.
Andreas Gampebf6b92a2014-03-05 16:11:04 -080099 PUSH rdx // Quick arg 2.
100 PUSH rcx // Quick arg 3.
Ian Rogers936b37f2014-02-14 00:52:24 -0800101 // Create space for FPR args and create 2 slots, 1 of padding and 1 for the ArtMethod*.
Ian Rogers44d6ff12014-03-06 23:11:11 -0800102 subq MACRO_LITERAL(80), %rsp
Ian Rogers936b37f2014-02-14 00:52:24 -0800103 CFI_ADJUST_CFA_OFFSET(80)
104 // R10 := ArtMethod* for ref and args callee save frame method.
105 movq RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET(%r10), %r10
106 // Save FPRs.
107 movq %xmm0, 16(%rsp)
108 movq %xmm1, 24(%rsp)
109 movq %xmm2, 32(%rsp)
110 movq %xmm3, 40(%rsp)
111 movq %xmm4, 48(%rsp)
112 movq %xmm5, 56(%rsp)
113 movq %xmm6, 64(%rsp)
114 movq %xmm7, 72(%rsp)
115 // Store ArtMethod* to bottom of stack.
116 movq %r10, 0(%rsp)
Ian Rogersef7d42f2014-01-06 12:55:46 -0800117END_MACRO
118
119MACRO0(RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME)
Ian Rogers936b37f2014-02-14 00:52:24 -0800120 // Restore FPRs.
121 movq 16(%rsp), %xmm0
122 movq 24(%rsp), %xmm1
123 movq 32(%rsp), %xmm2
124 movq 40(%rsp), %xmm3
125 movq 48(%rsp), %xmm4
126 movq 56(%rsp), %xmm5
127 movq 64(%rsp), %xmm6
128 movq 72(%rsp), %xmm7
Ian Rogers44d6ff12014-03-06 23:11:11 -0800129 addq MACRO_LITERAL(80), %rsp
Ian Rogers936b37f2014-02-14 00:52:24 -0800130 CFI_ADJUST_CFA_OFFSET(-80)
Ian Rogersbefbd572014-03-06 01:13:39 -0800131 // Restore callee and GPR args, mixed together to agree with core spills bitmap.
Ian Rogers936b37f2014-02-14 00:52:24 -0800132 POP rcx
133 POP rdx
134 POP rbx
135 POP rbp
136 POP rsi
137 POP r8
138 POP r9
139 POP r12
140 POP r13
141 POP r14
142 POP r15
Ian Rogersef7d42f2014-01-06 12:55:46 -0800143END_MACRO
144
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800145
Ian Rogersef7d42f2014-01-06 12:55:46 -0800146 /*
147 * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending
148 * exception is Thread::Current()->exception_.
149 */
150MACRO0(DELIVER_PENDING_EXCEPTION)
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800151 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save callee saves for throw
152 // (Thread*, SP) setup
153 movq %gs:THREAD_SELF_OFFSET, %rdi
154 movq %rsp, %rsi
155 call PLT_SYMBOL(artDeliverPendingExceptionFromCode) // artDeliverPendingExceptionFromCode(Thread*, SP)
Ian Rogers47d00c02014-04-16 17:33:27 -0700156 UNREACHABLE
Ian Rogersef7d42f2014-01-06 12:55:46 -0800157END_MACRO
158
159MACRO2(NO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
160 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers47d00c02014-04-16 17:33:27 -0700161 UNTESTED
162 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
163 // Outgoing argument set up
164 movq %rsp, %rsi // pass SP
165 movq %gs:THREAD_SELF_OFFSET, %rdi // pass Thread::Current()
166 call PLT_VAR(cxx_name, 1) // cxx_name(Thread*, SP)
167 UNREACHABLE
Ian Rogersef7d42f2014-01-06 12:55:46 -0800168 END_FUNCTION VAR(c_name, 0)
169END_MACRO
170
171MACRO2(ONE_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
172 DEFINE_FUNCTION VAR(c_name, 0)
Dmitry Petrochenkofca82202014-03-21 11:21:37 +0700173 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
174 // Outgoing argument set up
Ian Rogers47d00c02014-04-16 17:33:27 -0700175 movq %rsp, %rdx // pass SP
176 movq %gs:THREAD_SELF_OFFSET, %rsi // pass Thread::Current()
Dmitry Petrochenkofca82202014-03-21 11:21:37 +0700177 call PLT_VAR(cxx_name, 1) // cxx_name(arg1, Thread*, SP)
Ian Rogers47d00c02014-04-16 17:33:27 -0700178 UNREACHABLE
Ian Rogersef7d42f2014-01-06 12:55:46 -0800179 END_FUNCTION VAR(c_name, 0)
180END_MACRO
181
182MACRO2(TWO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
183 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers47d00c02014-04-16 17:33:27 -0700184 UNTESTED
185 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
186 // Outgoing argument set up
187 movq %rsp, %rcx // pass SP
188 movq %gs:THREAD_SELF_OFFSET, %rdx // pass Thread::Current()
189 call PLT_VAR(cxx_name, 1) // cxx_name(Thread*, SP)
190 UNREACHABLE
Ian Rogersef7d42f2014-01-06 12:55:46 -0800191 END_FUNCTION VAR(c_name, 0)
192END_MACRO
193
194 /*
195 * Called by managed code to create and deliver a NullPointerException.
196 */
197NO_ARG_RUNTIME_EXCEPTION art_quick_throw_null_pointer_exception, artThrowNullPointerExceptionFromCode
198
199 /*
200 * Called by managed code to create and deliver an ArithmeticException.
201 */
202NO_ARG_RUNTIME_EXCEPTION art_quick_throw_div_zero, artThrowDivZeroFromCode
203
204 /*
205 * Called by managed code to create and deliver a StackOverflowError.
206 */
207NO_ARG_RUNTIME_EXCEPTION art_quick_throw_stack_overflow, artThrowStackOverflowFromCode
208
209 /*
210 * Called by managed code, saves callee saves and then calls artThrowException
211 * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception.
212 */
213ONE_ARG_RUNTIME_EXCEPTION art_quick_deliver_exception, artDeliverExceptionFromCode
214
215 /*
216 * Called by managed code to create and deliver a NoSuchMethodError.
217 */
218ONE_ARG_RUNTIME_EXCEPTION art_quick_throw_no_such_method, artThrowNoSuchMethodFromCode
219
220 /*
221 * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds
222 * index, arg2 holds limit.
223 */
224TWO_ARG_RUNTIME_EXCEPTION art_quick_throw_array_bounds, artThrowArrayBoundsFromCode
225
226 /*
227 * All generated callsites for interface invokes and invocation slow paths will load arguments
228 * as usual - except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain
229 * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the
230 * stack and call the appropriate C helper.
231 * NOTE: "this" is first visible argument of the target, and so can be found in arg1/r1.
232 *
233 * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting
234 * of the target Method* in r0 and method->code_ in r1.
235 *
236 * If unsuccessful, the helper will return NULL/NULL. There will bea pending exception in the
237 * thread and we branch to another stub to deliver it.
238 *
239 * On success this wrapper will restore arguments and *jump* to the target, leaving the lr
240 * pointing back to the original caller.
241 */
242MACRO2(INVOKE_TRAMPOLINE, c_name, cxx_name)
243 DEFINE_FUNCTION VAR(c_name, 0)
244 int3
245 int3
246 END_FUNCTION VAR(c_name, 0)
247END_MACRO
248
249INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline, artInvokeInterfaceTrampoline
250INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
251
252INVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck
253INVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck
254INVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
255INVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
256
Ian Rogers936b37f2014-02-14 00:52:24 -0800257
258 /*
259 * Helper for quick invocation stub to set up XMM registers. Assumes r10 == shorty,
260 * r11 == arg_array. Clobbers r10, r11 and al. Branches to xmm_setup_finished if it encounters
261 * the end of the shorty.
262 */
263MACRO2(LOOP_OVER_SHORTY_LOADING_XMMS, xmm_reg, finished)
2641: // LOOP
265 movb (%r10), %al // al := *shorty
Ian Rogers44d6ff12014-03-06 23:11:11 -0800266 addq MACRO_LITERAL(1), %r10 // shorty++
267 cmpb MACRO_LITERAL(0), %al // if (al == '\0') goto xmm_setup_finished
Ian Rogers936b37f2014-02-14 00:52:24 -0800268 je VAR(finished, 1)
Ian Rogers44d6ff12014-03-06 23:11:11 -0800269 cmpb MACRO_LITERAL(68), %al // if (al == 'D') goto FOUND_DOUBLE
Ian Rogers936b37f2014-02-14 00:52:24 -0800270 je 2f
Ian Rogers44d6ff12014-03-06 23:11:11 -0800271 cmpb MACRO_LITERAL(70), %al // if (al == 'F') goto FOUND_FLOAT
Ian Rogers936b37f2014-02-14 00:52:24 -0800272 je 3f
Ian Rogers44d6ff12014-03-06 23:11:11 -0800273 addq MACRO_LITERAL(4), %r11 // arg_array++
Ian Rogers936b37f2014-02-14 00:52:24 -0800274 // Handle extra space in arg array taken by a long.
Ian Rogers44d6ff12014-03-06 23:11:11 -0800275 cmpb MACRO_LITERAL(74), %al // if (al != 'J') goto LOOP
Ian Rogers936b37f2014-02-14 00:52:24 -0800276 jne 1b
Ian Rogers44d6ff12014-03-06 23:11:11 -0800277 addq MACRO_LITERAL(4), %r11 // arg_array++
Ian Rogers936b37f2014-02-14 00:52:24 -0800278 jmp 1b // goto LOOP
2792: // FOUND_DOUBLE
280 movsd (%r11), REG_VAR(xmm_reg, 0)
Ian Rogers44d6ff12014-03-06 23:11:11 -0800281 addq MACRO_LITERAL(8), %r11 // arg_array+=2
Ian Rogers936b37f2014-02-14 00:52:24 -0800282 jmp 4f
2833: // FOUND_FLOAT
284 movss (%r11), REG_VAR(xmm_reg, 0)
Ian Rogers44d6ff12014-03-06 23:11:11 -0800285 addq MACRO_LITERAL(4), %r11 // arg_array++
Ian Rogers936b37f2014-02-14 00:52:24 -08002864:
287END_MACRO
288
289 /*
290 * Helper for quick invocation stub to set up GPR registers. Assumes r10 == shorty,
291 * r11 == arg_array. Clobbers r10, r11 and al. Branches to gpr_setup_finished if it encounters
292 * the end of the shorty.
293 */
294MACRO3(LOOP_OVER_SHORTY_LOADING_GPRS, gpr_reg64, gpr_reg32, finished)
2951: // LOOP
296 movb (%r10), %al // al := *shorty
Ian Rogers44d6ff12014-03-06 23:11:11 -0800297 addq MACRO_LITERAL(1), %r10 // shorty++
298 cmpb MACRO_LITERAL(0), %al // if (al == '\0') goto gpr_setup_finished
Ian Rogers936b37f2014-02-14 00:52:24 -0800299 je VAR(finished, 2)
Ian Rogers44d6ff12014-03-06 23:11:11 -0800300 cmpb MACRO_LITERAL(74), %al // if (al == 'J') goto FOUND_LONG
Ian Rogers936b37f2014-02-14 00:52:24 -0800301 je 2f
Ian Rogers44d6ff12014-03-06 23:11:11 -0800302 cmpb MACRO_LITERAL(70), %al // if (al == 'F') goto SKIP_FLOAT
Ian Rogers936b37f2014-02-14 00:52:24 -0800303 je 3f
Ian Rogers44d6ff12014-03-06 23:11:11 -0800304 cmpb MACRO_LITERAL(68), %al // if (al == 'D') goto SKIP_DOUBLE
Ian Rogers936b37f2014-02-14 00:52:24 -0800305 je 4f
306 movl (%r11), REG_VAR(gpr_reg32, 1)
Ian Rogers44d6ff12014-03-06 23:11:11 -0800307 addq MACRO_LITERAL(4), %r11 // arg_array++
Ian Rogers936b37f2014-02-14 00:52:24 -0800308 jmp 5f
3092: // FOUND_LONG
310 movq (%r11), REG_VAR(gpr_reg64, 0)
Ian Rogers44d6ff12014-03-06 23:11:11 -0800311 addq MACRO_LITERAL(8), %r11 // arg_array+=2
Ian Rogers936b37f2014-02-14 00:52:24 -0800312 jmp 5f
3133: // SKIP_FLOAT
Ian Rogers44d6ff12014-03-06 23:11:11 -0800314 addq MACRO_LITERAL(4), %r11 // arg_array++
Ian Rogers936b37f2014-02-14 00:52:24 -0800315 jmp 1b
3164: // SKIP_DOUBLE
Ian Rogers44d6ff12014-03-06 23:11:11 -0800317 addq MACRO_LITERAL(8), %r11 // arg_array+=2
Ian Rogers936b37f2014-02-14 00:52:24 -0800318 jmp 1b
3195:
320END_MACRO
321
Ian Rogersef7d42f2014-01-06 12:55:46 -0800322 /*
323 * Quick invocation stub.
Ian Rogers0177e532014-02-11 16:30:46 -0800324 * On entry:
325 * [sp] = return address
326 * rdi = method pointer
Ian Rogers936b37f2014-02-14 00:52:24 -0800327 * rsi = argument array that must at least contain the this pointer.
Ian Rogers0177e532014-02-11 16:30:46 -0800328 * rdx = size of argument array in bytes
329 * rcx = (managed) thread pointer
330 * r8 = JValue* result
331 * r9 = char* shorty
Ian Rogersef7d42f2014-01-06 12:55:46 -0800332 */
333DEFINE_FUNCTION art_quick_invoke_stub
Ian Rogers936b37f2014-02-14 00:52:24 -0800334 // Set up argument XMM registers.
335 leaq 1(%r9), %r10 // R10 := shorty + 1 ; ie skip return arg character.
336 leaq 4(%rsi), %r11 // R11 := arg_array + 4 ; ie skip this pointer.
337 LOOP_OVER_SHORTY_LOADING_XMMS xmm0, .Lxmm_setup_finished
338 LOOP_OVER_SHORTY_LOADING_XMMS xmm1, .Lxmm_setup_finished
339 LOOP_OVER_SHORTY_LOADING_XMMS xmm2, .Lxmm_setup_finished
340 LOOP_OVER_SHORTY_LOADING_XMMS xmm3, .Lxmm_setup_finished
341 LOOP_OVER_SHORTY_LOADING_XMMS xmm4, .Lxmm_setup_finished
342 LOOP_OVER_SHORTY_LOADING_XMMS xmm5, .Lxmm_setup_finished
343 LOOP_OVER_SHORTY_LOADING_XMMS xmm6, .Lxmm_setup_finished
344 LOOP_OVER_SHORTY_LOADING_XMMS xmm7, .Lxmm_setup_finished
345 .balign 16
346.Lxmm_setup_finished:
347 PUSH rbp // Save rbp.
348 PUSH r8 // Save r8/result*.
349 PUSH r9 // Save r9/shorty*.
Ian Rogers47d00c02014-04-16 17:33:27 -0700350 movq %rsp, %rbp // Copy value of stack pointer into base pointer.
Ian Rogers936b37f2014-02-14 00:52:24 -0800351 CFI_DEF_CFA_REGISTER(rbp)
352 movl %edx, %r10d
353 addl LITERAL(64), %edx // Reserve space for return addr, method*, rbp, r8 and r9 in frame.
354 andl LITERAL(0xFFFFFFF0), %edx // Align frame size to 16 bytes.
355 subl LITERAL(32), %edx // Remove space for return address, rbp, r8 and r9.
356 subq %rdx, %rsp // Reserve stack space for argument array.
357 movq LITERAL(0), (%rsp) // Store NULL for method*
358 movl %r10d, %ecx // Place size of args in rcx.
359 movq %rdi, %rax // RAX := method to be called
360 movq %rsi, %r11 // R11 := arg_array
361 leaq 8(%rsp), %rdi // Rdi is pointing just above the method* in the stack arguments.
362 // Copy arg array into stack.
363 rep movsb // while (rcx--) { *rdi++ = *rsi++ }
364 leaq 1(%r9), %r10 // R10 := shorty + 1 ; ie skip return arg character
365 movq %rax, %rdi // RDI := method to be called
366 movl (%r11), %esi // RSI := this pointer
367 addq LITERAL(4), %r11 // arg_array++
368 LOOP_OVER_SHORTY_LOADING_GPRS rdx, edx, .Lgpr_setup_finished
369 LOOP_OVER_SHORTY_LOADING_GPRS rcx, ecx, .Lgpr_setup_finished
370 LOOP_OVER_SHORTY_LOADING_GPRS r8, r8d, .Lgpr_setup_finished
371 LOOP_OVER_SHORTY_LOADING_GPRS r9, r9d, .Lgpr_setup_finished
372.Lgpr_setup_finished:
373 call *METHOD_QUICK_CODE_OFFSET(%rdi) // Call the method.
374 movq %rbp, %rsp // Restore stack pointer.
375 CFI_DEF_CFA_REGISTER(rsp)
376 POP r9 // Pop r9 - shorty*.
377 POP r8 // Pop r8 - result*.
378 POP rbp // Pop rbp
379 cmpb LITERAL(68), (%r9) // Test if result type char == 'D'.
380 je .Lreturn_double_quick
381 cmpb LITERAL(70), (%r9) // Test if result type char == 'F'.
382 je .Lreturn_float_quick
383 movq %rax, (%r8) // Store the result assuming its a long, int or Object*
384 ret
385.Lreturn_double_quick:
386 movsd %xmm0, (%r8) // Store the double floating point result.
387 ret
388.Lreturn_float_quick:
389 movss %xmm0, (%r8) // Store the floating point result.
390 ret
391END_FUNCTION art_quick_invoke_stub
392
393 /*
394 * Quick invocation stub.
395 * On entry:
396 * [sp] = return address
397 * rdi = method pointer
398 * rsi = argument array or NULL if no arguments.
399 * rdx = size of argument array in bytes
400 * rcx = (managed) thread pointer
401 * r8 = JValue* result
402 * r9 = char* shorty
403 */
404DEFINE_FUNCTION art_quick_invoke_static_stub
405 // Set up argument XMM registers.
406 leaq 1(%r9), %r10 // R10 := shorty + 1 ; ie skip return arg character
407 movq %rsi, %r11 // R11 := arg_array
408 LOOP_OVER_SHORTY_LOADING_XMMS xmm0, .Lxmm_setup_finished2
409 LOOP_OVER_SHORTY_LOADING_XMMS xmm1, .Lxmm_setup_finished2
410 LOOP_OVER_SHORTY_LOADING_XMMS xmm2, .Lxmm_setup_finished2
411 LOOP_OVER_SHORTY_LOADING_XMMS xmm3, .Lxmm_setup_finished2
412 LOOP_OVER_SHORTY_LOADING_XMMS xmm4, .Lxmm_setup_finished2
413 LOOP_OVER_SHORTY_LOADING_XMMS xmm5, .Lxmm_setup_finished2
414 LOOP_OVER_SHORTY_LOADING_XMMS xmm6, .Lxmm_setup_finished2
415 LOOP_OVER_SHORTY_LOADING_XMMS xmm7, .Lxmm_setup_finished2
416 .balign 16
417.Lxmm_setup_finished2:
418 PUSH rbp // Save rbp.
419 PUSH r8 // Save r8/result*.
420 PUSH r9 // Save r9/shorty*.
Ian Rogers47d00c02014-04-16 17:33:27 -0700421 movq %rsp, %rbp // Copy value of stack pointer into base pointer.
Ian Rogers936b37f2014-02-14 00:52:24 -0800422 CFI_DEF_CFA_REGISTER(rbp)
423 movl %edx, %r10d
424 addl LITERAL(64), %edx // Reserve space for return addr, method*, rbp, r8 and r9 in frame.
425 andl LITERAL(0xFFFFFFF0), %edx // Align frame size to 16 bytes.
426 subl LITERAL(32), %edx // Remove space for return address, rbp, r8 and r9.
427 subq %rdx, %rsp // Reserve stack space for argument array.
428 movq LITERAL(0), (%rsp) // Store NULL for method*
429 movl %r10d, %ecx // Place size of args in rcx.
430 movq %rdi, %rax // RAX := method to be called
431 movq %rsi, %r11 // R11 := arg_array
432 leaq 8(%rsp), %rdi // Rdi is pointing just above the method* in the stack arguments.
433 // Copy arg array into stack.
434 rep movsb // while (rcx--) { *rdi++ = *rsi++ }
435 leaq 1(%r9), %r10 // R10 := shorty + 1 ; ie skip return arg character
436 movq %rax, %rdi // RDI := method to be called
437 LOOP_OVER_SHORTY_LOADING_GPRS rsi, esi, .Lgpr_setup_finished2
438 LOOP_OVER_SHORTY_LOADING_GPRS rdx, edx, .Lgpr_setup_finished2
439 LOOP_OVER_SHORTY_LOADING_GPRS rcx, ecx, .Lgpr_setup_finished2
440 LOOP_OVER_SHORTY_LOADING_GPRS r8, r8d, .Lgpr_setup_finished2
441 LOOP_OVER_SHORTY_LOADING_GPRS r9, r9d, .Lgpr_setup_finished2
442.Lgpr_setup_finished2:
443 call *METHOD_QUICK_CODE_OFFSET(%rdi) // Call the method.
444 movq %rbp, %rsp // Restore stack pointer.
445 CFI_DEF_CFA_REGISTER(rsp)
446 POP r9 // Pop r9 - shorty*.
447 POP r8 // Pop r8 - result*.
448 POP rbp // Pop rbp
449 cmpb LITERAL(68), (%r9) // Test if result type char == 'D'.
450 je .Lreturn_double_quick2
451 cmpb LITERAL(70), (%r9) // Test if result type char == 'F'.
452 je .Lreturn_float_quick2
453 movq %rax, (%r8) // Store the result assuming its a long, int or Object*
454 ret
455.Lreturn_double_quick2:
456 movsd %xmm0, (%r8) // Store the double floating point result.
457 ret
458.Lreturn_float_quick2:
459 movss %xmm0, (%r8) // Store the floating point result.
460 ret
Ian Rogers1a570662014-03-12 01:02:21 -0700461END_FUNCTION art_quick_invoke_static_stub
Ian Rogersef7d42f2014-01-06 12:55:46 -0800462
463MACRO3(NO_ARG_DOWNCALL, c_name, cxx_name, return_macro)
464 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers47d00c02014-04-16 17:33:27 -0700465 UNTESTED
466 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
467 // Outgoing argument set up
468 movq %rsp, %rsi // pass SP
469 movq %gs:THREAD_SELF_OFFSET, %rdi // pass Thread::Current()
470 call PLT_VAR(cxx_name, 1) // cxx_name(Thread*, SP)
471 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
472 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersef7d42f2014-01-06 12:55:46 -0800473 END_FUNCTION VAR(c_name, 0)
474END_MACRO
475
476MACRO3(ONE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
477 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers47d00c02014-04-16 17:33:27 -0700478 UNTESTED
479 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
480 // Outgoing argument set up
481 movq %rsp, %rdx // pass SP
482 movq %gs:THREAD_SELF_OFFSET, %rsi // pass Thread::Current()
483 call PLT_VAR(cxx_name, 1) // cxx_name(arg0, Thread*, SP)
484 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
485 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersef7d42f2014-01-06 12:55:46 -0800486 END_FUNCTION VAR(c_name, 0)
487END_MACRO
488
489MACRO3(TWO_ARG_DOWNCALL, c_name, cxx_name, return_macro)
490 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers47d00c02014-04-16 17:33:27 -0700491 UNTESTED
492 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
493 // Outgoing argument set up
494 movq %rsp, %rcx // pass SP
495 movq %gs:THREAD_SELF_OFFSET, %rdx // pass Thread::Current()
496 call PLT_VAR(cxx_name, 1) // cxx_name(arg0, arg1, Thread*, SP)
497 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
498 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersef7d42f2014-01-06 12:55:46 -0800499 END_FUNCTION VAR(c_name, 0)
500END_MACRO
501
502MACRO3(THREE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
503 DEFINE_FUNCTION VAR(c_name, 0)
Ian Rogers47d00c02014-04-16 17:33:27 -0700504 UNTESTED
505 SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
506 // Outgoing argument set up
507 movq %rsp, %r8 // pass SP
508 movq %gs:THREAD_SELF_OFFSET, %rcx // pass Thread::Current()
509 call PLT_VAR(cxx_name, 1) // cxx_name(arg0, arg1, arg2, Thread*, SP)
510 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
511 CALL_MACRO(return_macro, 2) // return or deliver exception
Ian Rogersef7d42f2014-01-06 12:55:46 -0800512 END_FUNCTION VAR(c_name, 0)
513END_MACRO
514
515MACRO0(RETURN_IF_RESULT_IS_NON_ZERO)
Ian Rogers47d00c02014-04-16 17:33:27 -0700516 UNTESTED
517 testq %rax, %rax // rax == 0 ?
518 jz 1f // if rax == 0 goto 1
Ian Rogersef7d42f2014-01-06 12:55:46 -0800519 ret // return
5201: // deliver exception on current thread
521 DELIVER_PENDING_EXCEPTION
522END_MACRO
523
524MACRO0(RETURN_IF_EAX_ZERO)
Ian Rogers47d00c02014-04-16 17:33:27 -0700525 UNTESTED
Ian Rogersef7d42f2014-01-06 12:55:46 -0800526 testl %eax, %eax // eax == 0 ?
527 jnz 1f // if eax != 0 goto 1
528 ret // return
5291: // deliver exception on current thread
530 DELIVER_PENDING_EXCEPTION
531END_MACRO
532
533MACRO0(RETURN_OR_DELIVER_PENDING_EXCEPTION)
Ian Rogers936b37f2014-02-14 00:52:24 -0800534 movq %gs:THREAD_EXCEPTION_OFFSET, %rcx // get exception field
535 testq %rcx, %rcx // rcx == 0 ?
536 jnz 1f // if rcx != 0 goto 1
537 ret // return
5381: // deliver exception on current thread
Ian Rogersef7d42f2014-01-06 12:55:46 -0800539 DELIVER_PENDING_EXCEPTION
540END_MACRO
541
542// Generate the allocation entrypoints for each allocator.
543// TODO: use arch/quick_alloc_entrypoints.S. Currently we don't as we need to use concatenation
544// macros to work around differences between OS/X's as and binutils as (OS/X lacks named arguments
545// to macros and the VAR macro won't concatenate arguments properly), this also breaks having
546// multi-line macros that use each other (hence using 1 macro per newline below).
547#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(c_suffix, cxx_suffix) \
548 TWO_ARG_DOWNCALL art_quick_alloc_object ## c_suffix, artAllocObjectFromCode ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO
549#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(c_suffix, cxx_suffix) \
550 TWO_ARG_DOWNCALL art_quick_alloc_object_resolved ## c_suffix, artAllocObjectFromCodeResolved ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO
551#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(c_suffix, cxx_suffix) \
552 TWO_ARG_DOWNCALL art_quick_alloc_object_initialized ## c_suffix, artAllocObjectFromCodeInitialized ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO
553#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(c_suffix, cxx_suffix) \
554 TWO_ARG_DOWNCALL art_quick_alloc_object_with_access_check ## c_suffix, artAllocObjectFromCodeWithAccessCheck ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO
555#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(c_suffix, cxx_suffix) \
556 THREE_ARG_DOWNCALL art_quick_alloc_array ## c_suffix, artAllocArrayFromCode ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO
557#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(c_suffix, cxx_suffix) \
558 THREE_ARG_DOWNCALL art_quick_alloc_array_resolved ## c_suffix, artAllocArrayFromCodeResolved ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO
559#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(c_suffix, cxx_suffix) \
560 THREE_ARG_DOWNCALL art_quick_alloc_array_with_access_check ## c_suffix, artAllocArrayFromCodeWithAccessCheck ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO
561#define GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(c_suffix, cxx_suffix) \
562 THREE_ARG_DOWNCALL art_quick_check_and_alloc_array ## c_suffix, artCheckAndAllocArrayFromCode ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO
563#define GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(c_suffix, cxx_suffix) \
564 THREE_ARG_DOWNCALL art_quick_check_and_alloc_array_with_access_check ## c_suffix, artCheckAndAllocArrayFromCodeWithAccessCheck ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO
565
566GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_dlmalloc, DlMalloc)
567GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_dlmalloc, DlMalloc)
568GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_dlmalloc, DlMalloc)
569GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_dlmalloc, DlMalloc)
570GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_dlmalloc, DlMalloc)
571GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_dlmalloc, DlMalloc)
572GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_dlmalloc, DlMalloc)
573GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_dlmalloc, DlMalloc)
574GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_dlmalloc, DlMalloc)
575
576GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_dlmalloc_instrumented, DlMallocInstrumented)
577GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_dlmalloc_instrumented, DlMallocInstrumented)
578GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_dlmalloc_instrumented, DlMallocInstrumented)
579GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_dlmalloc_instrumented, DlMallocInstrumented)
580GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_dlmalloc_instrumented, DlMallocInstrumented)
581GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_dlmalloc_instrumented, DlMallocInstrumented)
582GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_dlmalloc_instrumented, DlMallocInstrumented)
583GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_dlmalloc_instrumented, DlMallocInstrumented)
584GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_dlmalloc_instrumented, DlMallocInstrumented)
585
586GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_rosalloc, RosAlloc)
587GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_rosalloc, RosAlloc)
588GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_rosalloc, RosAlloc)
589GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_rosalloc, RosAlloc)
590GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_rosalloc, RosAlloc)
591GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_rosalloc, RosAlloc)
592GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_rosalloc, RosAlloc)
593GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_rosalloc, RosAlloc)
594GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_rosalloc, RosAlloc)
595
596GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_rosalloc_instrumented, RosAllocInstrumented)
597GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_rosalloc_instrumented, RosAllocInstrumented)
598GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_rosalloc_instrumented, RosAllocInstrumented)
599GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_rosalloc_instrumented, RosAllocInstrumented)
600GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_rosalloc_instrumented, RosAllocInstrumented)
601GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_rosalloc_instrumented, RosAllocInstrumented)
602GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_rosalloc_instrumented, RosAllocInstrumented)
603GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_rosalloc_instrumented, RosAllocInstrumented)
604GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_rosalloc_instrumented, RosAllocInstrumented)
605
606GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_bump_pointer, BumpPointer)
607GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_bump_pointer, BumpPointer)
608GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_bump_pointer, BumpPointer)
609GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_bump_pointer, BumpPointer)
610GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_bump_pointer, BumpPointer)
611GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_bump_pointer, BumpPointer)
612GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_bump_pointer, BumpPointer)
613GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_bump_pointer, BumpPointer)
614GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_bump_pointer, BumpPointer)
615
616GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_bump_pointer_instrumented, BumpPointerInstrumented)
617GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_bump_pointer_instrumented, BumpPointerInstrumented)
618GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_bump_pointer_instrumented, BumpPointerInstrumented)
619GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_bump_pointer_instrumented, BumpPointerInstrumented)
620GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_bump_pointer_instrumented, BumpPointerInstrumented)
621GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_bump_pointer_instrumented, BumpPointerInstrumented)
622GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_bump_pointer_instrumented, BumpPointerInstrumented)
623GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_bump_pointer_instrumented, BumpPointerInstrumented)
624GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_bump_pointer_instrumented, BumpPointerInstrumented)
625
626GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_tlab, TLAB)
627GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB)
628GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB)
629GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB)
630GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_tlab, TLAB)
631GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB)
632GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_tlab, TLAB)
633GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_tlab, TLAB)
634GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_tlab, TLAB)
635
636GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_tlab_instrumented, TLABInstrumented)
637GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab_instrumented, TLABInstrumented)
638GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab_instrumented, TLABInstrumented)
639GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab_instrumented, TLABInstrumented)
640GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_tlab_instrumented, TLABInstrumented)
641GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab_instrumented, TLABInstrumented)
642GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_tlab_instrumented, TLABInstrumented)
643GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_tlab_instrumented, TLABInstrumented)
644GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_tlab_instrumented, TLABInstrumented)
645
646TWO_ARG_DOWNCALL art_quick_resolve_string, artResolveStringFromCode, RETURN_IF_RESULT_IS_NON_ZERO
647TWO_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode, RETURN_IF_RESULT_IS_NON_ZERO
648TWO_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_RESULT_IS_NON_ZERO
649TWO_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_RESULT_IS_NON_ZERO
650
651TWO_ARG_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO
652
653DEFINE_FUNCTION art_quick_lock_object
654 int3
655 int3
656END_FUNCTION art_quick_lock_object
657
658DEFINE_FUNCTION art_quick_unlock_object
659 int3
660 int3
661END_FUNCTION art_quick_unlock_object
662
663DEFINE_FUNCTION art_quick_is_assignable
664 int3
665 int3
666END_FUNCTION art_quick_is_assignable
667
668DEFINE_FUNCTION art_quick_check_cast
Andreas Gampe525cde22014-04-22 15:44:50 -0700669 PUSH rdi // Save args for exc
670 PUSH rsi
671 call PLT_SYMBOL(artIsAssignableFromCode) // (Class* klass, Class* ref_klass)
672 testq %rax, %rax
673 jz 1f // jump forward if not assignable
674 addq LITERAL(16), %rsp // pop arguments
675 CFI_ADJUST_CFA_OFFSET(-16)
676 ret
6771:
678 POP rsi // Pop arguments
679 POP rdi
680 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
681 mov %rsp, %rcx // pass SP
682 mov %gs:THREAD_SELF_OFFSET, %rdx // pass Thread::Current()
683 call PLT_SYMBOL(artThrowClassCastException) // (Class* a, Class* b, Thread*, SP)
684 int3 // unreached
Ian Rogersef7d42f2014-01-06 12:55:46 -0800685END_FUNCTION art_quick_check_cast
686
687 /*
688 * Entry from managed code for array put operations of objects where the value being stored
689 * needs to be checked for compatibility.
690 * eax = array, ecx = index, edx = value
691 */
692UNIMPLEMENTED art_quick_aput_obj_with_null_and_bound_check
693UNIMPLEMENTED art_quick_aput_obj_with_bound_check
694UNIMPLEMENTED art_quick_aput_obj
Andreas Gampe525cde22014-04-22 15:44:50 -0700695
696// TODO: This is quite silly on X86_64 now.
697DEFINE_FUNCTION art_quick_memcpy
698 call PLT_SYMBOL(memcpy) // (void*, const void*, size_t)
699 ret
700END_FUNCTION art_quick_memcpy
Ian Rogersef7d42f2014-01-06 12:55:46 -0800701
702NO_ARG_DOWNCALL art_quick_test_suspend, artTestSuspendFromCode, ret
703
704UNIMPLEMENTED art_quick_fmod
705UNIMPLEMENTED art_quick_fmodf
706UNIMPLEMENTED art_quick_l2d
707UNIMPLEMENTED art_quick_l2f
708UNIMPLEMENTED art_quick_d2l
709UNIMPLEMENTED art_quick_f2l
710UNIMPLEMENTED art_quick_idivmod
711UNIMPLEMENTED art_quick_ldiv
712UNIMPLEMENTED art_quick_lmod
713UNIMPLEMENTED art_quick_lmul
714UNIMPLEMENTED art_quick_lshl
715UNIMPLEMENTED art_quick_lshr
716UNIMPLEMENTED art_quick_lushr
717UNIMPLEMENTED art_quick_set32_instance
718UNIMPLEMENTED art_quick_set64_instance
719UNIMPLEMENTED art_quick_set_obj_instance
720UNIMPLEMENTED art_quick_get32_instance
721UNIMPLEMENTED art_quick_get64_instance
722UNIMPLEMENTED art_quick_get_obj_instance
723UNIMPLEMENTED art_quick_set32_static
724UNIMPLEMENTED art_quick_set64_static
725UNIMPLEMENTED art_quick_set_obj_static
726UNIMPLEMENTED art_quick_get32_static
727UNIMPLEMENTED art_quick_get64_static
728UNIMPLEMENTED art_quick_get_obj_static
Ian Rogersb7dabf52014-03-12 12:11:54 -0700729
730DEFINE_FUNCTION art_quick_proxy_invoke_handler
731 // Save callee and GPR args, mixed together to agree with core spills bitmap of ref. and args
732 // callee save frame.
733 PUSH r15 // Callee save.
734 PUSH r14 // Callee save.
735 PUSH r13 // Callee save.
736 PUSH r12 // Callee save.
737 PUSH r9 // Quick arg 5.
738 PUSH r8 // Quick arg 4.
739 PUSH rsi // Quick arg 1.
740 PUSH rbp // Callee save.
741 PUSH rbx // Callee save.
742 PUSH rdx // Quick arg 2.
743 PUSH rcx // Quick arg 3.
744 // Create space for FPR args and create 2 slots, 1 of padding and 1 for the ArtMethod*.
745 subq LITERAL(80), %rsp
746 CFI_ADJUST_CFA_OFFSET(80)
747 // Save FPRs.
748 movq %xmm0, 16(%rsp)
749 movq %xmm1, 24(%rsp)
750 movq %xmm2, 32(%rsp)
751 movq %xmm3, 40(%rsp)
752 movq %xmm4, 48(%rsp)
753 movq %xmm5, 56(%rsp)
754 movq %xmm6, 64(%rsp)
755 movq %xmm7, 72(%rsp)
756 // Store proxy method to bottom of stack.
757 movq %rdi, 0(%rsp)
758 movq %gs:THREAD_SELF_OFFSET, %rdx // Pass Thread::Current().
759 movq %rsp, %rcx // Pass SP.
760 call PLT_SYMBOL(artQuickProxyInvokeHandler) // (proxy method, receiver, Thread*, SP)
761 movq %rax, %xmm0 // Copy return value in case of float returns.
762 addq LITERAL(168), %rsp // Pop arguments.
763 CFI_ADJUST_CFA_OFFSET(-168)
764 RETURN_OR_DELIVER_PENDING_EXCEPTION
765END_FUNCTION art_quick_proxy_invoke_handler
Ian Rogersef7d42f2014-01-06 12:55:46 -0800766
767 /*
768 * Called to resolve an imt conflict.
769 */
770UNIMPLEMENTED art_quick_imt_conflict_trampoline
Ian Rogers936b37f2014-02-14 00:52:24 -0800771
Ian Rogersbefbd572014-03-06 01:13:39 -0800772DEFINE_FUNCTION art_quick_resolution_trampoline
773 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
774 movq %gs:THREAD_SELF_OFFSET, %rdx
775 movq %rsp, %rcx
776 call PLT_SYMBOL(artQuickResolutionTrampoline) // (called, receiver, Thread*, SP)
777 movq %rax, %r10 // Remember returned code pointer in R10.
Ian Rogers1a570662014-03-12 01:02:21 -0700778 movq (%rsp), %rdi // Load called method into RDI.
Ian Rogersbefbd572014-03-06 01:13:39 -0800779 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
780 testq %r10, %r10 // If code pointer is NULL goto deliver pending exception.
781 jz 1f
782 jmp *%r10 // Tail call into method.
7831:
784 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
785 DELIVER_PENDING_EXCEPTION
786END_FUNCTION art_quick_resolution_trampoline
787
788/* Generic JNI frame layout:
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800789 *
790 * #-------------------#
791 * | |
792 * | caller method... |
793 * #-------------------# <--- SP on entry
Andreas Gampe36fea8d2014-03-10 13:37:40 -0700794 *
795 * |
796 * V
797 *
798 * #-------------------#
799 * | caller method... |
800 * #-------------------#
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800801 * | Return |
802 * | R15 | callee save
803 * | R14 | callee save
804 * | R13 | callee save
805 * | R12 | callee save
806 * | R9 | arg5
807 * | R8 | arg4
808 * | RSI/R6 | arg1
809 * | RBP/R5 | callee save
810 * | RBX/R3 | callee save
811 * | RDX/R2 | arg2
812 * | RCX/R1 | arg3
813 * | XMM7 | float arg 8
814 * | XMM6 | float arg 7
815 * | XMM5 | float arg 6
816 * | XMM4 | float arg 5
817 * | XMM3 | float arg 4
818 * | XMM2 | float arg 3
819 * | XMM1 | float arg 2
820 * | XMM0 | float arg 1
821 * | Padding |
822 * | RDI/Method* | <- sp
823 * #-------------------#
Andreas Gampe36fea8d2014-03-10 13:37:40 -0700824 * | Scratch Alloca | 5K scratch space
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800825 * #---------#---------#
826 * | | sp* |
827 * | Tramp. #---------#
828 * | args | thread |
829 * | Tramp. #---------#
830 * | | method |
831 * #-------------------# <--- SP on artQuickGenericJniTrampoline
Andreas Gampe36fea8d2014-03-10 13:37:40 -0700832 *
833 * |
834 * v artQuickGenericJniTrampoline
835 *
836 * #-------------------#
837 * | caller method... |
838 * #-------------------#
839 * | Return |
840 * | Callee-Save Data |
841 * #-------------------#
842 * | SIRT |
843 * #-------------------#
844 * | Method* | <--- (1)
845 * #-------------------#
846 * | local ref cookie | // 4B
847 * | SIRT size | // 4B TODO: roll into call stack alignment?
848 * #-------------------#
849 * | JNI Call Stack |
850 * #-------------------# <--- SP on native call
851 * | |
852 * | Stack for Regs | The trampoline assembly will pop these values
853 * | | into registers for native call
854 * #-------------------#
855 * | Native code ptr |
856 * #-------------------#
857 * | Free scratch |
858 * #-------------------#
859 * | Ptr to (1) | <--- RSP
860 * #-------------------#
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800861 */
Andreas Gampe2da88232014-02-27 12:26:20 -0800862 /*
863 * Called to do a generic JNI down-call
864 */
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800865DEFINE_FUNCTION art_quick_generic_jni_trampoline
866 // Save callee and GPR args, mixed together to agree with core spills bitmap.
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800867 PUSH r15 // Callee save.
868 PUSH r14 // Callee save.
869 PUSH r13 // Callee save.
870 PUSH r12 // Callee save.
871 PUSH r9 // Quick arg 5.
872 PUSH r8 // Quick arg 4.
873 PUSH rsi // Quick arg 1.
874 PUSH rbp // Callee save.
875 PUSH rbx // Callee save.
876 PUSH rdx // Quick arg 2.
877 PUSH rcx // Quick arg 3.
878 // Create space for FPR args and create 2 slots, 1 of padding and 1 for the ArtMethod*.
879 subq LITERAL(80), %rsp
880 CFI_ADJUST_CFA_OFFSET(80)
881 // Save FPRs.
882 movq %xmm0, 16(%rsp)
883 movq %xmm1, 24(%rsp)
884 movq %xmm2, 32(%rsp)
885 movq %xmm3, 40(%rsp)
886 movq %xmm4, 48(%rsp)
887 movq %xmm5, 56(%rsp)
888 movq %xmm6, 64(%rsp)
889 movq %xmm7, 72(%rsp)
890 // Store native ArtMethod* to bottom of stack.
891 movq %rdi, 0(%rsp)
892 movq %rsp, %rbp // save SP at callee-save frame
Andreas Gampe36fea8d2014-03-10 13:37:40 -0700893 movq %rsp, %rbx
894 CFI_DEF_CFA_REGISTER(rbx)
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800895 //
896 // reserve a lot of space
897 //
898 // 4 local state ref
899 // 4 padding
900 // 4196 4k scratch space, enough for 2x 256 8-byte parameters (TODO: SIRT overhead?)
901 // 16 SIRT member fields ?
902 // + 112 14x 8-byte stack-2-register space
903 // ------
904 // 4332
905 // 16-byte aligned: 4336
906 // Note: 14x8 = 7*16, so the stack stays aligned for the native call...
907 // Also means: the padding is somewhere in the middle
Andreas Gampec147b002014-03-06 18:11:06 -0800908 //
909 //
910 // New test: use 5K and release
911 // 5k = 5120
912 subq LITERAL(5120), %rsp
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800913 // prepare for artQuickGenericJniTrampoline call
914 // (Thread*, SP)
915 // rdi rsi <= C calling convention
916 // gs:... rbp <= where they are
917 movq %gs:THREAD_SELF_OFFSET, %rdi
918 movq %rbp, %rsi
Ian Rogersbefbd572014-03-06 01:13:39 -0800919 call PLT_SYMBOL(artQuickGenericJniTrampoline) // (Thread*, sp)
Andreas Gampe36fea8d2014-03-10 13:37:40 -0700920
921 // At the bottom of the alloca we now have the name pointer to the method=bottom of callee-save
922 // get the adjusted frame pointer
923 popq %rbp
924
925 // Check for error, negative value.
926 test %rax, %rax
Ian Rogerse0dcd462014-03-08 15:21:04 -0800927 js .Lentry_error
Andreas Gampe36fea8d2014-03-10 13:37:40 -0700928
929 // release part of the alloca, get the code pointer
Andreas Gampec147b002014-03-06 18:11:06 -0800930 addq %rax, %rsp
Andreas Gampec147b002014-03-06 18:11:06 -0800931 popq %rax
Andreas Gampe36fea8d2014-03-10 13:37:40 -0700932
Andreas Gampec147b002014-03-06 18:11:06 -0800933 // pop from the register-passing alloca region
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800934 // what's the right layout?
935 popq %rdi
936 popq %rsi
937 popq %rdx
938 popq %rcx
939 popq %r8
940 popq %r9
941 // TODO: skip floating point if unused, some flag.
942 movq 0(%rsp), %xmm0
943 movq 8(%rsp), %xmm1
944 movq 16(%rsp), %xmm2
945 movq 24(%rsp), %xmm3
946 movq 32(%rsp), %xmm4
947 movq 40(%rsp), %xmm5
948 movq 48(%rsp), %xmm6
949 movq 56(%rsp), %xmm7
950 addq LITERAL(64), %rsp // floating-point done
951 // native call
Ian Rogerse0dcd462014-03-08 15:21:04 -0800952 call *%rax // Stack should be aligned 16B without the return addr?
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800953 // result sign extension is handled in C code
954 // prepare for artQuickGenericJniEndTrampoline call
955 // (Thread*, SP, result, result_f)
956 // rdi rsi rdx rcx <= C calling convention
957 // gs:... rbp rax xmm0 <= where they are
958 movq %gs:THREAD_SELF_OFFSET, %rdi
959 movq %rbp, %rsi
960 movq %rax, %rdx
961 movq %xmm0, %rcx
962 call PLT_SYMBOL(artQuickGenericJniEndTrampoline)
Ian Rogerse0dcd462014-03-08 15:21:04 -0800963
964 // Tear down the alloca.
Andreas Gampe36fea8d2014-03-10 13:37:40 -0700965 movq %rbx, %rsp
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800966 CFI_DEF_CFA_REGISTER(rsp)
Ian Rogerse0dcd462014-03-08 15:21:04 -0800967
968 // Pending exceptions possible.
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800969 // TODO: use cmpq, needs direct encoding because of gas bug
Ian Rogerse0dcd462014-03-08 15:21:04 -0800970 movq %gs:THREAD_EXCEPTION_OFFSET, %rcx
971 test %rcx, %rcx
972 jnz .Lexception_in_native
973
974 // Tear down the callee-save frame.
Andreas Gampebf6b92a2014-03-05 16:11:04 -0800975 // Load FPRs.
976 // movq %xmm0, 16(%rsp) // doesn't make sense!!!
977 movq 24(%rsp), %xmm1 // neither does this!!!
978 movq 32(%rsp), %xmm2
979 movq 40(%rsp), %xmm3
980 movq 48(%rsp), %xmm4
981 movq 56(%rsp), %xmm5
982 movq 64(%rsp), %xmm6
983 movq 72(%rsp), %xmm7
984 // was 80 bytes
985 addq LITERAL(80), %rsp
986 CFI_ADJUST_CFA_OFFSET(-80)
987 // Save callee and GPR args, mixed together to agree with core spills bitmap.
988 POP rcx // Arg.
989 POP rdx // Arg.
990 POP rbx // Callee save.
991 POP rbp // Callee save.
992 POP rsi // Arg.
993 POP r8 // Arg.
994 POP r9 // Arg.
995 POP r12 // Callee save.
996 POP r13 // Callee save.
997 POP r14 // Callee save.
998 POP r15 // Callee save.
999 // store into fpr, for when it's a fpr return...
1000 movq %rax, %xmm0
1001 ret
Ian Rogerse0dcd462014-03-08 15:21:04 -08001002.Lentry_error:
Andreas Gampe36fea8d2014-03-10 13:37:40 -07001003 movq %rbx, %rsp
1004 CFI_DEF_CFA_REGISTER(rsp)
Ian Rogerse0dcd462014-03-08 15:21:04 -08001005.Lexception_in_native:
Ian Rogerse0dcd462014-03-08 15:21:04 -08001006 // TODO: the SIRT contains the this pointer which is used by the debugger for exception
1007 // delivery.
Andreas Gampe36fea8d2014-03-10 13:37:40 -07001008 movq %xmm0, 16(%rsp) // doesn't make sense!!!
1009 movq 24(%rsp), %xmm1 // neither does this!!!
1010 movq 32(%rsp), %xmm2
1011 movq 40(%rsp), %xmm3
1012 movq 48(%rsp), %xmm4
1013 movq 56(%rsp), %xmm5
1014 movq 64(%rsp), %xmm6
1015 movq 72(%rsp), %xmm7
1016 // was 80 bytes
1017 addq LITERAL(80), %rsp
1018 CFI_ADJUST_CFA_OFFSET(-80)
1019 // Save callee and GPR args, mixed together to agree with core spills bitmap.
1020 POP rcx // Arg.
1021 POP rdx // Arg.
1022 POP rbx // Callee save.
1023 POP rbp // Callee save.
1024 POP rsi // Arg.
1025 POP r8 // Arg.
1026 POP r9 // Arg.
1027 POP r12 // Callee save.
1028 POP r13 // Callee save.
1029 POP r14 // Callee save.
1030 POP r15 // Callee save.
1031
Andreas Gampebf6b92a2014-03-05 16:11:04 -08001032 DELIVER_PENDING_EXCEPTION
1033END_FUNCTION art_quick_generic_jni_trampoline
Andreas Gampe2da88232014-02-27 12:26:20 -08001034
Ian Rogers936b37f2014-02-14 00:52:24 -08001035 /*
1036 * Called to bridge from the quick to interpreter ABI. On entry the arguments match those
1037 * of a quick call:
1038 * RDI = method being called / to bridge to.
1039 * RSI, RDX, RCX, R8, R9 are arguments to that method.
1040 */
1041DEFINE_FUNCTION art_quick_to_interpreter_bridge
1042 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // Set up frame and save arguments.
1043 movq %gs:THREAD_SELF_OFFSET, %rsi // RSI := Thread::Current()
1044 movq %rsp, %rdx // RDX := sp
1045 call PLT_SYMBOL(artQuickToInterpreterBridge) // (method, Thread*, SP)
1046 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME // TODO: no need to restore arguments in this case.
1047 movq %rax, %xmm0 // Place return value also into floating point return value.
1048 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
1049END_FUNCTION art_quick_to_interpreter_bridge
Ian Rogersef7d42f2014-01-06 12:55:46 -08001050
1051 /*
1052 * Routine that intercepts method calls and returns.
1053 */
1054UNIMPLEMENTED art_quick_instrumentation_entry
1055UNIMPLEMENTED art_quick_instrumentation_exit
1056
1057 /*
1058 * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization
1059 * will long jump to the upcall with a special exception of -1.
1060 */
1061UNIMPLEMENTED art_quick_deoptimize
1062
1063UNIMPLEMENTED art_quick_indexof
1064UNIMPLEMENTED art_quick_string_compareto
1065UNIMPLEMENTED art_quick_memcmp16