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