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