entry.S revision 5387824f19033ed51a945fbc8c2b574998404b3d
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