Home | History | Annotate | Download | only in armv5te
      1 /*
      2  * Copyright (C) 2008 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  * Interpreter entry point.
     18  */
     19 
     20 /*
     21  * We don't have formal stack frames, so gdb scans upward in the code
     22  * to find the start of the function (a label with the %function type),
     23  * and then looks at the next few instructions to figure out what
     24  * got pushed onto the stack.  From this it figures out how to restore
     25  * the registers, including PC, for the previous stack frame.  If gdb
     26  * sees a non-function label, it stops scanning, so either we need to
     27  * have nothing but assembler-local labels between the entry point and
     28  * the break, or we need to fake it out.
     29  *
     30  * When this is defined, we add some stuff to make gdb less confused.
     31  */
     32 #define ASSIST_DEBUGGER 1
     33 
     34     .text
     35     .align  2
     36     .global dvmMterpStdRun
     37     .type   dvmMterpStdRun, %function
     38 
     39 /*
     40  * On entry:
     41  *  r0  MterpGlue* glue
     42  *
     43  * This function returns a boolean "changeInterp" value.  The return comes
     44  * via a call to dvmMterpStdBail().
     45  */
     46 dvmMterpStdRun:
     47 #define MTERP_ENTRY1 \
     48     .save {r4-r10,fp,lr}; \
     49     stmfd   sp!, {r4-r10,fp,lr}         @ save 9 regs
     50 #define MTERP_ENTRY2 \
     51     .pad    #4; \
     52     sub     sp, sp, #4                  @ align 64
     53 
     54     .fnstart
     55     MTERP_ENTRY1
     56     MTERP_ENTRY2
     57 
     58     /* save stack pointer, add magic word for debuggerd */
     59     str     sp, [r0, #offGlue_bailPtr]  @ save SP for eventual return
     60 
     61     /* set up "named" registers, figure out entry point */
     62     mov     rGLUE, r0                   @ set rGLUE
     63     ldr     r1, [r0, #offGlue_entryPoint]   @ enum is 4 bytes in aapcs-EABI
     64     LOAD_PC_FP_FROM_GLUE()              @ load rPC and rFP from "glue"
     65     adr     rIBASE, dvmAsmInstructionStart  @ set rIBASE
     66     cmp     r1, #kInterpEntryInstr      @ usual case?
     67     bne     .Lnot_instr                 @ no, handle it
     68 
     69 #if defined(WITH_JIT)
     70 .LentryInstr:
     71     ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
     72     /* Entry is always a possible trace start */
     73     GET_JIT_PROF_TABLE(r0)
     74     FETCH_INST()
     75     mov    r1, #0                       @ prepare the value for the new state
     76     str    r1, [r10, #offThread_inJitCodeCache] @ back to the interp land
     77     cmp    r0,#0
     78     bne    common_updateProfile
     79     GET_INST_OPCODE(ip)
     80     GOTO_OPCODE(ip)
     81 #else
     82     /* start executing the instruction at rPC */
     83     FETCH_INST()                        @ load rINST from rPC
     84     GET_INST_OPCODE(ip)                 @ extract opcode from rINST
     85     GOTO_OPCODE(ip)                     @ jump to next instruction
     86 #endif
     87 
     88 .Lnot_instr:
     89     cmp     r1, #kInterpEntryReturn     @ were we returning from a method?
     90     beq     common_returnFromMethod
     91 
     92 .Lnot_return:
     93     cmp     r1, #kInterpEntryThrow      @ were we throwing an exception?
     94     beq     common_exceptionThrown
     95 
     96 #if defined(WITH_JIT)
     97 .Lnot_throw:
     98     ldr     r10,[rGLUE, #offGlue_jitResumeNPC]
     99     ldr     r2,[rGLUE, #offGlue_jitResumeDPC]
    100     cmp     r1, #kInterpEntryResume     @ resuming after Jit single-step?
    101     bne     .Lbad_arg
    102     cmp     rPC,r2
    103     bne     .LentryInstr                @ must have branched, don't resume
    104 #if defined(WITH_SELF_VERIFICATION)
    105     @ glue->entryPoint will be set in dvmSelfVerificationSaveState
    106     b       jitSVShadowRunStart         @ re-enter the translation after the
    107                                         @ single-stepped instruction
    108     @noreturn
    109 #endif
    110     mov     r1, #kInterpEntryInstr
    111     str     r1, [rGLUE, #offGlue_entryPoint]
    112     bx      r10                         @ re-enter the translation
    113 #endif
    114 
    115 .Lbad_arg:
    116     ldr     r0, strBadEntryPoint
    117     @ r1 holds value of entryPoint
    118     bl      printf
    119     bl      dvmAbort
    120     .fnend
    121 
    122 
    123     .global dvmMterpStdBail
    124     .type   dvmMterpStdBail, %function
    125 
    126 /*
    127  * Restore the stack pointer and PC from the save point established on entry.
    128  * This is essentially the same as a longjmp, but should be cheaper.  The
    129  * last instruction causes us to return to whoever called dvmMterpStdRun.
    130  *
    131  * We pushed some registers on the stack in dvmMterpStdRun, then saved
    132  * SP and LR.  Here we restore SP, restore the registers, and then restore
    133  * LR to PC.
    134  *
    135  * On entry:
    136  *  r0  MterpGlue* glue
    137  *  r1  bool changeInterp
    138  */
    139 dvmMterpStdBail:
    140     ldr     sp, [r0, #offGlue_bailPtr]      @ sp<- saved SP
    141     mov     r0, r1                          @ return the changeInterp value
    142     add     sp, sp, #4                      @ un-align 64
    143     LDMFD_PC "r4-r10,fp"                    @ restore 9 regs and return
    144 
    145 
    146 /*
    147  * String references.
    148  */
    149 strBadEntryPoint:
    150     .word   .LstrBadEntryPoint
    151 
    152