Home | History | Annotate | Download | only in x86-atom
      1    /* Copyright (C) 2008 The Android Open Source Project
      2     *
      3     * Licensed under the Apache License, Version 2.0 (the "License");
      4     * you may not use this file except in compliance with the License.
      5     * You may obtain a copy of the License at
      6     *
      7     * http://www.apache.org/licenses/LICENSE-2.0
      8     *
      9     * Unless required by applicable law or agreed to in writing, software
     10     * distributed under the License is distributed on an "AS IS" BASIS,
     11     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12     * See the License for the specific language governing permissions and
     13     * limitations under the License.
     14     */
     15 
     16    /*
     17     * File: entry.S
     18     */
     19 
     20 #define ASSIST_DEBUGGER 1
     21     .text
     22     .align      2
     23     .global     dvmMterpStdRun
     24     .type       dvmMterpStdRun, %function
     25 
     26    /*
     27     * Save registers, initialize sp and fp.
     28     * On entry:
     29     *     bool MterpGlue(glue *)
     30     */
     31 
     32     .macro      MTERP_ENTRY
     33     movl        4(%esp), %ecx           # get first argument
     34     movl        %ebp, -4(%esp)          # save caller base pointer
     35     movl        %ebx, -8(%esp)          # save %ebx
     36     movl        %esi, -12(%esp)         # save %esi
     37     movl        %edi, -16(%esp)         # save %edi
     38     lea         -40(%esp), %ebp         # set callee base pointer
     39     lea         -40(%esp), %esp         # set callee stack pointer
     40     .endm
     41 
     42    /*
     43     * Restore registers.
     44     * This function returns a boolean "changeInterp" value.
     45     * The return value is from dvmMterpStdBail().
     46     */
     47 
     48     .macro      MTERP_EXIT
     49     lea         40(%esp), %esp          # correct stack pointer
     50     movl        -16(%esp), %edi         # restore %edi
     51     movl        -12(%esp), %esi         # restore %esi
     52     movl        -8(%esp), %ebx          # restore %ebx
     53     movl        -4(%esp), %ebp          # restore caller base pointer
     54     ret                                 # return
     55     .endm
     56 
     57    /*
     58     * DvmMterpStdRun entry point: save stack pointer, setup memory locations, get
     59     * entry point, start executing instructions.
     60     */
     61 
     62 dvmMterpStdRun:
     63     MTERP_ENTRY
     64     movl        %ecx, rGLUE             # save value for pMterpGlue
     65     movl        offGlue_pc(%ecx), rPC   # get program counter
     66     cmp         $$kInterpEntryInstr, offGlue_entryPoint(%ecx) # check instruction
     67     movl        offGlue_fp(%ecx), rFP   # get frame pointer
     68     movl        %esp, offGlue_bailPtr(%ecx) # save SP for eventual return
     69     FFETCH      %edx                    # %edx<- opcode
     70     jne         .Lnot_instr             # no, handle it
     71     FGETOP_JMPa %edx                    # start executing the instruction at rPC
     72 
     73    /*
     74     * Not an instruction. Are we returning from a method?
     75     */
     76 
     77 .Lnot_instr:
     78     cmpl        $$kInterpEntryReturn, offGlue_entryPoint(%ecx)
     79     je          common_returnFromMethod
     80 
     81    /*
     82     * No, are we throwing an exception?
     83     */
     84 
     85 .Lnot_return:
     86     cmpl        $$kInterpEntryThrow, offGlue_entryPoint(%ecx)
     87     je          common_exceptionThrown
     88 
     89    /*
     90     * No, then we must abort.
     91     */
     92 
     93 .Lbad_arg:
     94     pushl       offGlue_entryPoint(%ecx)
     95     movl        $$.LstrBadEntryPoint, -4(%esp)
     96     lea         -4(%esp), %esp
     97     call        printf
     98     lea         8(%esp), %esp
     99     call        dvmAbort                # call (void)
    100 
    101    /*
    102     * Restore the stack pointer and PC from the save point established on entry and
    103     * return to whoever called dvmMterpStdRun.
    104     *
    105     * On entry:
    106     *  4(%esp) MterpGlue* glue
    107     *  8(%esp) bool changeInterp
    108     */
    109 
    110     .global     dvmMterpStdBail
    111     .type       dvmMterpStdBail, %function
    112 
    113 dvmMterpStdBail:
    114     movl        4(%esp), %ecx           # get first argument
    115     movl        8(%esp), %eax           # get second argument
    116     movl        offGlue_bailPtr(%ecx), %esp # sp <- saved SP
    117     MTERP_EXIT
    118 
    119    /*
    120     * String references.
    121     */
    122 
    123 .LstrBadEntryPoint:
    124     .asciz "Bad entry point %d\n"
    125 
    126 
    127 dvmAsmInstructionJmpTable = .LdvmAsmInstructionJmpTable
    128 .LdvmAsmInstructionJmpTable:
    129 .long .L_OP_NOP
    130 .long .L_OP_MOVE
    131 .long .L_OP_MOVE_FROM16
    132 .long .L_OP_MOVE_16
    133 .long .L_OP_MOVE_WIDE
    134 .long .L_OP_MOVE_WIDE_FROM16
    135 .long .L_OP_MOVE_WIDE_16
    136 .long .L_OP_MOVE_OBJECT
    137 .long .L_OP_MOVE_OBJECT_FROM16
    138 .long .L_OP_MOVE_OBJECT_16
    139 .long .L_OP_MOVE_RESULT
    140 .long .L_OP_MOVE_RESULT_WIDE
    141 .long .L_OP_MOVE_RESULT_OBJECT
    142 .long .L_OP_MOVE_EXCEPTION
    143 .long .L_OP_RETURN_VOID
    144 .long .L_OP_RETURN
    145 .long .L_OP_RETURN_WIDE
    146 .long .L_OP_RETURN_OBJECT
    147 .long .L_OP_CONST_4
    148 .long .L_OP_CONST_16
    149 .long .L_OP_CONST
    150 .long .L_OP_CONST_HIGH16
    151 .long .L_OP_CONST_WIDE_16
    152 .long .L_OP_CONST_WIDE_32
    153 .long .L_OP_CONST_WIDE
    154 .long .L_OP_CONST_WIDE_HIGH16
    155 .long .L_OP_CONST_STRING
    156 .long .L_OP_CONST_STRING_JUMBO
    157 .long .L_OP_CONST_CLASS
    158 .long .L_OP_MONITOR_ENTER
    159 .long .L_OP_MONITOR_EXIT
    160 .long .L_OP_CHECK_CAST
    161 .long .L_OP_INSTANCE_OF
    162 .long .L_OP_ARRAY_LENGTH
    163 .long .L_OP_NEW_INSTANCE
    164 .long .L_OP_NEW_ARRAY
    165 .long .L_OP_FILLED_NEW_ARRAY
    166 .long .L_OP_FILLED_NEW_ARRAY_RANGE
    167 .long .L_OP_FILL_ARRAY_DATA
    168 .long .L_OP_THROW
    169 .long .L_OP_GOTO
    170 .long .L_OP_GOTO_16
    171 .long .L_OP_GOTO_32
    172 .long .L_OP_PACKED_SWITCH
    173 .long .L_OP_SPARSE_SWITCH
    174 .long .L_OP_CMPL_FLOAT
    175 .long .L_OP_CMPG_FLOAT
    176 .long .L_OP_CMPL_DOUBLE
    177 .long .L_OP_CMPG_DOUBLE
    178 .long .L_OP_CMP_LONG
    179 .long .L_OP_IF_EQ
    180 .long .L_OP_IF_NE
    181 .long .L_OP_IF_LT
    182 .long .L_OP_IF_GE
    183 .long .L_OP_IF_GT
    184 .long .L_OP_IF_LE
    185 .long .L_OP_IF_EQZ
    186 .long .L_OP_IF_NEZ
    187 .long .L_OP_IF_LTZ
    188 .long .L_OP_IF_GEZ
    189 .long .L_OP_IF_GTZ
    190 .long .L_OP_IF_LEZ
    191 .long .L_OP_UNUSED_3E
    192 .long .L_OP_UNUSED_3F
    193 .long .L_OP_UNUSED_40
    194 .long .L_OP_UNUSED_41
    195 .long .L_OP_UNUSED_42
    196 .long .L_OP_UNUSED_43
    197 .long .L_OP_AGET
    198 .long .L_OP_AGET_WIDE
    199 .long .L_OP_AGET_OBJECT
    200 .long .L_OP_AGET_BOOLEAN
    201 .long .L_OP_AGET_BYTE
    202 .long .L_OP_AGET_CHAR
    203 .long .L_OP_AGET_SHORT
    204 .long .L_OP_APUT
    205 .long .L_OP_APUT_WIDE
    206 .long .L_OP_APUT_OBJECT
    207 .long .L_OP_APUT_BOOLEAN
    208 .long .L_OP_APUT_BYTE
    209 .long .L_OP_APUT_CHAR
    210 .long .L_OP_APUT_SHORT
    211 .long .L_OP_IGET
    212 .long .L_OP_IGET_WIDE
    213 .long .L_OP_IGET_OBJECT
    214 .long .L_OP_IGET_BOOLEAN
    215 .long .L_OP_IGET_BYTE
    216 .long .L_OP_IGET_CHAR
    217 .long .L_OP_IGET_SHORT
    218 .long .L_OP_IPUT
    219 .long .L_OP_IPUT_WIDE
    220 .long .L_OP_IPUT_OBJECT
    221 .long .L_OP_IPUT_BOOLEAN
    222 .long .L_OP_IPUT_BYTE
    223 .long .L_OP_IPUT_CHAR
    224 .long .L_OP_IPUT_SHORT
    225 .long .L_OP_SGET
    226 .long .L_OP_SGET_WIDE
    227 .long .L_OP_SGET_OBJECT
    228 .long .L_OP_SGET_BOOLEAN
    229 .long .L_OP_SGET_BYTE
    230 .long .L_OP_SGET_CHAR
    231 .long .L_OP_SGET_SHORT
    232 .long .L_OP_SPUT
    233 .long .L_OP_SPUT_WIDE
    234 .long .L_OP_SPUT_OBJECT
    235 .long .L_OP_SPUT_BOOLEAN
    236 .long .L_OP_SPUT_BYTE
    237 .long .L_OP_SPUT_CHAR
    238 .long .L_OP_SPUT_SHORT
    239 .long .L_OP_INVOKE_VIRTUAL
    240 .long .L_OP_INVOKE_SUPER
    241 .long .L_OP_INVOKE_DIRECT
    242 .long .L_OP_INVOKE_STATIC
    243 .long .L_OP_INVOKE_INTERFACE
    244 .long .L_OP_UNUSED_73
    245 .long .L_OP_INVOKE_VIRTUAL_RANGE
    246 .long .L_OP_INVOKE_SUPER_RANGE
    247 .long .L_OP_INVOKE_DIRECT_RANGE
    248 .long .L_OP_INVOKE_STATIC_RANGE
    249 .long .L_OP_INVOKE_INTERFACE_RANGE
    250 .long .L_OP_UNUSED_79
    251 .long .L_OP_UNUSED_7A
    252 .long .L_OP_NEG_INT
    253 .long .L_OP_NOT_INT
    254 .long .L_OP_NEG_LONG
    255 .long .L_OP_NOT_LONG
    256 .long .L_OP_NEG_FLOAT
    257 .long .L_OP_NEG_DOUBLE
    258 .long .L_OP_INT_TO_LONG
    259 .long .L_OP_INT_TO_FLOAT
    260 .long .L_OP_INT_TO_DOUBLE
    261 .long .L_OP_LONG_TO_INT
    262 .long .L_OP_LONG_TO_FLOAT
    263 .long .L_OP_LONG_TO_DOUBLE
    264 .long .L_OP_FLOAT_TO_INT
    265 .long .L_OP_FLOAT_TO_LONG
    266 .long .L_OP_FLOAT_TO_DOUBLE
    267 .long .L_OP_DOUBLE_TO_INT
    268 .long .L_OP_DOUBLE_TO_LONG
    269 .long .L_OP_DOUBLE_TO_FLOAT
    270 .long .L_OP_INT_TO_BYTE
    271 .long .L_OP_INT_TO_CHAR
    272 .long .L_OP_INT_TO_SHORT
    273 .long .L_OP_ADD_INT
    274 .long .L_OP_SUB_INT
    275 .long .L_OP_MUL_INT
    276 .long .L_OP_DIV_INT
    277 .long .L_OP_REM_INT
    278 .long .L_OP_AND_INT
    279 .long .L_OP_OR_INT
    280 .long .L_OP_XOR_INT
    281 .long .L_OP_SHL_INT
    282 .long .L_OP_SHR_INT
    283 .long .L_OP_USHR_INT
    284 .long .L_OP_ADD_LONG
    285 .long .L_OP_SUB_LONG
    286 .long .L_OP_MUL_LONG
    287 .long .L_OP_DIV_LONG
    288 .long .L_OP_REM_LONG
    289 .long .L_OP_AND_LONG
    290 .long .L_OP_OR_LONG
    291 .long .L_OP_XOR_LONG
    292 .long .L_OP_SHL_LONG
    293 .long .L_OP_SHR_LONG
    294 .long .L_OP_USHR_LONG
    295 .long .L_OP_ADD_FLOAT
    296 .long .L_OP_SUB_FLOAT
    297 .long .L_OP_MUL_FLOAT
    298 .long .L_OP_DIV_FLOAT
    299 .long .L_OP_REM_FLOAT
    300 .long .L_OP_ADD_DOUBLE
    301 .long .L_OP_SUB_DOUBLE
    302 .long .L_OP_MUL_DOUBLE
    303 .long .L_OP_DIV_DOUBLE
    304 .long .L_OP_REM_DOUBLE
    305 .long .L_OP_ADD_INT_2ADDR
    306 .long .L_OP_SUB_INT_2ADDR
    307 .long .L_OP_MUL_INT_2ADDR
    308 .long .L_OP_DIV_INT_2ADDR
    309 .long .L_OP_REM_INT_2ADDR
    310 .long .L_OP_AND_INT_2ADDR
    311 .long .L_OP_OR_INT_2ADDR
    312 .long .L_OP_XOR_INT_2ADDR
    313 .long .L_OP_SHL_INT_2ADDR
    314 .long .L_OP_SHR_INT_2ADDR
    315 .long .L_OP_USHR_INT_2ADDR
    316 .long .L_OP_ADD_LONG_2ADDR
    317 .long .L_OP_SUB_LONG_2ADDR
    318 .long .L_OP_MUL_LONG_2ADDR
    319 .long .L_OP_DIV_LONG_2ADDR
    320 .long .L_OP_REM_LONG_2ADDR
    321 .long .L_OP_AND_LONG_2ADDR
    322 .long .L_OP_OR_LONG_2ADDR
    323 .long .L_OP_XOR_LONG_2ADDR
    324 .long .L_OP_SHL_LONG_2ADDR
    325 .long .L_OP_SHR_LONG_2ADDR
    326 .long .L_OP_USHR_LONG_2ADDR
    327 .long .L_OP_ADD_FLOAT_2ADDR
    328 .long .L_OP_SUB_FLOAT_2ADDR
    329 .long .L_OP_MUL_FLOAT_2ADDR
    330 .long .L_OP_DIV_FLOAT_2ADDR
    331 .long .L_OP_REM_FLOAT_2ADDR
    332 .long .L_OP_ADD_DOUBLE_2ADDR
    333 .long .L_OP_SUB_DOUBLE_2ADDR
    334 .long .L_OP_MUL_DOUBLE_2ADDR
    335 .long .L_OP_DIV_DOUBLE_2ADDR
    336 .long .L_OP_REM_DOUBLE_2ADDR
    337 .long .L_OP_ADD_INT_LIT16
    338 .long .L_OP_RSUB_INT
    339 .long .L_OP_MUL_INT_LIT16
    340 .long .L_OP_DIV_INT_LIT16
    341 .long .L_OP_REM_INT_LIT16
    342 .long .L_OP_AND_INT_LIT16
    343 .long .L_OP_OR_INT_LIT16
    344 .long .L_OP_XOR_INT_LIT16
    345 .long .L_OP_ADD_INT_LIT8
    346 .long .L_OP_RSUB_INT_LIT8
    347 .long .L_OP_MUL_INT_LIT8
    348 .long .L_OP_DIV_INT_LIT8
    349 .long .L_OP_REM_INT_LIT8
    350 .long .L_OP_AND_INT_LIT8
    351 .long .L_OP_OR_INT_LIT8
    352 .long .L_OP_XOR_INT_LIT8
    353 .long .L_OP_SHL_INT_LIT8
    354 .long .L_OP_SHR_INT_LIT8
    355 .long .L_OP_USHR_INT_LIT8
    356 .long .L_OP_IGET_VOLATILE
    357 .long .L_OP_IPUT_VOLATILE
    358 .long .L_OP_SGET_VOLATILE
    359 .long .L_OP_SPUT_VOLATILE
    360 .long .L_OP_IGET_OBJECT_VOLATILE
    361 .long .L_OP_IGET_WIDE_VOLATILE
    362 .long .L_OP_IPUT_WIDE_VOLATILE
    363 .long .L_OP_SGET_WIDE_VOLATILE
    364 .long .L_OP_SPUT_WIDE_VOLATILE
    365 .long .L_OP_BREAKPOINT
    366 .long .L_OP_THROW_VERIFICATION_ERROR
    367 .long .L_OP_EXECUTE_INLINE
    368 .long .L_OP_EXECUTE_INLINE_RANGE
    369 .long .L_OP_INVOKE_OBJECT_INIT_RANGE
    370 .long .L_OP_RETURN_VOID_BARRIER
    371 .long .L_OP_IGET_QUICK
    372 .long .L_OP_IGET_WIDE_QUICK
    373 .long .L_OP_IGET_OBJECT_QUICK
    374 .long .L_OP_IPUT_QUICK
    375 .long .L_OP_IPUT_WIDE_QUICK
    376 .long .L_OP_IPUT_OBJECT_QUICK
    377 .long .L_OP_INVOKE_VIRTUAL_QUICK
    378 .long .L_OP_INVOKE_VIRTUAL_QUICK_RANGE
    379 .long .L_OP_INVOKE_SUPER_QUICK
    380 .long .L_OP_INVOKE_SUPER_QUICK_RANGE
    381 .long .L_OP_IPUT_OBJECT_VOLATILE
    382 .long .L_OP_SGET_OBJECT_VOLATILE
    383 .long .L_OP_SPUT_OBJECT_VOLATILE
    384 .long .L_OP_DISPATCH_FF
    385