Home | History | Annotate | Download | only in arm
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "asm_support_arm.S"
     18 
     19     /*
     20      * Portable invocation stub.
     21      * On entry:
     22      *   r0 = method pointer
     23      *   r1 = argument array or NULL for no argument methods
     24      *   r2 = size of argument array in bytes
     25      *   r3 = (managed) thread pointer
     26      *   [sp] = JValue* result
     27      *   [sp + 4] = result type char
     28      */
     29 ENTRY art_portable_invoke_stub
     30     push   {r0, r4, r5, r9, r11, lr}       @ spill regs
     31     .save  {r0, r4, r5, r9, r11, lr}
     32     .cfi_adjust_cfa_offset 24
     33     .cfi_rel_offset r0, 0
     34     .cfi_rel_offset r4, 4
     35     .cfi_rel_offset r5, 8
     36     .cfi_rel_offset r9, 12
     37     .cfi_rel_offset r11, 16
     38     .cfi_rel_offset lr, 20
     39     mov    r11, sp                         @ save the stack pointer
     40     .cfi_def_cfa_register r11
     41     @.movsp r11
     42     mov    r9, r3                          @ move managed thread pointer into r9
     43     mov    r4, #SUSPEND_CHECK_INTERVAL     @ reset r4 to suspend check interval
     44     add    r5, r2, #16                     @ create space for method pointer in frame
     45     and    r5, #0xFFFFFFF0                 @ align frame size to 16 bytes
     46     sub    sp, r5                          @ reserve stack space for argument array
     47     add    r0, sp, #4                      @ pass stack pointer + method ptr as dest for memcpy
     48     bl     memcpy                          @ memcpy (dest, src, bytes)
     49     ldr    r0, [r11]                       @ restore method*
     50     ldr    r1, [sp, #4]                    @ copy arg value for r1
     51     ldr    r2, [sp, #8]                    @ copy arg value for r2
     52     ldr    r3, [sp, #12]                   @ copy arg value for r3
     53     mov    ip, #0                          @ set ip to 0
     54     str    ip, [sp]                        @ store NULL for method* at bottom of frame
     55     add    sp, #16                         @ first 4 args are not passed on stack for portable
     56     ldr    ip, [r0, #METHOD_PORTABLE_CODE_OFFSET_32]  @ get pointer to the code
     57     blx    ip                              @ call the method
     58     mov    sp, r11                         @ restore the stack pointer
     59     ldr    ip, [sp, #24]                   @ load the result pointer
     60     strd   r0, [ip]                        @ store r0/r1 into result pointer
     61     pop    {r0, r4, r5, r9, r11, lr}       @ restore spill regs
     62     .cfi_adjust_cfa_offset -24
     63     bx     lr
     64 END art_portable_invoke_stub
     65 
     66     .extern artPortableProxyInvokeHandler
     67 ENTRY art_portable_proxy_invoke_handler
     68     @ Fake callee save ref and args frame set up, note portable doesn't use callee save frames.
     69     @ TODO: just save the registers that are needed in artPortableProxyInvokeHandler.
     70     push {r1-r3, r5-r8, r10-r11, lr}  @ 10 words of callee saves
     71     .save {r1-r3, r5-r8, r10-r11, lr}
     72     .cfi_adjust_cfa_offset 40
     73     .cfi_rel_offset r1, 0
     74     .cfi_rel_offset r2, 4
     75     .cfi_rel_offset r3, 8
     76     .cfi_rel_offset r5, 12
     77     .cfi_rel_offset r6, 16
     78     .cfi_rel_offset r7, 20
     79     .cfi_rel_offset r8, 24
     80     .cfi_rel_offset r10, 28
     81     .cfi_rel_offset r11, 32
     82     .cfi_rel_offset lr, 36
     83     sub sp, #8                        @ 2 words of space, bottom word will hold Method*
     84     .pad #8
     85     .cfi_adjust_cfa_offset 8
     86     @ Begin argument set up.
     87     str     r0, [sp, #0]           @ place proxy method at bottom of frame
     88     mov     r2, r9                 @ pass Thread::Current
     89     mov     r3, sp                 @ pass SP
     90     blx     artPortableProxyInvokeHandler  @ (Method* proxy method, receiver, Thread*, SP)
     91     ldr     r12, [r9, #THREAD_EXCEPTION_OFFSET]  @ load Thread::Current()->exception_
     92     ldr     lr,  [sp, #44]         @ restore lr
     93     add     sp,  #48               @ pop frame
     94     .cfi_adjust_cfa_offset -48
     95     bx      lr                     @ return
     96 END art_portable_proxy_invoke_handler
     97 
     98     .extern artPortableResolutionTrampoline
     99 ENTRY art_portable_resolution_trampoline
    100     @ Fake callee save ref and args frame set up, note portable doesn't use callee save frames.
    101     @ TODO: just save the registers that are needed in artPortableResolutionTrampoline.
    102     push {r1-r3, r5-r8, r10-r11, lr}  @ 10 words of callee saves
    103     .save {r1-r3, r5-r8, r10-r11, lr}
    104     .cfi_adjust_cfa_offset 40
    105     .cfi_rel_offset r1, 0
    106     .cfi_rel_offset r2, 4
    107     .cfi_rel_offset r3, 8
    108     .cfi_rel_offset r5, 12
    109     .cfi_rel_offset r6, 16
    110     .cfi_rel_offset r7, 20
    111     .cfi_rel_offset r8, 24
    112     .cfi_rel_offset r10, 28
    113     .cfi_rel_offset r11, 32
    114     .cfi_rel_offset lr, 36
    115     sub sp, #8                     @ 2 words of space, bottom word will hold Method*
    116     .pad #8
    117     .cfi_adjust_cfa_offset 8
    118     mov     r2, r9                 @ pass Thread::Current
    119     mov     r3, sp                 @ pass SP
    120     blx     artPortableResolutionTrampoline  @ (Method* called, receiver, Thread*, SP)
    121     cmp     r0, #0                 @ is code pointer null?
    122     beq     1f                     @ goto exception
    123     mov     r12, r0
    124     ldr  r0, [sp, #0]              @ load resolved method in r0
    125     ldr  r1, [sp, #8]              @ restore non-callee save r1
    126     ldrd r2, [sp, #12]             @ restore non-callee saves r2-r3
    127     ldr  lr, [sp, #44]             @ restore lr
    128     add  sp, #48                   @ rewind sp
    129     .cfi_adjust_cfa_offset -48
    130     bx      r12                    @ tail-call into actual code
    131 1:
    132     ldr  r1, [sp, #8]          @ restore non-callee save r1
    133     ldrd r2, [sp, #12]         @ restore non-callee saves r2-r3
    134     ldr  lr, [sp, #44]         @ restore lr
    135     add  sp, #48               @ rewind sp
    136     .cfi_adjust_cfa_offset -48
    137     bx lr
    138 END art_portable_resolution_trampoline
    139 
    140     .extern artPortableToInterpreterBridge
    141 ENTRY_NO_HIDE art_portable_to_interpreter_bridge
    142     @ Fake callee save ref and args frame set up, note portable doesn't use callee save frames.
    143     @ TODO: just save the registers that are needed in artPortableToInterpreterBridge.
    144     push {r1-r3, r5-r8, r10-r11, lr}  @ 10 words of callee saves
    145     .save {r1-r3, r5-r8, r10-r11, lr}
    146     .cfi_adjust_cfa_offset 40
    147     .cfi_rel_offset r1, 0
    148     .cfi_rel_offset r2, 4
    149     .cfi_rel_offset r3, 8
    150     .cfi_rel_offset r5, 12
    151     .cfi_rel_offset r6, 16
    152     .cfi_rel_offset r7, 20
    153     .cfi_rel_offset r8, 24
    154     .cfi_rel_offset r10, 28
    155     .cfi_rel_offset r11, 32
    156     .cfi_rel_offset lr, 36
    157     sub sp, #8                     @ 2 words of space, bottom word will hold Method*
    158     .pad #8
    159     .cfi_adjust_cfa_offset 8
    160     mov     r1, r9                 @ pass Thread::Current
    161     mov     r2, sp                 @ pass SP
    162     blx     artPortableToInterpreterBridge    @ (Method* method, Thread*, SP)
    163     ldr     lr,  [sp, #44]         @ restore lr
    164     add     sp,  #48               @ pop frame
    165     .cfi_adjust_cfa_offset -48
    166     bx      lr                     @ return
    167 END art_portable_to_interpreter_bridge
    168