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