entry.S revision ab35b50311951feea3782151dd5422ee944685c2
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_UNUSED_FF
385