1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Copyright (C) 2012 The Android Open Source Project 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 459d709d503bab6e2b61931737e662dd293b40578ccornelius * Licensed under the Apache License, Version 2.0 (the "License"); 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * you may not use this file except in compliance with the License. 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * You may obtain a copy of the License at 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * http://www.apache.org/licenses/LICENSE-2.0 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Unless required by applicable law or agreed to in writing, software 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * distributed under the License is distributed on an "AS IS" BASIS, 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * See the License for the specific language governing permissions and 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * limitations under the License. 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "asm_support_x86_64.S" 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO0(SETUP_FP_CALLEE_SAVE_FRAME) 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create space for ART FP callee-saved registers 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subq MACRO_LITERAL(4 * 8), %rsp 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(4 * 8) 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm12, 0(%rsp) 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm13, 8(%rsp) 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm14, 16(%rsp) 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm15, 24(%rsp) 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO0(RESTORE_FP_CALLEE_SAVE_FRAME) 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Restore ART FP callee-saved registers 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 0(%rsp), %xmm12 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 8(%rsp), %xmm13 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 16(%rsp), %xmm14 3427f654740f2a26ad62a5c155af9199af9e69b889claireho movq 24(%rsp), %xmm15 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq MACRO_LITERAL(4 * 8), %rsp 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(- 4 * 8) 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// For x86, the CFA is esp+4, the address above the pushed return address on the stack. 4027f654740f2a26ad62a5c155af9199af9e69b889claireho 4127f654740f2a26ad62a5c155af9199af9e69b889claireho /* 4227f654740f2a26ad62a5c155af9199af9e69b889claireho * Macro that sets up the callee save frame to conform with 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Runtime::CreateCalleeSaveMethod(kSaveAll) 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO0(SETUP_SAVE_ALL_CALLEE_SAVE_FRAME) 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(__APPLE__) 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // R10 := Runtime::Current() 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq _ZN3art7Runtime9instance_E@GOTPCREL(%rip), %r10 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq (%r10), %r10 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Save callee save registers to agree with core spills bitmap. 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r15 // Callee save. 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r14 // Callee save. 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r13 // Callee save. 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r12 // Callee save. 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rbp // Callee save. 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rbx // Callee save. 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create space for FPR args, plus padding for alignment 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subq LITERAL(4 * 8), %rsp 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(4 * 8) 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Save FPRs. 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm12, 0(%rsp) 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm13, 8(%rsp) 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm14, 16(%rsp) 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm15, 24(%rsp) 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subq MACRO_LITERAL(8), %rsp // Space for Method* (also aligns the frame). 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(8) 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // R10 := ArtMethod* for save all callee save frame method. 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru THIS_LOAD_REQUIRES_READ_BARRIER 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET(%r10), %r10 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Store ArtMethod* to bottom of stack. 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %r10, 0(%rsp) 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Ugly compile-time check, but we only have the preprocessor. 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Last +8: implicit return address pushed on stack when caller made call. 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 6*8 + 4*8 + 8 + 8) 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#error "SAVE_ALL_CALLEE_SAVE_FRAME(X86_64) size not as expected." 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif // __APPLE__ 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Macro that sets up the callee save frame to conform with 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Runtime::CreateCalleeSaveMethod(kRefsOnly) 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO0(SETUP_REF_ONLY_CALLEE_SAVE_FRAME) 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(__APPLE__) 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // R10 := Runtime::Current() 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq _ZN3art7Runtime9instance_E@GOTPCREL(%rip), %r10 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq (%r10), %r10 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Save callee and GPR args, mixed together to agree with core spills bitmap. 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r15 // Callee save. 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r14 // Callee save. 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r13 // Callee save. 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r12 // Callee save. 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rbp // Callee save. 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rbx // Callee save. 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create space for FPR args, plus padding for alignment 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subq LITERAL(8 + 4*8), %rsp 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(8 + 4*8) 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Save FPRs. 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm12, 8(%rsp) 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm13, 16(%rsp) 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm14, 24(%rsp) 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm15, 32(%rsp) 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // R10 := ArtMethod* for refs only callee save frame method. 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru THIS_LOAD_REQUIRES_READ_BARRIER 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET(%r10), %r10 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Store ArtMethod* to bottom of stack. 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %r10, 0(%rsp) 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Ugly compile-time check, but we only have the preprocessor. 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Last +8: implicit return address pushed on stack when caller made call. 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 6*8 + 4*8 + 8 + 8) 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#error "REFS_ONLY_CALLEE_SAVE_FRAME(X86_64) size not as expected." 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif // __APPLE__ 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO0(RESTORE_REF_ONLY_CALLEE_SAVE_FRAME) 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 8(%rsp), %xmm12 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 16(%rsp), %xmm13 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 24(%rsp), %xmm14 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 32(%rsp), %xmm15 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq LITERAL(8 + 4*8), %rsp 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(-8 - 4*8) 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // TODO: optimize by not restoring callee-saves restored by the ABI 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rbx 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rbp 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r12 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r13 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r14 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r15 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Macro that sets up the callee save frame to conform with 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Runtime::CreateCalleeSaveMethod(kRefsAndArgs) 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO0(SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME) 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(__APPLE__) 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // R10 := Runtime::Current() 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq _ZN3art7Runtime9instance_E@GOTPCREL(%rip), %r10 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq (%r10), %r10 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Save callee and GPR args, mixed together to agree with core spills bitmap. 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r15 // Callee save. 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r14 // Callee save. 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r13 // Callee save. 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r12 // Callee save. 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r9 // Quick arg 5. 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r8 // Quick arg 4. 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rsi // Quick arg 1. 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rbp // Callee save. 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rbx // Callee save. 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rdx // Quick arg 2. 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rcx // Quick arg 3. 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create space for FPR args and create 2 slots, 1 of padding and 1 for the ArtMethod*. 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subq MACRO_LITERAL(80 + 4 * 8), %rsp 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(80 + 4 * 8) 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // R10 := ArtMethod* for ref and args callee save frame method. 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru THIS_LOAD_REQUIRES_READ_BARRIER 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET(%r10), %r10 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Save FPRs. 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm0, 16(%rsp) 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm1, 24(%rsp) 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm2, 32(%rsp) 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm3, 40(%rsp) 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm4, 48(%rsp) 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm5, 56(%rsp) 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm6, 64(%rsp) 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm7, 72(%rsp) 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm12, 80(%rsp) 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm13, 88(%rsp) 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm14, 96(%rsp) 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm15, 104(%rsp) 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Store ArtMethod* to bottom of stack. 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %r10, 0(%rsp) 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Ugly compile-time check, but we only have the preprocessor. 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Last +8: implicit return address pushed on stack when caller made call. 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE != 11*8 + 4*8 + 80 + 8) 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#error "REFS_AND_ARGS_CALLEE_SAVE_FRAME(X86_64) size not as expected." 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif // __APPLE__ 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO0(RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME) 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Restore FPRs. 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 16(%rsp), %xmm0 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 24(%rsp), %xmm1 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 32(%rsp), %xmm2 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 40(%rsp), %xmm3 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 48(%rsp), %xmm4 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 56(%rsp), %xmm5 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 64(%rsp), %xmm6 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 72(%rsp), %xmm7 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 80(%rsp), %xmm12 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 88(%rsp), %xmm13 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 96(%rsp), %xmm14 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 104(%rsp), %xmm15 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq MACRO_LITERAL(80 + 4 * 8), %rsp 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(-(80 + 4 * 8)) 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Restore callee and GPR args, mixed together to agree with core spills bitmap. 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rcx 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rdx 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rbx 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rbp 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rsi 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r8 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r9 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r12 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r13 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r14 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r15 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * exception is Thread::Current()->exception_. 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO0(DELIVER_PENDING_EXCEPTION) 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save callee saves for throw 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // (Thread*, SP) setup 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rdi 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %rsi 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call SYMBOL(artDeliverPendingExceptionFromCode) // artDeliverPendingExceptionFromCode(Thread*, SP) 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UNREACHABLE 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO2(NO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name) 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DEFINE_FUNCTION VAR(c_name, 0) 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Outgoing argument set up 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %rsi // pass SP 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rdi // pass Thread::Current() 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call VAR(cxx_name, 1) // cxx_name(Thread*, SP) 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UNREACHABLE 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru END_FUNCTION VAR(c_name, 0) 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO2(ONE_ARG_RUNTIME_EXCEPTION, c_name, cxx_name) 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DEFINE_FUNCTION VAR(c_name, 0) 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Outgoing argument set up 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %rdx // pass SP 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rsi // pass Thread::Current() 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call VAR(cxx_name, 1) // cxx_name(arg1, Thread*, SP) 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UNREACHABLE 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru END_FUNCTION VAR(c_name, 0) 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO2(TWO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name) 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DEFINE_FUNCTION VAR(c_name, 0) 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Outgoing argument set up 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %rcx // pass SP 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rdx // pass Thread::Current() 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call VAR(cxx_name, 1) // cxx_name(Thread*, SP) 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UNREACHABLE 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru END_FUNCTION VAR(c_name, 0) 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Called by managed code to create and deliver a NullPointerException. 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNO_ARG_RUNTIME_EXCEPTION art_quick_throw_null_pointer_exception, artThrowNullPointerExceptionFromCode 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Called by managed code to create and deliver an ArithmeticException. 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNO_ARG_RUNTIME_EXCEPTION art_quick_throw_div_zero, artThrowDivZeroFromCode 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Called by managed code to create and deliver a StackOverflowError. 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNO_ARG_RUNTIME_EXCEPTION art_quick_throw_stack_overflow, artThrowStackOverflowFromCode 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Called by managed code, saves callee saves and then calls artThrowException 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception. 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruONE_ARG_RUNTIME_EXCEPTION art_quick_deliver_exception, artDeliverExceptionFromCode 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Called by managed code to create and deliver a NoSuchMethodError. 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruONE_ARG_RUNTIME_EXCEPTION art_quick_throw_no_such_method, artThrowNoSuchMethodFromCode 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * index, arg2 holds limit. 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTWO_ARG_RUNTIME_EXCEPTION art_quick_throw_array_bounds, artThrowArrayBoundsFromCode 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * All generated callsites for interface invokes and invocation slow paths will load arguments 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * as usual - except instead of loading arg0/rdi with the target Method*, arg0/rdi will contain 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * stack and call the appropriate C helper. 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * NOTE: "this" is first visible argument of the target, and so can be found in arg1/rsi. 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The helper will attempt to locate the target and return a 128-bit result in rax/rdx consisting 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * of the target Method* in rax and method->code_ in rdx. 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If unsuccessful, the helper will return NULL/????. There will be a pending exception in the 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * thread and we branch to another stub to deliver it. 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * On success this wrapper will restore arguments and *jump* to the target, leaving the return 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * location on the stack. 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Adapted from x86 code. 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO2(INVOKE_TRAMPOLINE, c_name, cxx_name) 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DEFINE_FUNCTION VAR(c_name, 0) 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save callee saves in case allocation triggers GC 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Helper signature is always 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // (method_idx, *this_object, *caller_method, *self, sp) 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE(%rsp), %edx // pass caller Method* 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rcx // pass Thread 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %r8 // pass SP 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho call VAR(cxx_name, 1) // cxx_name(arg1, arg2, caller method*, Thread*, SP) 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // save the code pointer 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rax, %rdi 335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho movq %rdx, %rax 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testq %rdi, %rdi 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jz 1f 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Tail call to intended method. 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jmp *%rax 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru1: 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELIVER_PENDING_EXCEPTION 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru END_FUNCTION VAR(c_name, 0) 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruINVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline, artInvokeInterfaceTrampoline 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruINVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruINVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruINVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruINVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruINVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Helper for quick invocation stub to set up XMM registers. Assumes r10 == shorty, 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * r11 == arg_array. Clobbers r10, r11 and al. Branches to xmm_setup_finished if it encounters 36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * the end of the shorty. 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 36250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoMACRO2(LOOP_OVER_SHORTY_LOADING_XMMS, xmm_reg, finished) 36350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho1: // LOOP 36450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho movb (%r10), %al // al := *shorty 36550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho addq MACRO_LITERAL(1), %r10 // shorty++ 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpb MACRO_LITERAL(0), %al // if (al == '\0') goto xmm_setup_finished 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru je VAR(finished, 1) 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpb MACRO_LITERAL(68), %al // if (al == 'D') goto FOUND_DOUBLE 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru je 2f 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpb MACRO_LITERAL(70), %al // if (al == 'F') goto FOUND_FLOAT 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru je 3f 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq MACRO_LITERAL(4), %r11 // arg_array++ 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Handle extra space in arg array taken by a long. 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpb MACRO_LITERAL(74), %al // if (al != 'J') goto LOOP 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jne 1b 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq MACRO_LITERAL(4), %r11 // arg_array++ 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jmp 1b // goto LOOP 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru2: // FOUND_DOUBLE 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movsd (%r11), REG_VAR(xmm_reg, 0) 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq MACRO_LITERAL(8), %r11 // arg_array+=2 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jmp 4f 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru3: // FOUND_FLOAT 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movss (%r11), REG_VAR(xmm_reg, 0) 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq MACRO_LITERAL(4), %r11 // arg_array++ 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru4: 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 3878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 3888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius /* 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Helper for quick invocation stub to set up GPR registers. Assumes r10 == shorty, 3908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * r11 == arg_array. Clobbers r10, r11 and al. Branches to gpr_setup_finished if it encounters 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the end of the shorty. 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO3(LOOP_OVER_SHORTY_LOADING_GPRS, gpr_reg64, gpr_reg32, finished) 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru1: // LOOP 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movb (%r10), %al // al := *shorty 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq MACRO_LITERAL(1), %r10 // shorty++ 39727f654740f2a26ad62a5c155af9199af9e69b889claireho cmpb MACRO_LITERAL(0), %al // if (al == '\0') goto gpr_setup_finished 39827f654740f2a26ad62a5c155af9199af9e69b889claireho je VAR(finished, 2) 39927f654740f2a26ad62a5c155af9199af9e69b889claireho cmpb MACRO_LITERAL(74), %al // if (al == 'J') goto FOUND_LONG 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru je 2f 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpb MACRO_LITERAL(70), %al // if (al == 'F') goto SKIP_FLOAT 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru je 3f 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpb MACRO_LITERAL(68), %al // if (al == 'D') goto SKIP_DOUBLE 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru je 4f 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl (%r11), REG_VAR(gpr_reg32, 1) 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq MACRO_LITERAL(4), %r11 // arg_array++ 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jmp 5f 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru2: // FOUND_LONG 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq (%r11), REG_VAR(gpr_reg64, 0) 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq MACRO_LITERAL(8), %r11 // arg_array+=2 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jmp 5f 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru3: // SKIP_FLOAT 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq MACRO_LITERAL(4), %r11 // arg_array++ 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jmp 1b 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru4: // SKIP_DOUBLE 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq MACRO_LITERAL(8), %r11 // arg_array+=2 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jmp 1b 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru5: 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Quick invocation stub. 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * On entry: 424b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * [sp] = return address 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * rdi = method pointer 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * rsi = argument array that must at least contain the this pointer. 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * rdx = size of argument array in bytes 428b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * rcx = (managed) thread pointer 429b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * r8 = JValue* result 430b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * r9 = char* shorty 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDEFINE_FUNCTION art_quick_invoke_stub 43327f654740f2a26ad62a5c155af9199af9e69b889claireho#if defined(__APPLE__) 43427f654740f2a26ad62a5c155af9199af9e69b889claireho int3 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Set up argument XMM registers. 4388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius leaq 1(%r9), %r10 // R10 := shorty + 1 ; ie skip return arg character. 4398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius leaq 4(%rsi), %r11 // R11 := arg_array + 4 ; ie skip this pointer. 4408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius LOOP_OVER_SHORTY_LOADING_XMMS xmm0, .Lxmm_setup_finished 4418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius LOOP_OVER_SHORTY_LOADING_XMMS xmm1, .Lxmm_setup_finished 4428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius LOOP_OVER_SHORTY_LOADING_XMMS xmm2, .Lxmm_setup_finished 4438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius LOOP_OVER_SHORTY_LOADING_XMMS xmm3, .Lxmm_setup_finished 4448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius LOOP_OVER_SHORTY_LOADING_XMMS xmm4, .Lxmm_setup_finished 4458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius LOOP_OVER_SHORTY_LOADING_XMMS xmm5, .Lxmm_setup_finished 4468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius LOOP_OVER_SHORTY_LOADING_XMMS xmm6, .Lxmm_setup_finished 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_XMMS xmm7, .Lxmm_setup_finished 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru .balign 16 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lxmm_setup_finished: 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rbp // Save rbp. 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r8 // Save r8/result*. 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r9 // Save r9/shorty*. 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %rbp // Copy value of stack pointer into base pointer. 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_DEF_CFA_REGISTER(rbp) 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl %edx, %r10d 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addl LITERAL(60), %edx // Reserve space for return addr, StackReference<method>, rbp, 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // r8 and r9 in frame. 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru andl LITERAL(0xFFFFFFF0), %edx // Align frame size to 16 bytes. 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subl LITERAL(32), %edx // Remove space for return address, rbp, r8 and r9. 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subq %rdx, %rsp // Reserve stack space for argument array. 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if (STACK_REFERENCE_SIZE != 4) 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#error "STACK_REFERENCE_SIZE(X86_64) size not as expected." 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl LITERAL(0), (%rsp) // Store NULL for method* 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl %r10d, %ecx // Place size of args in rcx. 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rdi, %rax // RAX := method to be called 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsi, %r11 // R11 := arg_array 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leaq 4(%rsp), %rdi // Rdi is pointing just above the StackReference<method> in the 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // stack arguments. 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Copy arg array into stack. 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rep movsb // while (rcx--) { *rdi++ = *rsi++ } 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leaq 1(%r9), %r10 // R10 := shorty + 1 ; ie skip return arg character 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rax, %rdi // RDI := method to be called 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl (%r11), %esi // RSI := this pointer 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq LITERAL(4), %r11 // arg_array++ 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_GPRS rdx, edx, .Lgpr_setup_finished 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_GPRS rcx, ecx, .Lgpr_setup_finished 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_GPRS r8, r8d, .Lgpr_setup_finished 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_GPRS r9, r9d, .Lgpr_setup_finished 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lgpr_setup_finished: 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call *METHOD_QUICK_CODE_OFFSET_64(%rdi) // Call the method. 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rbp, %rsp // Restore stack pointer. 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_DEF_CFA_REGISTER(rsp) 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r9 // Pop r9 - shorty*. 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r8 // Pop r8 - result*. 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rbp // Pop rbp 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpb LITERAL(68), (%r9) // Test if result type char == 'D'. 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru je .Lreturn_double_quick 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpb LITERAL(70), (%r9) // Test if result type char == 'F'. 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru je .Lreturn_float_quick 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rax, (%r8) // Store the result assuming its a long, int or Object* 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lreturn_double_quick: 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movsd %xmm0, (%r8) // Store the double floating point result. 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lreturn_float_quick: 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movss %xmm0, (%r8) // Store the floating point result. 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif // __APPLE__ 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_FUNCTION art_quick_invoke_stub 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Quick invocation stub. 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * On entry: 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * [sp] = return address 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * rdi = method pointer 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * rsi = argument array or NULL if no arguments. 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * rdx = size of argument array in bytes 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * rcx = (managed) thread pointer 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * r8 = JValue* result 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * r9 = char* shorty 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDEFINE_FUNCTION art_quick_invoke_static_stub 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(__APPLE__) 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 51927f654740f2a26ad62a5c155af9199af9e69b889claireho int3 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Set up argument XMM registers. 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leaq 1(%r9), %r10 // R10 := shorty + 1 ; ie skip return arg character 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsi, %r11 // R11 := arg_array 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_XMMS xmm0, .Lxmm_setup_finished2 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_XMMS xmm1, .Lxmm_setup_finished2 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_XMMS xmm2, .Lxmm_setup_finished2 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_XMMS xmm3, .Lxmm_setup_finished2 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_XMMS xmm4, .Lxmm_setup_finished2 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_XMMS xmm5, .Lxmm_setup_finished2 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_XMMS xmm6, .Lxmm_setup_finished2 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_XMMS xmm7, .Lxmm_setup_finished2 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru .balign 16 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lxmm_setup_finished2: 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rbp // Save rbp. 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r8 // Save r8/result*. 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r9 // Save r9/shorty*. 5378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq %rsp, %rbp // Copy value of stack pointer into base pointer. 5388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius CFI_DEF_CFA_REGISTER(rbp) 5398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 5408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movl %edx, %r10d 5418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius addl LITERAL(60), %edx // Reserve space for return addr, StackReference<method>, rbp, 5428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // r8 and r9 in frame. 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru andl LITERAL(0xFFFFFFF0), %edx // Align frame size to 16 bytes. 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subl LITERAL(32), %edx // Remove space for return address, rbp, r8 and r9. 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subq %rdx, %rsp // Reserve stack space for argument array. 54627f654740f2a26ad62a5c155af9199af9e69b889claireho 54727f654740f2a26ad62a5c155af9199af9e69b889claireho#if (STACK_REFERENCE_SIZE != 4) 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#error "STACK_REFERENCE_SIZE(X86_64) size not as expected." 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl LITERAL(0), (%rsp) // Store NULL for method* 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 5528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movl %r10d, %ecx // Place size of args in rcx. 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rdi, %rax // RAX := method to be called 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsi, %r11 // R11 := arg_array 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leaq 4(%rsp), %rdi // Rdi is pointing just above the StackReference<method> in the 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // stack arguments. 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Copy arg array into stack. 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rep movsb // while (rcx--) { *rdi++ = *rsi++ } 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leaq 1(%r9), %r10 // R10 := shorty + 1 ; ie skip return arg character 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rax, %rdi // RDI := method to be called 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_GPRS rsi, esi, .Lgpr_setup_finished2 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_GPRS rdx, edx, .Lgpr_setup_finished2 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_GPRS rcx, ecx, .Lgpr_setup_finished2 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_GPRS r8, r8d, .Lgpr_setup_finished2 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LOOP_OVER_SHORTY_LOADING_GPRS r9, r9d, .Lgpr_setup_finished2 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lgpr_setup_finished2: 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call *METHOD_QUICK_CODE_OFFSET_64(%rdi) // Call the method. 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rbp, %rsp // Restore stack pointer. 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_DEF_CFA_REGISTER(rsp) 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r9 // Pop r9 - shorty*. 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP r8 // Pop r8 - result*. 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rbp // Pop rbp 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpb LITERAL(68), (%r9) // Test if result type char == 'D'. 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru je .Lreturn_double_quick2 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpb LITERAL(70), (%r9) // Test if result type char == 'F'. 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru je .Lreturn_float_quick2 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rax, (%r8) // Store the result assuming its a long, int or Object* 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lreturn_double_quick2: 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movsd %xmm0, (%r8) // Store the double floating point result. 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lreturn_float_quick2: 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movss %xmm0, (%r8) // Store the floating point result. 5848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ret 5858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#endif // __APPLE__ 5868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusEND_FUNCTION art_quick_invoke_static_stub 5878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 5888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius /* 5898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * Long jump stub. 5908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * On entry: 5918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * rdi = gprs 5928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * rsi = fprs 5938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius */ 5948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusDEFINE_FUNCTION art_quick_do_long_jump 5958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#if defined(__APPLE__) 5968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int3 5978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int3 5988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#else 5998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Restore FPRs. 6008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 0(%rsi), %xmm0 6018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 8(%rsi), %xmm1 6028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 16(%rsi), %xmm2 6038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 24(%rsi), %xmm3 6048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 32(%rsi), %xmm4 6058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 40(%rsi), %xmm5 6068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 48(%rsi), %xmm6 6078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 56(%rsi), %xmm7 6088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 64(%rsi), %xmm8 6098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 72(%rsi), %xmm9 6108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 80(%rsi), %xmm10 6118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 88(%rsi), %xmm11 61259d709d503bab6e2b61931737e662dd293b40578ccornelius movq 96(%rsi), %xmm12 6138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 104(%rsi), %xmm13 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq 112(%rsi), %xmm14 6158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq 120(%rsi), %xmm15 6168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Restore FPRs. 6178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq %rdi, %rsp // RSP points to gprs. 6188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Load all registers except RSP and RIP with values in gprs. 6198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius popq %r15 6208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius popq %r14 6218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius popq %r13 6228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius popq %r12 6238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius popq %r11 6248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius popq %r10 6258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius popq %r9 6268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius popq %r8 6278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius popq %rdi 6288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius popq %rsi 6298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius popq %rbp 6308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius addq LITERAL(8), %rsp // Skip rsp 6318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius popq %rbx 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru popq %rdx 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru popq %rcx 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru popq %rax 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru popq %rsp // Load stack pointer. 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret // From higher in the stack pop rip. 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif // __APPLE__ 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_FUNCTION art_quick_do_long_jump 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO3(NO_ARG_DOWNCALL, c_name, cxx_name, return_macro) 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DEFINE_FUNCTION VAR(c_name, 0) 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Outgoing argument set up 6448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius movq %rsp, %rsi // pass SP 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rdi // pass Thread::Current() 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call VAR(cxx_name, 1) // cxx_name(Thread*, SP) 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CALL_MACRO(return_macro, 2) // return or deliver exception 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru END_FUNCTION VAR(c_name, 0) 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO3(ONE_ARG_DOWNCALL, c_name, cxx_name, return_macro) 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DEFINE_FUNCTION VAR(c_name, 0) 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Outgoing argument set up 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %rdx // pass SP 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rsi // pass Thread::Current() 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call VAR(cxx_name, 1) // cxx_name(arg0, Thread*, SP) 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CALL_MACRO(return_macro, 2) // return or deliver exception 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru END_FUNCTION VAR(c_name, 0) 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO3(TWO_ARG_DOWNCALL, c_name, cxx_name, return_macro) 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DEFINE_FUNCTION VAR(c_name, 0) 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Outgoing argument set up 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %rcx // pass SP 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rdx // pass Thread::Current() 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call VAR(cxx_name, 1) // cxx_name(arg0, arg1, Thread*, SP) 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CALL_MACRO(return_macro, 2) // return or deliver exception 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru END_FUNCTION VAR(c_name, 0) 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO3(THREE_ARG_DOWNCALL, c_name, cxx_name, return_macro) 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DEFINE_FUNCTION VAR(c_name, 0) 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Outgoing argument set up 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %r8 // pass SP 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rcx // pass Thread::Current() 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call VAR(cxx_name, 1) // cxx_name(arg0, arg1, arg2, Thread*, SP) 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CALL_MACRO(return_macro, 2) // return or deliver exception 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru END_FUNCTION VAR(c_name, 0) 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO3(ONE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DEFINE_FUNCTION VAR(c_name, 0) 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl 8(%rsp), %esi // pass referrer 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_REF_ONLY_CALLEE_SAVE_FRAME 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // arg0 is in rdi 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rdx // pass Thread::Current() 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %rcx // pass SP 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call VAR(cxx_name, 1) // cxx_name(arg0, referrer, Thread*, SP) 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CALL_MACRO(return_macro, 2) 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru END_FUNCTION VAR(c_name, 0) 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO3(TWO_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DEFINE_FUNCTION VAR(c_name, 0) 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl 8(%rsp), %edx // pass referrer 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_REF_ONLY_CALLEE_SAVE_FRAME 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // arg0 and arg1 are in rdi/rsi 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rcx // pass Thread::Current() 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %r8 // pass SP 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call VAR(cxx_name, 1) // (arg0, arg1, referrer, Thread*, SP) 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CALL_MACRO(return_macro, 2) 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru END_FUNCTION VAR(c_name, 0) 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO3(THREE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DEFINE_FUNCTION VAR(c_name, 0) 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl 8(%rsp), %ecx // pass referrer 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_REF_ONLY_CALLEE_SAVE_FRAME 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // arg0, arg1, and arg2 are in rdi/rsi/rdx 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %r8 // pass Thread::Current() 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %r9 // pass SP 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call VAR(cxx_name, 1) // cxx_name(arg0, arg1, arg2, referrer, Thread*, SP) 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CALL_MACRO(return_macro, 2) // return or deliver exception 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru END_FUNCTION VAR(c_name, 0) 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO0(RETURN_IF_RESULT_IS_NON_ZERO) 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testq %rax, %rax // rax == 0 ? 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jz 1f // if rax == 0 goto 1 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret // return 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru1: // deliver exception on current thread 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELIVER_PENDING_EXCEPTION 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO0(RETURN_IF_EAX_ZERO) 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testl %eax, %eax // eax == 0 ? 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jnz 1f // if eax != 0 goto 1 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret // return 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru1: // deliver exception on current thread 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELIVER_PENDING_EXCEPTION 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMACRO0(RETURN_OR_DELIVER_PENDING_EXCEPTION) 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_EXCEPTION_OFFSET, %rcx // get exception field 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testq %rcx, %rcx // rcx == 0 ? 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jnz 1f // if rcx != 0 goto 1 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret // return 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru1: // deliver exception on current thread 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELIVER_PENDING_EXCEPTION 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_MACRO 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Generate the allocation entrypoints for each allocator. 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// TODO: use arch/quick_alloc_entrypoints.S. Currently we don't as we need to use concatenation 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// macros to work around differences between OS/X's as and binutils as (OS/X lacks named arguments 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// to macros and the VAR macro won't concatenate arguments properly), this also breaks having 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// multi-line macros that use each other (hence using 1 macro per newline below). 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(c_suffix, cxx_suffix) \ 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TWO_ARG_DOWNCALL art_quick_alloc_object ## c_suffix, artAllocObjectFromCode ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(c_suffix, cxx_suffix) \ 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TWO_ARG_DOWNCALL art_quick_alloc_object_resolved ## c_suffix, artAllocObjectFromCodeResolved ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(c_suffix, cxx_suffix) \ 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TWO_ARG_DOWNCALL art_quick_alloc_object_initialized ## c_suffix, artAllocObjectFromCodeInitialized ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(c_suffix, cxx_suffix) \ 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TWO_ARG_DOWNCALL art_quick_alloc_object_with_access_check ## c_suffix, artAllocObjectFromCodeWithAccessCheck ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(c_suffix, cxx_suffix) \ 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru THREE_ARG_DOWNCALL art_quick_alloc_array ## c_suffix, artAllocArrayFromCode ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(c_suffix, cxx_suffix) \ 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru THREE_ARG_DOWNCALL art_quick_alloc_array_resolved ## c_suffix, artAllocArrayFromCodeResolved ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(c_suffix, cxx_suffix) \ 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru THREE_ARG_DOWNCALL art_quick_alloc_array_with_access_check ## c_suffix, artAllocArrayFromCodeWithAccessCheck ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(c_suffix, cxx_suffix) \ 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru THREE_ARG_DOWNCALL art_quick_check_and_alloc_array ## c_suffix, artCheckAndAllocArrayFromCode ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(c_suffix, cxx_suffix) \ 7748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius THREE_ARG_DOWNCALL art_quick_check_and_alloc_array_with_access_check ## c_suffix, artCheckAndAllocArrayFromCodeWithAccessCheck ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO 7758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 7768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_dlmalloc, DlMalloc) 7778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_dlmalloc, DlMalloc) 7788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_dlmalloc, DlMalloc) 7798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_dlmalloc, DlMalloc) 7808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_dlmalloc, DlMalloc) 7818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_dlmalloc, DlMalloc) 7828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_dlmalloc, DlMalloc) 7838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_dlmalloc, DlMalloc) 7848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_dlmalloc, DlMalloc) 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_dlmalloc_instrumented, DlMallocInstrumented) 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_dlmalloc_instrumented, DlMallocInstrumented) 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_dlmalloc_instrumented, DlMallocInstrumented) 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_dlmalloc_instrumented, DlMallocInstrumented) 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_dlmalloc_instrumented, DlMallocInstrumented) 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_dlmalloc_instrumented, DlMallocInstrumented) 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_dlmalloc_instrumented, DlMallocInstrumented) 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_dlmalloc_instrumented, DlMallocInstrumented) 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_dlmalloc_instrumented, DlMallocInstrumented) 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_rosalloc, RosAlloc) 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_rosalloc, RosAlloc) 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_rosalloc, RosAlloc) 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_rosalloc, RosAlloc) 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_rosalloc, RosAlloc) 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_rosalloc, RosAlloc) 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_rosalloc, RosAlloc) 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_rosalloc, RosAlloc) 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_rosalloc, RosAlloc) 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_rosalloc_instrumented, RosAllocInstrumented) 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_rosalloc_instrumented, RosAllocInstrumented) 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_rosalloc_instrumented, RosAllocInstrumented) 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_rosalloc_instrumented, RosAllocInstrumented) 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_rosalloc_instrumented, RosAllocInstrumented) 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_rosalloc_instrumented, RosAllocInstrumented) 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_rosalloc_instrumented, RosAllocInstrumented) 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_rosalloc_instrumented, RosAllocInstrumented) 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_rosalloc_instrumented, RosAllocInstrumented) 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_bump_pointer, BumpPointer) 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_bump_pointer, BumpPointer) 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_bump_pointer, BumpPointer) 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_bump_pointer, BumpPointer) 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_bump_pointer, BumpPointer) 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_bump_pointer, BumpPointer) 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_bump_pointer, BumpPointer) 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_bump_pointer, BumpPointer) 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_bump_pointer, BumpPointer) 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_bump_pointer_instrumented, BumpPointerInstrumented) 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_bump_pointer_instrumented, BumpPointerInstrumented) 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_bump_pointer_instrumented, BumpPointerInstrumented) 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_bump_pointer_instrumented, BumpPointerInstrumented) 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_bump_pointer_instrumented, BumpPointerInstrumented) 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_bump_pointer_instrumented, BumpPointerInstrumented) 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_bump_pointer_instrumented, BumpPointerInstrumented) 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_bump_pointer_instrumented, BumpPointerInstrumented) 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_bump_pointer_instrumented, BumpPointerInstrumented) 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_tlab, TLAB) 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB) 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB) 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB) 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_tlab, TLAB) 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB) 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_tlab, TLAB) 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_tlab, TLAB) 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_tlab, TLAB) 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_tlab_instrumented, TLABInstrumented) 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab_instrumented, TLABInstrumented) 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab_instrumented, TLABInstrumented) 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab_instrumented, TLABInstrumented) 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_tlab_instrumented, TLABInstrumented) 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab_instrumented, TLABInstrumented) 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_tlab_instrumented, TLABInstrumented) 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_tlab_instrumented, TLABInstrumented) 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruGENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_tlab_instrumented, TLABInstrumented) 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTWO_ARG_DOWNCALL art_quick_resolve_string, artResolveStringFromCode, RETURN_IF_RESULT_IS_NON_ZERO 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTWO_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode, RETURN_IF_RESULT_IS_NON_ZERO 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTWO_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_RESULT_IS_NON_ZERO 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTWO_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_RESULT_IS_NON_ZERO 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTWO_ARG_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDEFINE_FUNCTION art_quick_lock_object 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testl %edi, %edi // Null check object/rdi. 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jz .Lslow_lock 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lretry_lock: 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl LOCK_WORD_OFFSET(%edi), %ecx // ecx := lock word. 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru test LITERAL(0xC0000000), %ecx // Test the 2 high bits. 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jne .Lslow_lock // Slow path if either of the two high bits are set. 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl %gs:THREAD_ID_OFFSET, %edx // edx := thread id 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru test %ecx, %ecx 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jnz .Lalready_thin // Lock word contains a thin lock. 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // unlocked case - %edx holds thread id with count of 0 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru xor %eax, %eax // eax == 0 for comparison with lock word in cmpxchg 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lock cmpxchg %edx, LOCK_WORD_OFFSET(%edi) 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jnz .Lretry_lock // cmpxchg failed retry 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lalready_thin: 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpw %cx, %dx // do we hold the lock already? 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jne .Lslow_lock 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addl LITERAL(65536), %ecx // increment recursion count 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru test LITERAL(0xC0000000), %ecx // overflowed if either of top two bits are set 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jne .Lslow_lock // count overflowed so go slow 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl %ecx, LOCK_WORD_OFFSET(%edi) // update lockword, cmpxchg not necessary as we hold lock 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lslow_lock: 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_REF_ONLY_CALLEE_SAVE_FRAME 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rsi // pass Thread::Current() 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %rdx // pass SP 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call SYMBOL(artLockObjectFromCode) // artLockObjectFromCode(object, Thread*, SP) 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_EAX_ZERO 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_FUNCTION art_quick_lock_object 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDEFINE_FUNCTION art_quick_unlock_object 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testl %edi, %edi // null check object/edi 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jz .Lslow_unlock 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl LOCK_WORD_OFFSET(%edi), %ecx // ecx := lock word 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl %gs:THREAD_ID_OFFSET, %edx // edx := thread id 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru test LITERAL(0xC0000000), %ecx 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jnz .Lslow_unlock // lock word contains a monitor 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpw %cx, %dx // does the thread id match? 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jne .Lslow_unlock 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpl LITERAL(65536), %ecx 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jae .Lrecursive_thin_unlock 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl LITERAL(0), LOCK_WORD_OFFSET(%edi) 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lrecursive_thin_unlock: 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subl LITERAL(65536), %ecx 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru mov %ecx, LOCK_WORD_OFFSET(%edi) 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lslow_unlock: 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_REF_ONLY_CALLEE_SAVE_FRAME 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rsi // pass Thread::Current() 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %rdx // pass SP 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call SYMBOL(artUnlockObjectFromCode) // artUnlockObjectFromCode(object, Thread*, SP) 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_EAX_ZERO 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_FUNCTION art_quick_unlock_object 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDEFINE_FUNCTION art_quick_check_cast 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rdi // Save args for exc 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rsi 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_FP_CALLEE_SAVE_FRAME 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call SYMBOL(artIsAssignableFromCode) // (Class* klass, Class* ref_klass) 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testq %rax, %rax 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jz 1f // jump forward if not assignable 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_FP_CALLEE_SAVE_FRAME 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq LITERAL(16), %rsp // pop arguments 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(-16) 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru1: 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_FP_CALLEE_SAVE_FRAME 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rsi // Pop arguments 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rdi 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru mov %rsp, %rcx // pass SP 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru mov %gs:THREAD_SELF_OFFSET, %rdx // pass Thread::Current() 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call SYMBOL(artThrowClassCastException) // (Class* a, Class* b, Thread*, SP) 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 // unreached 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_FUNCTION art_quick_check_cast 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Entry from managed code for array put operations of objects where the value being stored 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * needs to be checked for compatibility. 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Currently all the parameters should fit into the 32b portions of the registers. Index always 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * will. So we optimize for a tighter encoding. The 64b versions are in comments. 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * rdi(edi) = array, rsi(esi) = index, rdx(edx) = value 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDEFINE_FUNCTION art_quick_aput_obj_with_null_and_bound_check 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(__APPLE__) 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testl %edi, %edi 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// testq %rdi, %rdi 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jnz art_quick_aput_obj_with_bound_check 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jmp art_quick_throw_null_pointer_exception 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif // __APPLE__ 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_FUNCTION art_quick_aput_obj_with_null_and_bound_check 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDEFINE_FUNCTION art_quick_aput_obj_with_bound_check 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(__APPLE__) 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl ARRAY_LENGTH_OFFSET(%edi), %ecx 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// movl ARRAY_LENGTH_OFFSET(%rdi), %ecx // This zero-extends, so value(%rcx)=value(%ecx) 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpl %ecx, %esi 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jb art_quick_aput_obj 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru mov %esi, %edi 977b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// mov %rsi, %rdi 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru mov %ecx, %esi 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// mov %rcx, %rsi 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jmp art_quick_throw_array_bounds 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif // __APPLE__ 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_FUNCTION art_quick_aput_obj_with_bound_check 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 984b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 985b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDEFINE_FUNCTION art_quick_aput_obj 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testl %edx, %edx // store of null 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// test %rdx, %rdx 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jz .Ldo_aput_null 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl CLASS_OFFSET(%edi), %ecx 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// movq CLASS_OFFSET(%rdi), %rcx 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl CLASS_COMPONENT_TYPE_OFFSET(%ecx), %ecx 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// movq CLASS_COMPONENT_TYPE_OFFSET(%rcx), %rcx 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cmpl CLASS_OFFSET(%edx), %ecx // value's type == array's component type - trivial assignability 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// cmpq CLASS_OFFSET(%rdx), %rcx 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jne .Lcheck_assignability 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Ldo_aput: 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl %edx, OBJECT_ARRAY_DATA_OFFSET(%edi, %esi, 4) 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// movq %rdx, OBJECT_ARRAY_DATA_OFFSET(%rdi, %rsi, 4) 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_CARD_TABLE_OFFSET, %rdx 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru shrl LITERAL(7), %edi 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// shrl LITERAL(7), %rdi 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movb %dl, (%rdx, %rdi) // Note: this assumes that top 32b of %rdi are zero 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Ldo_aput_null: 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl %edx, OBJECT_ARRAY_DATA_OFFSET(%edi, %esi, 4) 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// movq %rdx, OBJECT_ARRAY_DATA_OFFSET(%rdi, %rsi, 4) 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lcheck_assignability: 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Save arguments. 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rdi 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rsi 1012b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru PUSH rdx 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subq LITERAL(8), %rsp // Alignment padding. 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(8) 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_FP_CALLEE_SAVE_FRAME 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // "Uncompress" = do nothing, as already zero-extended on load. 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl CLASS_OFFSET(%edx), %esi // Pass arg2 = value's class. 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rcx, %rdi // Pass arg1 = array's component type. 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call SYMBOL(artIsAssignableFromCode) // (Class* a, Class* b) 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Exception? 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testq %rax, %rax 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jz .Lthrow_array_store_exception 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_FP_CALLEE_SAVE_FRAME 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Restore arguments. 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq LITERAL(8), %rsp 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(-8) 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rdx 1032b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru POP rsi 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rdi 1034b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1035b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru movl %edx, OBJECT_ARRAY_DATA_OFFSET(%edi, %esi, 4) 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// movq %rdx, OBJECT_ARRAY_DATA_OFFSET(%rdi, %rsi, 4) 103727f654740f2a26ad62a5c155af9199af9e69b889claireho movq %gs:THREAD_CARD_TABLE_OFFSET, %rdx 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru shrl LITERAL(7), %edi 1039b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// shrl LITERAL(7), %rdi 1040b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru movb %dl, (%rdx, %rdi) // Note: this assumes that top 32b of %rdi are zero 1041b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// movb %dl, (%rdx, %rdi) 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru.Lthrow_array_store_exception: 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_FP_CALLEE_SAVE_FRAME 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Restore arguments. 1046b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru addq LITERAL(8), %rsp 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(-8) 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru POP rdx 1049b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru POP rsi 1050b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru POP rdi 1051b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // Save all registers as basis for long jump context. 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1054b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Outgoing argument set up. 1055b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru movq %rsp, %rcx // Pass arg 4 = SP. 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rdx, %rsi // Pass arg 2 = value. 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rdx // Pass arg 3 = Thread::Current(). 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Pass arg 1 = array. 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call SYMBOL(artThrowArrayStoreException) // (array, value, Thread*, SP) 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 // unreached 1062b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruEND_FUNCTION art_quick_aput_obj 1063b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1064b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// TODO: This is quite silly on X86_64 now. 1065b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruDEFINE_FUNCTION art_quick_memcpy 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call PLT_SYMBOL(memcpy) // (void*, const void*, size_t) 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_FUNCTION art_quick_memcpy 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruNO_ARG_DOWNCALL art_quick_test_suspend, artTestSuspendFromCode, ret 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUNIMPLEMENTED art_quick_ldiv 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUNIMPLEMENTED art_quick_lmod 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUNIMPLEMENTED art_quick_lmul 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUNIMPLEMENTED art_quick_lshl 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUNIMPLEMENTED art_quick_lshr 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUNIMPLEMENTED art_quick_lushr 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTHREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCode, RETURN_IF_EAX_ZERO 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTHREE_ARG_DOWNCALL art_quick_set64_instance, artSet64InstanceFromCode, RETURN_IF_EAX_ZERO 1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTHREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCode, RETURN_IF_EAX_ZERO 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCode, RETURN_IF_EAX_ZERO 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCode, RETURN_IF_EAX_ZERO 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1090b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 1091b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 1093b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1094b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// This is singled out as the argument order is different. 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDEFINE_FUNCTION art_quick_set64_static 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsi, %rdx // pass new_val 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl 8(%rsp), %esi // pass referrer 1098b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru SETUP_REF_ONLY_CALLEE_SAVE_FRAME 1099b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // field_idx is in rdi 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rcx // pass Thread::Current() 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %r8 // pass SP 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call SYMBOL(artSet64StaticFromCode) // (field_idx, referrer, new_val, Thread*, SP) 1103b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_IF_EAX_ZERO // return or deliver exception 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_FUNCTION art_quick_set64_static 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDEFINE_FUNCTION art_quick_proxy_invoke_handler 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Save callee and GPR args, mixed together to agree with core spills bitmap of ref. and args 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // callee save frame. 1111b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru PUSH r15 // Callee save. 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r14 // Callee save. 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r13 // Callee save. 1114b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru PUSH r12 // Callee save. 1115b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru PUSH r9 // Quick arg 5. 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r8 // Quick arg 4. 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rsi // Quick arg 1. 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rbp // Callee save. 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rbx // Callee save. 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rdx // Quick arg 2. 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rcx // Quick arg 3. 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create space for FPR args and create 2 slots, 1 of padding and 1 for the ArtMethod*. 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subq LITERAL(80 + 4*8), %rsp 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(80 + 4*8) 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Save FPRs. 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm0, 16(%rsp) 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm1, 24(%rsp) 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm2, 32(%rsp) 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm3, 40(%rsp) 1130b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru movq %xmm4, 48(%rsp) 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm5, 56(%rsp) 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm6, 64(%rsp) 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm7, 72(%rsp) 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm12, 80(%rsp) 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm13, 88(%rsp) 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm14, 96(%rsp) 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm15, 104(%rsp) 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Store proxy method to bottom of stack. 1139b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru movq %rdi, 0(%rsp) 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rdx // Pass Thread::Current(). 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rsp, %rcx // Pass SP. 1142b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru call SYMBOL(artQuickProxyInvokeHandler) // (proxy method, receiver, Thread*, SP) 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rax, %xmm0 // Copy return value in case of float returns. 1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addq LITERAL(168 + 4*8), %rsp // Pop arguments. 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(-168 - 4*8) 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RETURN_OR_DELIVER_PENDING_EXCEPTION 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_FUNCTION art_quick_proxy_invoke_handler 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Called to resolve an imt conflict. 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * rax is a hidden argument that holds the target method's dex method index. 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDEFINE_FUNCTION art_quick_imt_conflict_trampoline 1154b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#if defined(__APPLE__) 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int3 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl 8(%rsp), %edi // load caller Method* 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl METHOD_DEX_CACHE_METHODS_OFFSET(%rdi), %edi // load dex_cache_resolved_methods 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movl OBJECT_ARRAY_DATA_OFFSET(%rdi, %rax, 4), %edi // load the target method 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jmp art_quick_invoke_interface_trampoline 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif // __APPLE__ 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_FUNCTION art_quick_imt_conflict_trampoline 1164b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDEFINE_FUNCTION art_quick_resolution_trampoline 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %gs:THREAD_SELF_OFFSET, %rdx 116850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho movq %rsp, %rcx 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru call SYMBOL(artQuickResolutionTrampoline) // (called, receiver, Thread*, SP) 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rax, %r10 // Remember returned code pointer in R10. 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq (%rsp), %rdi // Load called method into RDI. 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testq %r10, %r10 // If code pointer is NULL goto deliver pending exception. 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jz 1f 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jmp *%r10 // Tail call into method. 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru1: 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DELIVER_PENDING_EXCEPTION 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruEND_FUNCTION art_quick_resolution_trampoline 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Generic JNI frame layout: 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | | 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | caller method... | 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# <--- SP on entry 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | 1188b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * V 1189b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | caller method... | 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | Return | 1194b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * | R15 | callee save 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | R14 | callee save 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | R13 | callee save 1197b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * | R12 | callee save 1198b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * | R9 | arg5 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | R8 | arg4 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | RSI/R6 | arg1 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | RBP/R5 | callee save 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | RBX/R3 | callee save 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | RDX/R2 | arg2 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | RCX/R1 | arg3 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | XMM7 | float arg 8 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | XMM6 | float arg 7 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | XMM5 | float arg 6 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | XMM4 | float arg 5 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | XMM3 | float arg 4 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | XMM2 | float arg 3 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | XMM1 | float arg 2 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | XMM0 | float arg 1 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | Padding | 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | RDI/Method* | <- sp 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | Scratch Alloca | 5K scratch space 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #---------#---------# 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | | sp* | 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | Tramp. #---------# 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | args | thread | 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | Tramp. #---------# 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | | method | 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# <--- SP on artQuickGenericJniTrampoline 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * v artQuickGenericJniTrampoline 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | caller method... | 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | Return | 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | Callee-Save Data | 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | handle scope | 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | Method* | <--- (1) 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | local ref cookie | // 4B 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | handle scope size | // 4B TODO: roll into call stack alignment? 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | JNI Call Stack | 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# <--- SP on native call 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | | 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | Stack for Regs | The trampoline assembly will pop these values 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | | into registers for native call 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | Native code ptr | 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | Free scratch | 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * | Ptr to (1) | <--- RSP 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * #-------------------# 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Called to do a generic JNI down-call 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDEFINE_FUNCTION_NO_HIDE art_quick_generic_jni_trampoline 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Save callee and GPR args, mixed together to agree with core spills bitmap. 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r15 // Callee save. 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r14 // Callee save. 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r13 // Callee save. 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r12 // Callee save. 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r9 // Quick arg 5. 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH r8 // Quick arg 4. 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rsi // Quick arg 1. 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rbp // Callee save. 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rbx // Callee save. 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rdx // Quick arg 2. 1269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru PUSH rcx // Quick arg 3. 1270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create space for FPR args and create 2 slots, 1 of padding and 1 for the ArtMethod*. 1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru subq LITERAL(80 + 4*8), %rsp 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CFI_ADJUST_CFA_OFFSET(80 + 4*8) 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Save FPRs. 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm0, 16(%rsp) 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm1, 24(%rsp) 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm2, 32(%rsp) 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm3, 40(%rsp) 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm4, 48(%rsp) 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm5, 56(%rsp) 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm6, 64(%rsp) 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm7, 72(%rsp) 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm12, 80(%rsp) 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm13, 88(%rsp) 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm14, 96(%rsp) 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %xmm15, 104(%rsp) 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru movq %rdi, 0(%rsp) // Store native ArtMethod* to bottom of stack. 128727f654740f2a26ad62a5c155af9199af9e69b889claireho movq %rsp, %rbp // save SP at (old) callee-save frame 128827f654740f2a26ad62a5c155af9199af9e69b889claireho CFI_DEF_CFA_REGISTER(rbp) 128927f654740f2a26ad62a5c155af9199af9e69b889claireho // 129027f654740f2a26ad62a5c155af9199af9e69b889claireho // reserve a lot of space 129127f654740f2a26ad62a5c155af9199af9e69b889claireho // 129227f654740f2a26ad62a5c155af9199af9e69b889claireho // 4 local state ref 129327f654740f2a26ad62a5c155af9199af9e69b889claireho // 4 padding 129427f654740f2a26ad62a5c155af9199af9e69b889claireho // 4196 4k scratch space, enough for 2x 256 8-byte parameters (TODO: handle scope overhead?) 129559d709d503bab6e2b61931737e662dd293b40578ccornelius // 16 handle scope member fields ? 129659d709d503bab6e2b61931737e662dd293b40578ccornelius // + 112 14x 8-byte stack-2-register space 129727f654740f2a26ad62a5c155af9199af9e69b889claireho // ------ 129827f654740f2a26ad62a5c155af9199af9e69b889claireho // 4332 129927f654740f2a26ad62a5c155af9199af9e69b889claireho // 16-byte aligned: 4336 130027f654740f2a26ad62a5c155af9199af9e69b889claireho // Note: 14x8 = 7*16, so the stack stays aligned for the native call... 130127f654740f2a26ad62a5c155af9199af9e69b889claireho // Also means: the padding is somewhere in the middle 130227f654740f2a26ad62a5c155af9199af9e69b889claireho // 130327f654740f2a26ad62a5c155af9199af9e69b889claireho // 130427f654740f2a26ad62a5c155af9199af9e69b889claireho // New test: use 5K and release 130527f654740f2a26ad62a5c155af9199af9e69b889claireho // 5k = 5120 130627f654740f2a26ad62a5c155af9199af9e69b889claireho subq LITERAL(5120), %rsp 130727f654740f2a26ad62a5c155af9199af9e69b889claireho // prepare for artQuickGenericJniTrampoline call 130827f654740f2a26ad62a5c155af9199af9e69b889claireho // (Thread*, SP) 130927f654740f2a26ad62a5c155af9199af9e69b889claireho // rdi rsi <= C calling convention 131027f654740f2a26ad62a5c155af9199af9e69b889claireho // gs:... rbp <= where they are 131127f654740f2a26ad62a5c155af9199af9e69b889claireho movq %gs:THREAD_SELF_OFFSET, %rdi 131227f654740f2a26ad62a5c155af9199af9e69b889claireho movq %rbp, %rsi 131327f654740f2a26ad62a5c155af9199af9e69b889claireho call SYMBOL(artQuickGenericJniTrampoline) // (Thread*, sp) 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1315 // The C call will have registered the complete save-frame on success. 1316 // The result of the call is: 1317 // %rax: pointer to native code, 0 on error. 1318 // %rdx: pointer to the bottom of the used area of the alloca, can restore stack till there. 1319 1320 // Check for error = 0. 1321 test %rax, %rax 1322 jz .Lentry_error 1323 1324 // Release part of the alloca. 1325 movq %rdx, %rsp 1326 1327 // pop from the register-passing alloca region 1328 // what's the right layout? 1329 popq %rdi 1330 popq %rsi 1331 popq %rdx 1332 popq %rcx 1333 popq %r8 1334 popq %r9 1335 // TODO: skip floating point if unused, some flag. 1336 movq 0(%rsp), %xmm0 1337 movq 8(%rsp), %xmm1 1338 movq 16(%rsp), %xmm2 1339 movq 24(%rsp), %xmm3 1340 movq 32(%rsp), %xmm4 1341 movq 40(%rsp), %xmm5 1342 movq 48(%rsp), %xmm6 1343 movq 56(%rsp), %xmm7 1344 addq LITERAL(64), %rsp // floating-point done 1345 1346 // native call 1347 call *%rax 1348 1349 // result sign extension is handled in C code 1350 // prepare for artQuickGenericJniEndTrampoline call 1351 // (Thread*, result, result_f) 1352 // rdi rsi rdx <= C calling convention 1353 // gs:... rax xmm0 <= where they are 1354 movq %gs:THREAD_SELF_OFFSET, %rdi 1355 movq %rax, %rsi 1356 movq %xmm0, %rdx 1357 call SYMBOL(artQuickGenericJniEndTrampoline) 1358 1359 // Tear down the alloca. 1360 movq %rbp, %rsp 1361 CFI_DEF_CFA_REGISTER(rsp) 1362 1363 // Pending exceptions possible. 1364 // TODO: use cmpq, needs direct encoding because of gas bug 1365 movq %gs:THREAD_EXCEPTION_OFFSET, %rcx 1366 test %rcx, %rcx 1367 jnz .Lexception_in_native 1368 1369 // Tear down the callee-save frame. 1370 // Load FPRs. 1371 // movq %xmm0, 16(%rsp) // doesn't make sense!!! 1372 movq 24(%rsp), %xmm1 // neither does this!!! 1373 movq 32(%rsp), %xmm2 1374 movq 40(%rsp), %xmm3 1375 movq 48(%rsp), %xmm4 1376 movq 56(%rsp), %xmm5 1377 movq 64(%rsp), %xmm6 1378 movq 72(%rsp), %xmm7 1379 movq 80(%rsp), %xmm12 1380 movq 88(%rsp), %xmm13 1381 movq 96(%rsp), %xmm14 1382 movq 104(%rsp), %xmm15 1383 // was 80 bytes 1384 addq LITERAL(80 + 4*8), %rsp 1385 CFI_ADJUST_CFA_OFFSET(-80 - 4*8) 1386 // Save callee and GPR args, mixed together to agree with core spills bitmap. 1387 POP rcx // Arg. 1388 POP rdx // Arg. 1389 POP rbx // Callee save. 1390 POP rbp // Callee save. 1391 POP rsi // Arg. 1392 POP r8 // Arg. 1393 POP r9 // Arg. 1394 POP r12 // Callee save. 1395 POP r13 // Callee save. 1396 POP r14 // Callee save. 1397 POP r15 // Callee save. 1398 // store into fpr, for when it's a fpr return... 1399 movq %rax, %xmm0 1400 ret 1401.Lentry_error: 1402 movq %rbp, %rsp 1403 CFI_DEF_CFA_REGISTER(rsp) 1404.Lexception_in_native: 1405 // TODO: the handle scope contains the this pointer which is used by the debugger for exception 1406 // delivery. 1407 movq %xmm0, 16(%rsp) // doesn't make sense!!! 1408 movq 24(%rsp), %xmm1 // neither does this!!! 1409 movq 32(%rsp), %xmm2 1410 movq 40(%rsp), %xmm3 1411 movq 48(%rsp), %xmm4 1412 movq 56(%rsp), %xmm5 1413 movq 64(%rsp), %xmm6 1414 movq 72(%rsp), %xmm7 1415 movq 80(%rsp), %xmm12 1416 movq 88(%rsp), %xmm13 1417 movq 96(%rsp), %xmm14 1418 movq 104(%rsp), %xmm15 1419 // was 80 + 32 bytes 1420 addq LITERAL(80 + 4*8), %rsp 1421 CFI_ADJUST_CFA_OFFSET(-80 - 4*8) 1422 // Save callee and GPR args, mixed together to agree with core spills bitmap. 1423 POP rcx // Arg. 1424 POP rdx // Arg. 1425 POP rbx // Callee save. 1426 POP rbp // Callee save. 1427 POP rsi // Arg. 1428 POP r8 // Arg. 1429 POP r9 // Arg. 1430 POP r12 // Callee save. 1431 POP r13 // Callee save. 1432 POP r14 // Callee save. 1433 POP r15 // Callee save. 1434 1435 DELIVER_PENDING_EXCEPTION 1436END_FUNCTION art_quick_generic_jni_trampoline 1437 1438 /* 1439 * Called to bridge from the quick to interpreter ABI. On entry the arguments match those 1440 * of a quick call: 1441 * RDI = method being called / to bridge to. 1442 * RSI, RDX, RCX, R8, R9 are arguments to that method. 1443 */ 1444DEFINE_FUNCTION_NO_HIDE art_quick_to_interpreter_bridge 1445 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // Set up frame and save arguments. 1446 movq %gs:THREAD_SELF_OFFSET, %rsi // RSI := Thread::Current() 1447 movq %rsp, %rdx // RDX := sp 1448 call SYMBOL(artQuickToInterpreterBridge) // (method, Thread*, SP) 1449 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME // TODO: no need to restore arguments in this case. 1450 movq %rax, %xmm0 // Place return value also into floating point return value. 1451 RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception 1452END_FUNCTION art_quick_to_interpreter_bridge 1453 1454 /* 1455 * Routine that intercepts method calls and returns. 1456 */ 1457DEFINE_FUNCTION art_quick_instrumentation_entry 1458#if defined(__APPLE__) 1459 int3 1460 int3 1461#else 1462 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME 1463 1464 movq %rdi, %r12 // Preserve method pointer in a callee-save. 1465 1466 movq %gs:THREAD_SELF_OFFSET, %rdx // Pass thread. 1467 movq %rsp, %rcx // Pass SP. 1468 movq FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE-8(%rsp), %r8 // Pass return PC. 1469 1470 call SYMBOL(artInstrumentationMethodEntryFromCode) // (Method*, Object*, Thread*, SP, LR) 1471 1472 // %rax = result of call. 1473 movq %r12, %rdi // Reload method pointer. 1474 1475 leaq art_quick_instrumentation_exit(%rip), %r12 // Set up return through instrumentation 1476 movq %r12, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE-8(%rsp) // exit. 1477 1478 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME 1479 1480 jmp *%rax // Tail call to intended method. 1481#endif // __APPLE__ 1482END_FUNCTION art_quick_instrumentation_entry 1483 1484DEFINE_FUNCTION art_quick_instrumentation_exit 1485 pushq LITERAL(0) // Push a fake return PC as there will be none on the stack. 1486 1487 SETUP_REF_ONLY_CALLEE_SAVE_FRAME 1488 1489 // We need to save rax and xmm0. We could use a callee-save from SETUP_REF_ONLY, but then 1490 // we would need to fully restore it. As there are a good number of callee-save registers, it 1491 // seems easier to have an extra small stack area. But this should be revisited. 1492 1493 movq %rsp, %rsi // Pass SP. 1494 1495 PUSH rax // Save integer result. 1496 subq LITERAL(8), %rsp // Save floating-point result. 1497 CFI_ADJUST_CFA_OFFSET(8) 1498 movq %xmm0, (%rsp) 1499 1500 movq %gs:THREAD_SELF_OFFSET, %rdi // Pass Thread. 1501 movq %rax, %rdx // Pass integer result. 1502 movq %xmm0, %rcx // Pass floating-point result. 1503 1504 call SYMBOL(artInstrumentationMethodExitFromCode) // (Thread*, SP, gpr_res, fpr_res) 1505 1506 movq %rax, %rdi // Store return PC 1507 movq %rdx, %rsi // Store second return PC in hidden arg. 1508 1509 movq (%rsp), %xmm0 // Restore floating-point result. 1510 addq LITERAL(8), %rsp 1511 CFI_ADJUST_CFA_OFFSET(-8) 1512 POP rax // Restore integer result. 1513 1514 addq LITERAL(FRAME_SIZE_REFS_ONLY_CALLEE_SAVE), %rsp // Drop save frame and fake return pc. 1515 1516 jmp *%rdi // Return. 1517END_FUNCTION art_quick_instrumentation_exit 1518 1519 /* 1520 * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization 1521 * will long jump to the upcall with a special exception of -1. 1522 */ 1523DEFINE_FUNCTION art_quick_deoptimize 1524 pushq %rsi // Fake that we were called. Use hidden arg. 1525 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME 1526 // Stack should be aligned now. 1527 movq %rsp, %rsi // Pass SP. 1528 movq %gs:THREAD_SELF_OFFSET, %rdi // Pass Thread. 1529 call SYMBOL(artDeoptimize) // artDeoptimize(Thread*, SP) 1530 int3 // Unreachable. 1531END_FUNCTION art_quick_deoptimize 1532 1533 1534 /* 1535 * String's compareTo. 1536 * 1537 * On entry: 1538 * rdi: this string object (known non-null) 1539 * rsi: comp string object (known non-null) 1540 */ 1541DEFINE_FUNCTION art_quick_string_compareto 1542 movl STRING_COUNT_OFFSET(%edi), %r8d 1543 movl STRING_COUNT_OFFSET(%esi), %r9d 1544 movl STRING_VALUE_OFFSET(%edi), %r10d 1545 movl STRING_VALUE_OFFSET(%esi), %r11d 1546 movl STRING_OFFSET_OFFSET(%edi), %eax 1547 movl STRING_OFFSET_OFFSET(%esi), %ecx 1548 /* Build pointers to the start of string data */ 1549 leal STRING_DATA_OFFSET(%r10d, %eax, 2), %esi 1550 leal STRING_DATA_OFFSET(%r11d, %ecx, 2), %edi 1551 /* Calculate min length and count diff */ 1552 movl %r8d, %ecx 1553 movl %r8d, %eax 1554 subl %r9d, %eax 1555 cmovg %r9d, %ecx 1556 /* 1557 * At this point we have: 1558 * eax: value to return if first part of strings are equal 1559 * ecx: minimum among the lengths of the two strings 1560 * esi: pointer to this string data 1561 * edi: pointer to comp string data 1562 */ 1563 jecxz .Lkeep_length 1564 repe cmpsw // find nonmatching chars in [%esi] and [%edi], up to length %ecx 1565 jne .Lnot_equal 1566.Lkeep_length: 1567 ret 1568 .balign 16 1569.Lnot_equal: 1570 movzwl -2(%esi), %eax // get last compared char from this string 1571 movzwl -2(%edi), %ecx // get last compared char from comp string 1572 subl %ecx, %eax // return the difference 1573 ret 1574END_FUNCTION art_quick_string_compareto 1575 1576UNIMPLEMENTED art_quick_memcmp16 1577 1578DEFINE_FUNCTION art_quick_assignable_from_code 1579 SETUP_FP_CALLEE_SAVE_FRAME 1580 call SYMBOL(artIsAssignableFromCode) // (const mirror::Class*, const mirror::Class*) 1581 RESTORE_FP_CALLEE_SAVE_FRAME 1582 ret 1583END_FUNCTION art_quick_assignable_from_code 1584 1585 1586// Return from a nested signal: 1587// Entry: 1588// rdi: address of jmp_buf in TLS 1589 1590DEFINE_FUNCTION art_nested_signal_return 1591 // first arg to longjmp is already in correct register 1592 movq LITERAL(1), %rsi // second arg to longjmp (1) 1593 call PLT_SYMBOL(longjmp) 1594 int3 // won't get here 1595END_FUNCTION art_nested_signal_return 1596 1597 1598