OSDN Git Service

Don't init class during reflection signature scan.
[android-x86/dalvik.git] / vm / arch / arm / CallOldABI.S
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*
18  * JNI method invocation.  This is used to call a C/C++ JNI method.  The
19  * argument list has to be pushed onto the native stack according to
20  * local calling conventions.
21  *
22  * This version supports the "old" ARM ABI.
23  */
24
25 #include <machine/cpu-features.h>
26
27 #ifndef __ARM_EABI__
28
29 /*
30 Function prototype:
31
32 void dvmPlatformInvoke(void* pEnv, ClassObject* clazz, int argInfo, int argc,
33     const u4* argv, const char* signature, void* func, JValue* pReturn) 
34
35 The method we are calling has the form:
36
37   return_type func(JNIEnv* pEnv, ClassObject* clazz, ...)
38     -or-
39   return_type func(JNIEnv* pEnv, Object* this, ...)
40
41 We receive a collection of 32-bit values which correspond to arguments from
42 the interpreter (e.g. float occupies one, double occupies two).  It's up to
43 us to convert these into local calling conventions.
44  */
45
46 /*
47 ARM ABI notes:
48
49 r0-r3 hold first 4 args to a method
50 r9 is given special treatment in some situations, but not for us
51 r10 (sl) seems to be generally available
52 r11 (fp) is used by gcc
53 r12 (ip) is scratch -- not preserved across method calls
54 r13 (sp) should be managed carefully in case a signal arrives
55 r14 (lr) must be preserved
56 r15 (pc) can be tinkered with directly
57
58 r0 holds returns <= 4 bytes
59 r0-r1 hold returns of 5-8 bytes, low word in r0
60
61 Stack is "full descending".  Only the arguments that don't fit in the first 4
62 registers are placed on the stack.  "sp" points at the first stacked argument
63 (i.e. the 5th arg).
64
65 VFP: single-precision results in s0, double-precision results in d0.
66
67 Happily we don't have to do anything special here -- the args from the
68 interpreter work directly as C/C++ args on ARM (with the "classic" ABI).
69 */
70
71     .text
72     .align  2
73     .global dvmPlatformInvoke
74     .type   dvmPlatformInvoke, %function
75
76 /*
77 On entry:
78   r0  JNIEnv
79   r1  clazz (NULL for virtual method calls, non-NULL for static)
80   r2  arg info (ignored)
81   r3  argc
82   [sp]     argv
83   [sp,#4]  signature (ignored)
84   [sp,#8]  func
85   [sp,#12] pReturn
86 */
87 dvmPlatformInvoke:
88     @ Standard gcc stack frame setup.  We don't need to push the original
89     @ sp or the current pc if "-fomit-frame-pointer" is in use for the
90     @ rest of the code.  If we don't plan to use a debugger we can speed
91     @ this up a little.
92     mov     ip, sp
93     stmfd   sp!, {r4, r5, r6, fp, ip, lr, pc}
94     sub     fp, ip, #4          @ set up fp, same way gdb does
95
96     @ We need to push a variable number of arguments onto the stack.
97     @ Rather than keep a count and pop them off after, we just hold on to
98     @ the stack pointers.
99     @
100     @ In theory we don't need to keep sp -- we can do an ldmdb instead of
101     @ an ldmia -- but we're doing the gcc frame trick where we push the
102     @ pc on with stmfd and don't pop it off.
103     mov     r4, ip
104     mov     r5, sp
105
106     @ argc is already in a scratch register (r3).  Put argv into one.  Note
107     @ argv can't go into r0-r3 because we need to use it to load those.
108     ldr     ip, [r4, #0]        @ ip <-- argv
109
110     @ Is this a static method?
111     cmp     r1, #0
112
113     @ No: set r1 to *argv++, and set argc--.
114     @ (r0=pEnv, r1=this)
115     ldreq   r1, [ip], #4
116     subeq   r3, r3, #1
117
118     @ While we still have the use of r2/r3, copy excess args from argv
119     @ to the stack.  We need to push the last item in argv first, and we
120     @ want the first two items in argv to end up in r2/r3.
121     subs    r3, r3, #2
122     ble     .Lno_copy
123
124     @ If there are N args, we want to skip 0 and 1, and push (N-1)..2.  We
125     @ have N-2 in r3.  If we set argv=argv+1, we can count from N-2 to 1
126     @ inclusive and get the right set of args.
127     add     r6, ip, #4
128
129 .Lcopy:
130     @ *--sp = argv[count]
131     ldr     r2, [r6, r3, lsl #2]
132     str     r2, [sp, #-4]!
133     subs    r3, r3, #1
134     bne     .Lcopy
135
136 .Lno_copy:
137     @ Load the last two args.  These are coming out of the interpreted stack,
138     @ and the VM preserves an overflow region at the bottom, so it should be
139     @ safe to load two items out of argv even if we're at the end.
140     ldr     r2, [ip]
141     ldr     r3, [ip, #4]
142
143     @ Show time.  Tuck the pc into lr and load the pc from the method
144     @ address supplied by the caller.  The value for "pc" is offset by 8
145     @ due to instruction prefetching.
146     @
147 #ifdef __ARM_HAVE_PC_INTERWORK
148     mov     lr, pc
149     ldr     pc, [r4, #8]
150 #else
151     ldr     ip, [r4, #8]
152     blx     ip
153 #endif
154
155     @ We're back, result is in r0 or (for long/double) r0-r1.
156     @
157     @ In theory, we need to use the "return type" arg to figure out what
158     @ we have and how to return it.  However, unless we have an FPU,
159     @ all we need to do is copy r0-r1 into the JValue union.
160     ldr     ip, [r4, #12]
161     stmia   ip, {r0-r1}
162
163 #ifdef __ARM_HAVE_PC_INTERWORK
164     @ Restore the registers we saved and return.  Note this remaps stuff,
165     @ so that "sp" comes from "ip", "pc" comes from "lr", and the "pc"
166     @ we pushed on evaporates when we restore "sp".
167     ldmfd   r5, {r4, r5, r6, fp, sp, pc}
168 #else
169     ldmfd   r5, {r4, r5, r6, fp, sp, lr}
170     bx      lr
171 #endif
172
173 #endif /*__ARM_EABI__*/