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 69dvmMterpStdRun: 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 120dvmMterpStdBail: 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 134dvmAsmInstructionJmpTable = .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