17655f29fabc0a12765de828914a18314382e5a35Ian Rogers/*
27655f29fabc0a12765de828914a18314382e5a35Ian Rogers * Copyright (C) 2012 The Android Open Source Project
37655f29fabc0a12765de828914a18314382e5a35Ian Rogers *
47655f29fabc0a12765de828914a18314382e5a35Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License");
57655f29fabc0a12765de828914a18314382e5a35Ian Rogers * you may not use this file except in compliance with the License.
67655f29fabc0a12765de828914a18314382e5a35Ian Rogers * You may obtain a copy of the License at
77655f29fabc0a12765de828914a18314382e5a35Ian Rogers *
87655f29fabc0a12765de828914a18314382e5a35Ian Rogers *      http://www.apache.org/licenses/LICENSE-2.0
97655f29fabc0a12765de828914a18314382e5a35Ian Rogers *
107655f29fabc0a12765de828914a18314382e5a35Ian Rogers * Unless required by applicable law or agreed to in writing, software
117655f29fabc0a12765de828914a18314382e5a35Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS,
127655f29fabc0a12765de828914a18314382e5a35Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137655f29fabc0a12765de828914a18314382e5a35Ian Rogers * See the License for the specific language governing permissions and
147655f29fabc0a12765de828914a18314382e5a35Ian Rogers * limitations under the License.
157655f29fabc0a12765de828914a18314382e5a35Ian Rogers */
167655f29fabc0a12765de828914a18314382e5a35Ian Rogers
177655f29fabc0a12765de828914a18314382e5a35Ian Rogers#include "asm_support_arm.S"
187655f29fabc0a12765de828914a18314382e5a35Ian Rogers
197655f29fabc0a12765de828914a18314382e5a35Ian Rogers    /*
207655f29fabc0a12765de828914a18314382e5a35Ian Rogers     * Portable invocation stub.
217655f29fabc0a12765de828914a18314382e5a35Ian Rogers     * On entry:
227655f29fabc0a12765de828914a18314382e5a35Ian Rogers     *   r0 = method pointer
237655f29fabc0a12765de828914a18314382e5a35Ian Rogers     *   r1 = argument array or NULL for no argument methods
247655f29fabc0a12765de828914a18314382e5a35Ian Rogers     *   r2 = size of argument array in bytes
257655f29fabc0a12765de828914a18314382e5a35Ian Rogers     *   r3 = (managed) thread pointer
267655f29fabc0a12765de828914a18314382e5a35Ian Rogers     *   [sp] = JValue* result
277655f29fabc0a12765de828914a18314382e5a35Ian Rogers     *   [sp + 4] = result type char
287655f29fabc0a12765de828914a18314382e5a35Ian Rogers     */
297655f29fabc0a12765de828914a18314382e5a35Ian RogersENTRY art_portable_invoke_stub
307655f29fabc0a12765de828914a18314382e5a35Ian Rogers    push   {r0, r4, r5, r9, r11, lr}       @ spill regs
317655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .save  {r0, r4, r5, r9, r11, lr}
327655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_adjust_cfa_offset 24
337655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r0, 0
347655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r4, 4
357655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r5, 8
367655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r9, 12
377655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r11, 16
387655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset lr, 20
397655f29fabc0a12765de828914a18314382e5a35Ian Rogers    mov    r11, sp                         @ save the stack pointer
407655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_def_cfa_register r11
4108bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    @.movsp r11
427655f29fabc0a12765de828914a18314382e5a35Ian Rogers    mov    r9, r3                          @ move managed thread pointer into r9
437655f29fabc0a12765de828914a18314382e5a35Ian Rogers    mov    r4, #SUSPEND_CHECK_INTERVAL     @ reset r4 to suspend check interval
447655f29fabc0a12765de828914a18314382e5a35Ian Rogers    add    r5, r2, #16                     @ create space for method pointer in frame
457655f29fabc0a12765de828914a18314382e5a35Ian Rogers    and    r5, #0xFFFFFFF0                 @ align frame size to 16 bytes
467655f29fabc0a12765de828914a18314382e5a35Ian Rogers    sub    sp, r5                          @ reserve stack space for argument array
477655f29fabc0a12765de828914a18314382e5a35Ian Rogers    add    r0, sp, #4                      @ pass stack pointer + method ptr as dest for memcpy
487655f29fabc0a12765de828914a18314382e5a35Ian Rogers    bl     memcpy                          @ memcpy (dest, src, bytes)
497655f29fabc0a12765de828914a18314382e5a35Ian Rogers    ldr    r0, [r11]                       @ restore method*
507655f29fabc0a12765de828914a18314382e5a35Ian Rogers    ldr    r1, [sp, #4]                    @ copy arg value for r1
517655f29fabc0a12765de828914a18314382e5a35Ian Rogers    ldr    r2, [sp, #8]                    @ copy arg value for r2
527655f29fabc0a12765de828914a18314382e5a35Ian Rogers    ldr    r3, [sp, #12]                   @ copy arg value for r3
537655f29fabc0a12765de828914a18314382e5a35Ian Rogers    mov    ip, #0                          @ set ip to 0
547655f29fabc0a12765de828914a18314382e5a35Ian Rogers    str    ip, [sp]                        @ store NULL for method* at bottom of frame
557655f29fabc0a12765de828914a18314382e5a35Ian Rogers    add    sp, #16                         @ first 4 args are not passed on stack for portable
567655f29fabc0a12765de828914a18314382e5a35Ian Rogers    ldr    ip, [r0, #METHOD_CODE_OFFSET]   @ get pointer to the code
577655f29fabc0a12765de828914a18314382e5a35Ian Rogers    blx    ip                              @ call the method
587655f29fabc0a12765de828914a18314382e5a35Ian Rogers    mov    sp, r11                         @ restore the stack pointer
597655f29fabc0a12765de828914a18314382e5a35Ian Rogers    ldr    ip, [sp, #24]                   @ load the result pointer
607655f29fabc0a12765de828914a18314382e5a35Ian Rogers    strd   r0, [ip]                        @ store r0/r1 into result pointer
617655f29fabc0a12765de828914a18314382e5a35Ian Rogers    pop    {r0, r4, r5, r9, r11, lr}       @ restore spill regs
627655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_adjust_cfa_offset -24
637655f29fabc0a12765de828914a18314382e5a35Ian Rogers    bx     lr
647655f29fabc0a12765de828914a18314382e5a35Ian RogersEND art_portable_invoke_stub
657655f29fabc0a12765de828914a18314382e5a35Ian Rogers
667655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .extern artPortableProxyInvokeHandler
677655f29fabc0a12765de828914a18314382e5a35Ian RogersENTRY art_portable_proxy_invoke_handler
687655f29fabc0a12765de828914a18314382e5a35Ian Rogers    @ Fake callee save ref and args frame set up, note portable doesn't use callee save frames.
697655f29fabc0a12765de828914a18314382e5a35Ian Rogers    @ TODO: just save the registers that are needed in artPortableProxyInvokeHandler.
707655f29fabc0a12765de828914a18314382e5a35Ian Rogers    push {r1-r3, r5-r8, r10-r11, lr}  @ 10 words of callee saves
717655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .save {r1-r3, r5-r8, r10-r11, lr}
727655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_adjust_cfa_offset 40
737655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r1, 0
747655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r2, 4
757655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r3, 8
767655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r5, 12
777655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r6, 16
787655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r7, 20
797655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r8, 24
807655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r10, 28
817655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset r11, 32
827655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_rel_offset lr, 36
837655f29fabc0a12765de828914a18314382e5a35Ian Rogers    sub sp, #8                        @ 2 words of space, bottom word will hold Method*
847655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .pad #8
857655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_adjust_cfa_offset 8
867655f29fabc0a12765de828914a18314382e5a35Ian Rogers    @ Begin argument set up.
877655f29fabc0a12765de828914a18314382e5a35Ian Rogers    str     r0, [sp, #0]           @ place proxy method at bottom of frame
887655f29fabc0a12765de828914a18314382e5a35Ian Rogers    mov     r2, r9                 @ pass Thread::Current
897655f29fabc0a12765de828914a18314382e5a35Ian Rogers    mov     r3, sp                 @ pass SP
907655f29fabc0a12765de828914a18314382e5a35Ian Rogers    blx     artPortableProxyInvokeHandler  @ (Method* proxy method, receiver, Thread*, SP)
917655f29fabc0a12765de828914a18314382e5a35Ian Rogers    ldr     r12, [r9, #THREAD_EXCEPTION_OFFSET]  @ load Thread::Current()->exception_
927655f29fabc0a12765de828914a18314382e5a35Ian Rogers    ldr     lr,  [sp, #44]         @ restore lr
937655f29fabc0a12765de828914a18314382e5a35Ian Rogers    add     sp,  #48               @ pop frame
947655f29fabc0a12765de828914a18314382e5a35Ian Rogers    .cfi_adjust_cfa_offset -48
957655f29fabc0a12765de828914a18314382e5a35Ian Rogers    bx      lr                     @ return
967655f29fabc0a12765de828914a18314382e5a35Ian RogersEND art_portable_proxy_invoke_handler
97848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers
9808bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .extern artPortableResolutionTrampoline
9908bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos SbirleaENTRY art_portable_resolution_trampoline
10008bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    @ Fake callee save ref and args frame set up, note portable doesn't use callee save frames.
10108bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    @ TODO: just save the registers that are needed in artPortableResolutionTrampoline.
10208bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    push {r1-r3, r5-r8, r10-r11, lr}  @ 10 words of callee saves
10308bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .save {r1-r3, r5-r8, r10-r11, lr}
10408bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_adjust_cfa_offset 40
10508bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r1, 0
10608bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r2, 4
10708bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r3, 8
10808bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r5, 12
10908bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r6, 16
11008bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r7, 20
11108bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r8, 24
11208bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r10, 28
11308bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r11, 32
11408bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset lr, 36
115bd136a29f08486525d6abc7d0a0006ce5b4011c1Dragos Sbirlea    sub sp, #8                     @ 2 words of space, bottom word will hold Method*
11608bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .pad #8
11708bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_adjust_cfa_offset 8
11808bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    mov     r2, r9                 @ pass Thread::Current
11908bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    mov     r3, sp                 @ pass SP
12008bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    blx     artPortableResolutionTrampoline  @ (Method* called, receiver, Thread*, SP)
12108bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    cmp     r0, #0                 @ is code pointer null?
12208bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    beq     1f                     @ goto exception
12308bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    mov     r12, r0
12408bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    ldr  r0, [sp, #0]              @ load resolved method in r0
12508bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    ldr  r1, [sp, #8]              @ restore non-callee save r1
12608bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    ldrd r2, [sp, #12]             @ restore non-callee saves r2-r3
12708bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    ldr  lr, [sp, #44]             @ restore lr
12808bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    add  sp, #48                   @ rewind sp
12908bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_adjust_cfa_offset -48
13008bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    bx      r12                    @ tail-call into actual code
13108bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea1:
13208bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    ldr  r1, [sp, #8]          @ restore non-callee save r1
13308bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    ldrd r2, [sp, #12]         @ restore non-callee saves r2-r3
13408bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    ldr  lr, [sp, #44]         @ restore lr
13508bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    add  sp, #48               @ rewind sp
13608bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_adjust_cfa_offset -48
13708bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    bx lr
13808bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos SbirleaEND art_portable_resolution_trampoline
13908bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea
14008bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .extern artPortableToInterpreterBridge
14108bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos SbirleaENTRY art_portable_to_interpreter_bridge
14208bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    @ Fake callee save ref and args frame set up, note portable doesn't use callee save frames.
14308bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    @ TODO: just save the registers that are needed in artPortableToInterpreterBridge.
14408bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    push {r1-r3, r5-r8, r10-r11, lr}  @ 10 words of callee saves
14508bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .save {r1-r3, r5-r8, r10-r11, lr}
14608bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_adjust_cfa_offset 40
14708bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r1, 0
14808bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r2, 4
14908bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r3, 8
15008bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r5, 12
15108bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r6, 16
15208bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r7, 20
15308bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r8, 24
15408bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r10, 28
15508bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset r11, 32
15608bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_rel_offset lr, 36
157bd136a29f08486525d6abc7d0a0006ce5b4011c1Dragos Sbirlea    sub sp, #8                     @ 2 words of space, bottom word will hold Method*
15808bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .pad #8
15908bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_adjust_cfa_offset 8
16008bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    mov     r1, r9                 @ pass Thread::Current
16108bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    mov     r2, sp                 @ pass SP
16208bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    blx     artPortableToInterpreterBridge    @ (Method* method, Thread*, SP)
16308bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    ldr     lr,  [sp, #44]         @ restore lr
16408bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    add     sp,  #48               @ pop frame
16508bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    .cfi_adjust_cfa_offset -48
16608bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos Sbirlea    bx      lr                     @ return
16708bf1967611965b65ffd5de1aa603b60e7b2d6a8Dragos SbirleaEND art_portable_to_interpreter_bridge
168