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 62dvmMterpStdRun: 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 113dvmMterpStdBail: 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 127dvmAsmInstructionJmpTable = .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