blob: 5715b9b7acac3c100f5d8e425edf9e44e17e9b72 [file] [log] [blame]
Ben Chengba4fc8b2009-06-01 13:00:29 -07001/*
2 * This file was generated automatically by gen-template.py for 'armv5te'.
3 *
4 * --> DO NOT EDIT <--
5 */
6
7/* File: armv5te/header.S */
8/*
9 * Copyright (C) 2008 The Android Open Source Project
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24#if defined(WITH_JIT)
25
26/*
27 * ARMv5 definitions and declarations.
28 */
29
30/*
31ARM EABI general notes:
32
33r0-r3 hold first 4 args to a method; they are not preserved across method calls
34r4-r8 are available for general use
35r9 is given special treatment in some situations, but not for us
36r10 (sl) seems to be generally available
37r11 (fp) is used by gcc (unless -fomit-frame-pointer is set)
38r12 (ip) is scratch -- not preserved across method calls
39r13 (sp) should be managed carefully in case a signal arrives
40r14 (lr) must be preserved
41r15 (pc) can be tinkered with directly
42
43r0 holds returns of <= 4 bytes
44r0-r1 hold returns of 8 bytes, low word in r0
45
46Callee must save/restore r4+ (except r12) if it modifies them.
47
48Stack is "full descending". Only the arguments that don't fit in the first 4
49registers are placed on the stack. "sp" points at the first stacked argument
50(i.e. the 5th arg).
51
52VFP: single-precision results in s0, double-precision results in d0.
53
54In the EABI, "sp" must be 64-bit aligned on entry to a function, and any
5564-bit quantities (long long, double) must be 64-bit aligned.
56*/
57
58/*
59JIT and ARM notes:
60
61The following registers have fixed assignments:
62
63 reg nick purpose
64 r5 rFP interpreted frame pointer, used for accessing locals and args
65 r6 rGLUE MterpGlue pointer
66
67The following registers have fixed assignments in mterp but are scratch
68registers in compiled code
69
70 reg nick purpose
71 r4 rPC interpreted program counter, used for fetching instructions
Andy McFadden1da12162009-06-05 16:19:13 -070072 r7 rINST first 16-bit code unit of current instruction
73 r8 rIBASE interpreted instruction base pointer, used for computed goto
Ben Chengba4fc8b2009-06-01 13:00:29 -070074
75Macros are provided for common operations. Each macro MUST emit only
76one instruction to make instruction-counting easier. They MUST NOT alter
77unspecified registers or condition codes.
78*/
79
80/* single-purpose registers, given names for clarity */
81#define rPC r4
82#define rFP r5
83#define rGLUE r6
Andy McFadden1da12162009-06-05 16:19:13 -070084#define rINST r7
85#define rIBASE r8
Ben Chengba4fc8b2009-06-01 13:00:29 -070086
87/*
88 * Given a frame pointer, find the stack save area.
89 *
90 * In C this is "((StackSaveArea*)(_fp) -1)".
91 */
92#define SAVEAREA_FROM_FP(_reg, _fpreg) \
93 sub _reg, _fpreg, #sizeofStackSaveArea
94
Bill Buzbee9a8c75a2009-11-08 14:31:20 -080095#define EXPORT_PC() \
96 str rPC, [rFP, #(-sizeofStackSaveArea + offStackSaveArea_currentPc)]
97
Ben Chengba4fc8b2009-06-01 13:00:29 -070098/*
99 * This is a #include, not a %include, because we want the C pre-processor
100 * to expand the macros into assembler assignment statements.
101 */
102#include "../../../mterp/common/asm-constants.h"
103
104
105/* File: armv5te/platform.S */
106/*
107 * ===========================================================================
Bill Buzbee342806d2009-12-08 12:37:13 -0800108 * CPU-version-specific defines and utility
Ben Chengba4fc8b2009-06-01 13:00:29 -0700109 * ===========================================================================
110 */
111
112/*
113 * Macro for "MOV LR,PC / LDR PC,xxx", which is not allowed pre-ARMv5.
114 * Jump to subroutine.
115 *
116 * May modify IP and LR.
117 */
118.macro LDR_PC_LR source
119 mov lr, pc
120 ldr pc, \source
121.endm
122
123
124 .global dvmCompilerTemplateStart
125 .type dvmCompilerTemplateStart, %function
126 .text
127
128dvmCompilerTemplateStart:
129
130/* ------------------------------ */
131 .balign 4
132 .global dvmCompiler_TEMPLATE_CMP_LONG
133dvmCompiler_TEMPLATE_CMP_LONG:
134/* File: armv5te/TEMPLATE_CMP_LONG.S */
135 /*
136 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination
137 * register based on the results of the comparison.
138 *
139 * We load the full values with LDM, but in practice many values could
140 * be resolved by only looking at the high word. This could be made
141 * faster or slower by splitting the LDM into a pair of LDRs.
142 *
143 * If we just wanted to set condition flags, we could do this:
144 * subs ip, r0, r2
145 * sbcs ip, r1, r3
146 * subeqs ip, r0, r2
147 * Leaving { <0, 0, >0 } in ip. However, we have to set it to a specific
148 * integer value, which we can do with 2 conditional mov/mvn instructions
149 * (set 1, set -1; if they're equal we already have 0 in ip), giving
150 * us a constant 5-cycle path plus a branch at the end to the
151 * instruction epilogue code. The multi-compare approach below needs
152 * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch
153 * in the worst case (the 64-bit values are equal).
154 */
155 /* cmp-long vAA, vBB, vCC */
156 cmp r1, r3 @ compare (vBB+1, vCC+1)
157 blt .LTEMPLATE_CMP_LONG_less @ signed compare on high part
158 bgt .LTEMPLATE_CMP_LONG_greater
159 subs r0, r0, r2 @ r0<- r0 - r2
160 bxeq lr
161 bhi .LTEMPLATE_CMP_LONG_greater @ unsigned compare on low part
162.LTEMPLATE_CMP_LONG_less:
163 mvn r0, #0 @ r0<- -1
164 bx lr
165.LTEMPLATE_CMP_LONG_greater:
166 mov r0, #1 @ r0<- 1
167 bx lr
168
169
170/* ------------------------------ */
171 .balign 4
172 .global dvmCompiler_TEMPLATE_RETURN
173dvmCompiler_TEMPLATE_RETURN:
174/* File: armv5te/TEMPLATE_RETURN.S */
175 /*
176 * Unwind a frame from the Dalvik stack for compiled OP_RETURN_XXX.
177 * If the stored value in returnAddr
178 * is non-zero, the caller is compiled by the JIT thus return to the
179 * address in the code cache following the invoke instruction. Otherwise
180 * return to the special dvmJitToInterpNoChain entry point.
181 */
182 SAVEAREA_FROM_FP(r0, rFP) @ r0<- saveArea (old)
183 ldr r10, [r0, #offStackSaveArea_prevFrame] @ r10<- saveArea->prevFrame
184 ldr r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
185 ldr rPC, [r0, #offStackSaveArea_savedPc] @ rPC<- saveArea->savedPc
Jeff Hao97319a82009-08-12 16:57:15 -0700186#if !defined(WITH_SELF_VERIFICATION)
Ben Chengba4fc8b2009-06-01 13:00:29 -0700187 ldr r9, [r0, #offStackSaveArea_returnAddr] @ r9<- chaining cell ret
Jeff Hao97319a82009-08-12 16:57:15 -0700188#else
189 mov r9, #0 @ disable chaining
190#endif
Ben Chengba4fc8b2009-06-01 13:00:29 -0700191 ldr r2, [r10, #(offStackSaveArea_method - sizeofStackSaveArea)]
192 @ r2<- method we're returning to
193 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self
194 cmp r2, #0 @ break frame?
Jeff Hao97319a82009-08-12 16:57:15 -0700195#if !defined(WITH_SELF_VERIFICATION)
Ben Chengba4fc8b2009-06-01 13:00:29 -0700196 beq 1f @ bail to interpreter
Jeff Hao97319a82009-08-12 16:57:15 -0700197#else
198 blxeq lr @ punt to interpreter and compare state
199#endif
Ben Cheng6c10a972009-10-29 14:39:18 -0700200 ldr r1, .LdvmJitToInterpNoChain @ defined in footer.S
Ben Chengba4fc8b2009-06-01 13:00:29 -0700201 mov rFP, r10 @ publish new FP
202 ldrne r10, [r2, #offMethod_clazz] @ r10<- method->clazz
203 ldr r8, [r8] @ r8<- suspendCount
204
205 str r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method
Ben Cheng6c10a972009-10-29 14:39:18 -0700206 ldr r0, [r10, #offClassObject_pDvmDex] @ r0<- method->clazz->pDvmDex
Ben Chengba4fc8b2009-06-01 13:00:29 -0700207 str rFP, [r3, #offThread_curFrame] @ self->curFrame = fp
208 add rPC, rPC, #6 @ publish new rPC (advance 6 bytes)
Ben Cheng6c10a972009-10-29 14:39:18 -0700209 str r0, [rGLUE, #offGlue_methodClassDex]
Ben Chengba4fc8b2009-06-01 13:00:29 -0700210 cmp r8, #0 @ check the suspendCount
211 movne r9, #0 @ clear the chaining cell address
212 cmp r9, #0 @ chaining cell exists?
213 blxne r9 @ jump to the chaining cell
Ben Cheng6c10a972009-10-29 14:39:18 -0700214#if defined(EXIT_STATS)
215 mov r0, #kCallsiteInterpreted
216#endif
217 mov pc, r1 @ callsite is interpreted
Ben Chengba4fc8b2009-06-01 13:00:29 -07002181:
219 stmia rGLUE, {rPC, rFP} @ SAVE_PC_FP_TO_GLUE()
220 ldr r2, .LdvmMterpStdBail @ defined in footer.S
221 mov r1, #0 @ changeInterp = false
222 mov r0, rGLUE @ Expecting rGLUE in r0
223 blx r2 @ exit the interpreter
224
225/* ------------------------------ */
226 .balign 4
227 .global dvmCompiler_TEMPLATE_INVOKE_METHOD_NO_OPT
228dvmCompiler_TEMPLATE_INVOKE_METHOD_NO_OPT:
229/* File: armv5te/TEMPLATE_INVOKE_METHOD_NO_OPT.S */
230 /*
231 * For polymorphic callsites - setup the Dalvik frame and load Dalvik PC
232 * into rPC then jump to dvmJitToInterpNoChain to dispatch the
233 * runtime-resolved callee.
234 */
235 @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite
236 ldrh r7, [r0, #offMethod_registersSize] @ r7<- methodToCall->regsSize
237 ldrh r2, [r0, #offMethod_outsSize] @ r2<- methodToCall->outsSize
238 ldr r9, [rGLUE, #offGlue_interpStackEnd] @ r9<- interpStackEnd
239 ldr r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
240 add r3, r1, #1 @ Thumb addr is odd
241 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area
242 sub r1, r1, r7, lsl #2 @ r1<- newFp (old savearea - regsSize)
243 SAVEAREA_FROM_FP(r10, r1) @ r10<- stack save area
244 sub r10, r10, r2, lsl #2 @ r10<- bottom (newsave - outsSize)
245 ldr r8, [r8] @ r3<- suspendCount (int)
246 cmp r10, r9 @ bottom < interpStackEnd?
247 bxlt lr @ return to raise stack overflow excep.
248 @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite
249 ldr r9, [r0, #offMethod_clazz] @ r9<- method->clazz
250 ldr r10, [r0, #offMethod_accessFlags] @ r10<- methodToCall->accessFlags
251 str rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)]
252 str rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)]
253 ldr rPC, [r0, #offMethod_insns] @ rPC<- methodToCall->insns
254
255
256 @ set up newSaveArea
257 str rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)]
258 str r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)]
259 str r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)]
260 cmp r8, #0 @ suspendCount != 0
261 bxne lr @ bail to the interpreter
262 tst r10, #ACC_NATIVE
Jeff Hao97319a82009-08-12 16:57:15 -0700263#if !defined(WITH_SELF_VERIFICATION)
Ben Chengba4fc8b2009-06-01 13:00:29 -0700264 bne .LinvokeNative
Jeff Hao97319a82009-08-12 16:57:15 -0700265#else
266 bxne lr @ bail to the interpreter
267#endif
Ben Chengba4fc8b2009-06-01 13:00:29 -0700268
269 ldr r10, .LdvmJitToInterpNoChain
270 ldr r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
271 ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self
272
273 @ Update "glue" values for the new method
274 str r0, [rGLUE, #offGlue_method] @ glue->method = methodToCall
275 str r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ...
276 mov rFP, r1 @ fp = newFp
277 str rFP, [r2, #offThread_curFrame] @ self->curFrame = newFp
278
279 @ Start executing the callee
Ben Cheng6c10a972009-10-29 14:39:18 -0700280#if defined(EXIT_STATS)
281 mov r0, #kInlineCacheMiss
282#endif
Ben Chengba4fc8b2009-06-01 13:00:29 -0700283 mov pc, r10 @ dvmJitToInterpNoChain
284
285/* ------------------------------ */
286 .balign 4
287 .global dvmCompiler_TEMPLATE_INVOKE_METHOD_CHAIN
288dvmCompiler_TEMPLATE_INVOKE_METHOD_CHAIN:
289/* File: armv5te/TEMPLATE_INVOKE_METHOD_CHAIN.S */
290 /*
291 * For monomorphic callsite, setup the Dalvik frame and return to the
292 * Thumb code through the link register to transfer control to the callee
293 * method through a dedicated chaining cell.
294 */
295 @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite
Ben Cheng38329f52009-07-07 14:19:20 -0700296 @ methodToCall is guaranteed to be non-native
297.LinvokeChain:
Ben Chengba4fc8b2009-06-01 13:00:29 -0700298 ldrh r7, [r0, #offMethod_registersSize] @ r7<- methodToCall->regsSize
299 ldrh r2, [r0, #offMethod_outsSize] @ r2<- methodToCall->outsSize
300 ldr r9, [rGLUE, #offGlue_interpStackEnd] @ r9<- interpStackEnd
301 ldr r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
302 add r3, r1, #1 @ Thumb addr is odd
303 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area
304 sub r1, r1, r7, lsl #2 @ r1<- newFp (old savearea - regsSize)
305 SAVEAREA_FROM_FP(r10, r1) @ r10<- stack save area
306 add r12, lr, #2 @ setup the punt-to-interp address
307 sub r10, r10, r2, lsl #2 @ r10<- bottom (newsave - outsSize)
308 ldr r8, [r8] @ r3<- suspendCount (int)
309 cmp r10, r9 @ bottom < interpStackEnd?
310 bxlt r12 @ return to raise stack overflow excep.
311 @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite
312 ldr r9, [r0, #offMethod_clazz] @ r9<- method->clazz
Ben Chengba4fc8b2009-06-01 13:00:29 -0700313 str rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)]
314 str rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)]
315 ldr rPC, [r0, #offMethod_insns] @ rPC<- methodToCall->insns
316
317
318 @ set up newSaveArea
319 str rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)]
320 str r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)]
321 str r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)]
322 cmp r8, #0 @ suspendCount != 0
323 bxne r12 @ bail to the interpreter
Ben Chengba4fc8b2009-06-01 13:00:29 -0700324
325 ldr r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
326 ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self
327
328 @ Update "glue" values for the new method
329 str r0, [rGLUE, #offGlue_method] @ glue->method = methodToCall
330 str r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ...
331 mov rFP, r1 @ fp = newFp
332 str rFP, [r2, #offThread_curFrame] @ self->curFrame = newFp
333
334 bx lr @ return to the callee-chaining cell
335
336
337
338/* ------------------------------ */
339 .balign 4
Ben Cheng38329f52009-07-07 14:19:20 -0700340 .global dvmCompiler_TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN
341dvmCompiler_TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN:
342/* File: armv5te/TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN.S */
343 /*
344 * For polymorphic callsite, check whether the cached class pointer matches
345 * the current one. If so setup the Dalvik frame and return to the
346 * Thumb code through the link register to transfer control to the callee
347 * method through a dedicated chaining cell.
348 *
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700349 * The predicted chaining cell is declared in ArmLIR.h with the
Ben Cheng38329f52009-07-07 14:19:20 -0700350 * following layout:
351 *
352 * typedef struct PredictedChainingCell {
353 * u4 branch;
354 * const ClassObject *clazz;
355 * const Method *method;
356 * u4 counter;
357 * } PredictedChainingCell;
358 *
359 * Upon returning to the callsite:
360 * - lr : to branch to the chaining cell
361 * - lr+2: to punt to the interpreter
362 * - lr+4: to fully resolve the callee and may rechain.
363 * r3 <- class
364 * r9 <- counter
365 */
366 @ r0 = this, r1 = returnCell, r2 = predictedChainCell, rPC = dalvikCallsite
367 ldr r3, [r0, #offObject_clazz] @ r3 <- this->class
368 ldr r8, [r2, #4] @ r8 <- predictedChainCell->clazz
369 ldr r0, [r2, #8] @ r0 <- predictedChainCell->method
370 ldr r9, [r2, #12] @ r9 <- predictedChainCell->counter
371 cmp r3, r8 @ predicted class == actual class?
372 beq .LinvokeChain @ predicted chain is valid
373 ldr r7, [r3, #offClassObject_vtable] @ r7 <- this->class->vtable
374 sub r1, r9, #1 @ count--
375 str r1, [r2, #12] @ write back to PredictedChainingCell->counter
376 add lr, lr, #4 @ return to fully-resolve landing pad
377 /*
378 * r1 <- count
379 * r2 <- &predictedChainCell
380 * r3 <- this->class
381 * r4 <- dPC
382 * r7 <- this->class->vtable
383 */
384 bx lr
385
386/* ------------------------------ */
387 .balign 4
388 .global dvmCompiler_TEMPLATE_INVOKE_METHOD_NATIVE
389dvmCompiler_TEMPLATE_INVOKE_METHOD_NATIVE:
390/* File: armv5te/TEMPLATE_INVOKE_METHOD_NATIVE.S */
391 @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite
392 ldrh r7, [r0, #offMethod_registersSize] @ r7<- methodToCall->regsSize
393 ldr r9, [rGLUE, #offGlue_interpStackEnd] @ r9<- interpStackEnd
394 ldr r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
395 add r3, r1, #1 @ Thumb addr is odd
396 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area
397 sub r1, r1, r7, lsl #2 @ r1<- newFp (old savearea - regsSize)
398 SAVEAREA_FROM_FP(r10, r1) @ r10<- stack save area
399 ldr r8, [r8] @ r3<- suspendCount (int)
400 cmp r10, r9 @ bottom < interpStackEnd?
401 bxlt lr @ return to raise stack overflow excep.
402 @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite
403 str rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)]
404 str rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)]
405 ldr rPC, [r0, #offMethod_insns] @ rPC<- methodToCall->insns
406
407
408 @ set up newSaveArea
409 str rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)]
410 str r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)]
411 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self
412 str r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)]
413 cmp r8, #0 @ suspendCount != 0
414 ldr r8, [r0, #offMethod_nativeFunc] @ r8<- method->nativeFunc
Jeff Hao97319a82009-08-12 16:57:15 -0700415#if !defined(WITH_SELF_VERIFICATION)
Ben Cheng38329f52009-07-07 14:19:20 -0700416 bxne lr @ bail to the interpreter
Jeff Hao97319a82009-08-12 16:57:15 -0700417#else
418 bx lr @ bail to interpreter unconditionally
419#endif
Ben Cheng38329f52009-07-07 14:19:20 -0700420
421 @ go ahead and transfer control to the native code
Andy McFaddend5ab7262009-08-25 07:19:34 -0700422 ldr r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->...
Ben Cheng38329f52009-07-07 14:19:20 -0700423 str r1, [r3, #offThread_curFrame] @ self->curFrame = newFp
Andy McFaddend5ab7262009-08-25 07:19:34 -0700424 str r9, [r1, #(offStackSaveArea_localRefCookie - sizeofStackSaveArea)]
425 @ newFp->localRefCookie=top
Ben Cheng38329f52009-07-07 14:19:20 -0700426 mov r9, r3 @ r9<- glue->self (preserve)
427 SAVEAREA_FROM_FP(r10, r1) @ r10<- new stack save area
428
429 mov r2, r0 @ r2<- methodToCall
430 mov r0, r1 @ r0<- newFP
431 add r1, rGLUE, #offGlue_retval @ r1<- &retval
432
433 blx r8 @ off to the native code
434
435 @ native return; r9=self, r10=newSaveArea
436 @ equivalent to dvmPopJniLocals
437 ldr r2, [r10, #offStackSaveArea_returnAddr] @ r2 = chaining cell ret
Andy McFaddend5ab7262009-08-25 07:19:34 -0700438 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved->top
Ben Cheng38329f52009-07-07 14:19:20 -0700439 ldr r1, [r9, #offThread_exception] @ check for exception
440 str rFP, [r9, #offThread_curFrame] @ self->curFrame = fp
441 cmp r1, #0 @ null?
Andy McFaddend5ab7262009-08-25 07:19:34 -0700442 str r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top
Bill Buzbee909b4182009-12-03 09:56:50 -0800443 ldr r0, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)]
Ben Cheng60c24f42010-01-04 12:29:56 -0800444
445 @ r0 = dalvikCallsitePC
446 bne .LhandleException @ no, handle exception
447
448 cmp r2, #0 @ return chaining cell still exists?
449 bxne r2 @ yes - go ahead
450
451 @ continue executing the next instruction through the interpreter
452 ldr r1, .LdvmJitToInterpNoChain @ defined in footer.S
453 add rPC, r0, #6 @ reconstruct new rPC (advance 6 bytes)
454 mov pc, r1
455
456
Ben Cheng38329f52009-07-07 14:19:20 -0700457
458
459/* ------------------------------ */
460 .balign 4
Ben Chengba4fc8b2009-06-01 13:00:29 -0700461 .global dvmCompiler_TEMPLATE_CMPG_DOUBLE
462dvmCompiler_TEMPLATE_CMPG_DOUBLE:
463/* File: armv5te/TEMPLATE_CMPG_DOUBLE.S */
464/* File: armv5te/TEMPLATE_CMPL_DOUBLE.S */
465 /*
Bill Buzbee1465db52009-09-23 17:17:35 -0700466 * For the JIT: incoming arguments in r0-r1, r2-r3
Ben Chengba4fc8b2009-06-01 13:00:29 -0700467 * result in r0
468 *
469 * Compare two floating-point values. Puts 0, 1, or -1 into the
470 * destination register based on the results of the comparison.
471 *
472 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
473 * on what value we'd like to return when one of the operands is NaN.
474 *
475 * See OP_CMPL_FLOAT for an explanation.
476 *
477 * For: cmpl-double, cmpg-double
478 */
479 /* op vAA, vBB, vCC */
Bill Buzbee1465db52009-09-23 17:17:35 -0700480 push {r0-r3} @ save operands
481 mov r11, lr @ save return address
Ben Chengba4fc8b2009-06-01 13:00:29 -0700482 LDR_PC_LR ".L__aeabi_cdcmple" @ PIC way of "bl __aeabi_cdcmple"
483 bhi .LTEMPLATE_CMPG_DOUBLE_gt_or_nan @ C set and Z clear, disambiguate
484 mvncc r0, #0 @ (less than) r1<- -1
485 moveq r0, #0 @ (equal) r1<- 0, trumps less than
Bill Buzbee1465db52009-09-23 17:17:35 -0700486 add sp, #16 @ drop unused operands
487 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700488
489 @ Test for NaN with a second comparison. EABI forbids testing bit
490 @ patterns, and we can't represent 0x7fc00000 in immediate form, so
491 @ make the library call.
492.LTEMPLATE_CMPG_DOUBLE_gt_or_nan:
Bill Buzbee1465db52009-09-23 17:17:35 -0700493 pop {r2-r3} @ restore operands in reverse order
494 pop {r0-r1} @ restore operands in reverse order
Ben Chengba4fc8b2009-06-01 13:00:29 -0700495 LDR_PC_LR ".L__aeabi_cdcmple" @ r0<- Z set if eq, C clear if <
496 movcc r0, #1 @ (greater than) r1<- 1
Bill Buzbee1465db52009-09-23 17:17:35 -0700497 bxcc r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700498 mov r0, #1 @ r1<- 1 or -1 for NaN
Bill Buzbee1465db52009-09-23 17:17:35 -0700499 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700500
501
502
503/* ------------------------------ */
504 .balign 4
505 .global dvmCompiler_TEMPLATE_CMPL_DOUBLE
506dvmCompiler_TEMPLATE_CMPL_DOUBLE:
507/* File: armv5te/TEMPLATE_CMPL_DOUBLE.S */
508 /*
Bill Buzbee1465db52009-09-23 17:17:35 -0700509 * For the JIT: incoming arguments in r0-r1, r2-r3
Ben Chengba4fc8b2009-06-01 13:00:29 -0700510 * result in r0
511 *
512 * Compare two floating-point values. Puts 0, 1, or -1 into the
513 * destination register based on the results of the comparison.
514 *
515 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
516 * on what value we'd like to return when one of the operands is NaN.
517 *
518 * See OP_CMPL_FLOAT for an explanation.
519 *
520 * For: cmpl-double, cmpg-double
521 */
522 /* op vAA, vBB, vCC */
Bill Buzbee1465db52009-09-23 17:17:35 -0700523 push {r0-r3} @ save operands
524 mov r11, lr @ save return address
Ben Chengba4fc8b2009-06-01 13:00:29 -0700525 LDR_PC_LR ".L__aeabi_cdcmple" @ PIC way of "bl __aeabi_cdcmple"
526 bhi .LTEMPLATE_CMPL_DOUBLE_gt_or_nan @ C set and Z clear, disambiguate
527 mvncc r0, #0 @ (less than) r1<- -1
528 moveq r0, #0 @ (equal) r1<- 0, trumps less than
Bill Buzbee1465db52009-09-23 17:17:35 -0700529 add sp, #16 @ drop unused operands
530 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700531
532 @ Test for NaN with a second comparison. EABI forbids testing bit
533 @ patterns, and we can't represent 0x7fc00000 in immediate form, so
534 @ make the library call.
535.LTEMPLATE_CMPL_DOUBLE_gt_or_nan:
Bill Buzbee1465db52009-09-23 17:17:35 -0700536 pop {r2-r3} @ restore operands in reverse order
537 pop {r0-r1} @ restore operands in reverse order
Ben Chengba4fc8b2009-06-01 13:00:29 -0700538 LDR_PC_LR ".L__aeabi_cdcmple" @ r0<- Z set if eq, C clear if <
539 movcc r0, #1 @ (greater than) r1<- 1
Bill Buzbee1465db52009-09-23 17:17:35 -0700540 bxcc r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700541 mvn r0, #0 @ r1<- 1 or -1 for NaN
Bill Buzbee1465db52009-09-23 17:17:35 -0700542 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700543
544
545/* ------------------------------ */
546 .balign 4
547 .global dvmCompiler_TEMPLATE_CMPG_FLOAT
548dvmCompiler_TEMPLATE_CMPG_FLOAT:
549/* File: armv5te/TEMPLATE_CMPG_FLOAT.S */
550/* File: armv5te/TEMPLATE_CMPL_FLOAT.S */
551 /*
Bill Buzbee1465db52009-09-23 17:17:35 -0700552 * For the JIT: incoming arguments in r0-r1, r2-r3
Ben Chengba4fc8b2009-06-01 13:00:29 -0700553 * result in r0
554 *
555 * Compare two floating-point values. Puts 0, 1, or -1 into the
556 * destination register based on the results of the comparison.
557 *
558 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
559 * on what value we'd like to return when one of the operands is NaN.
560 *
561 * The operation we're implementing is:
562 * if (x == y)
563 * return 0;
564 * else if (x < y)
565 * return -1;
566 * else if (x > y)
567 * return 1;
568 * else
569 * return {-1,1}; // one or both operands was NaN
570 *
571 * The straightforward implementation requires 3 calls to functions
572 * that return a result in r0. We can do it with two calls if our
573 * EABI library supports __aeabi_cfcmple (only one if we want to check
574 * for NaN directly):
575 * check x <= y
576 * if <, return -1
577 * if ==, return 0
578 * check y <= x
579 * if <, return 1
580 * return {-1,1}
581 *
582 * for: cmpl-float, cmpg-float
583 */
584 /* op vAA, vBB, vCC */
Ben Chengba4fc8b2009-06-01 13:00:29 -0700585 mov r9, r0 @ Save copies - we may need to redo
586 mov r10, r1
Bill Buzbee1465db52009-09-23 17:17:35 -0700587 mov r11, lr @ save return address
Ben Chengba4fc8b2009-06-01 13:00:29 -0700588 LDR_PC_LR ".L__aeabi_cfcmple" @ cmp <=: C clear if <, Z set if eq
589 bhi .LTEMPLATE_CMPG_FLOAT_gt_or_nan @ C set and Z clear, disambiguate
590 mvncc r0, #0 @ (less than) r0<- -1
591 moveq r0, #0 @ (equal) r0<- 0, trumps less than
Bill Buzbee1465db52009-09-23 17:17:35 -0700592 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700593 @ Test for NaN with a second comparison. EABI forbids testing bit
594 @ patterns, and we can't represent 0x7fc00000 in immediate form, so
595 @ make the library call.
596.LTEMPLATE_CMPG_FLOAT_gt_or_nan:
Bill Buzbee1465db52009-09-23 17:17:35 -0700597 mov r0, r10 @ restore in reverse order
598 mov r1, r9
Ben Chengba4fc8b2009-06-01 13:00:29 -0700599 LDR_PC_LR ".L__aeabi_cfcmple" @ r0<- Z set if eq, C clear if <
600 movcc r0, #1 @ (greater than) r1<- 1
Bill Buzbee1465db52009-09-23 17:17:35 -0700601 bxcc r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700602 mov r0, #1 @ r1<- 1 or -1 for NaN
Bill Buzbee1465db52009-09-23 17:17:35 -0700603 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700604
605
606
607
608/* ------------------------------ */
609 .balign 4
610 .global dvmCompiler_TEMPLATE_CMPL_FLOAT
611dvmCompiler_TEMPLATE_CMPL_FLOAT:
612/* File: armv5te/TEMPLATE_CMPL_FLOAT.S */
613 /*
Bill Buzbee1465db52009-09-23 17:17:35 -0700614 * For the JIT: incoming arguments in r0-r1, r2-r3
Ben Chengba4fc8b2009-06-01 13:00:29 -0700615 * result in r0
616 *
617 * Compare two floating-point values. Puts 0, 1, or -1 into the
618 * destination register based on the results of the comparison.
619 *
620 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
621 * on what value we'd like to return when one of the operands is NaN.
622 *
623 * The operation we're implementing is:
624 * if (x == y)
625 * return 0;
626 * else if (x < y)
627 * return -1;
628 * else if (x > y)
629 * return 1;
630 * else
631 * return {-1,1}; // one or both operands was NaN
632 *
633 * The straightforward implementation requires 3 calls to functions
634 * that return a result in r0. We can do it with two calls if our
635 * EABI library supports __aeabi_cfcmple (only one if we want to check
636 * for NaN directly):
637 * check x <= y
638 * if <, return -1
639 * if ==, return 0
640 * check y <= x
641 * if <, return 1
642 * return {-1,1}
643 *
644 * for: cmpl-float, cmpg-float
645 */
646 /* op vAA, vBB, vCC */
Ben Chengba4fc8b2009-06-01 13:00:29 -0700647 mov r9, r0 @ Save copies - we may need to redo
648 mov r10, r1
Bill Buzbee1465db52009-09-23 17:17:35 -0700649 mov r11, lr @ save return address
Ben Chengba4fc8b2009-06-01 13:00:29 -0700650 LDR_PC_LR ".L__aeabi_cfcmple" @ cmp <=: C clear if <, Z set if eq
651 bhi .LTEMPLATE_CMPL_FLOAT_gt_or_nan @ C set and Z clear, disambiguate
652 mvncc r0, #0 @ (less than) r0<- -1
653 moveq r0, #0 @ (equal) r0<- 0, trumps less than
Bill Buzbee1465db52009-09-23 17:17:35 -0700654 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700655 @ Test for NaN with a second comparison. EABI forbids testing bit
656 @ patterns, and we can't represent 0x7fc00000 in immediate form, so
657 @ make the library call.
658.LTEMPLATE_CMPL_FLOAT_gt_or_nan:
Bill Buzbee1465db52009-09-23 17:17:35 -0700659 mov r0, r10 @ restore in reverse order
660 mov r1, r9
Ben Chengba4fc8b2009-06-01 13:00:29 -0700661 LDR_PC_LR ".L__aeabi_cfcmple" @ r0<- Z set if eq, C clear if <
662 movcc r0, #1 @ (greater than) r1<- 1
Bill Buzbee1465db52009-09-23 17:17:35 -0700663 bxcc r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700664 mvn r0, #0 @ r1<- 1 or -1 for NaN
Bill Buzbee1465db52009-09-23 17:17:35 -0700665 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700666
667
668
669/* ------------------------------ */
670 .balign 4
671 .global dvmCompiler_TEMPLATE_MUL_LONG
672dvmCompiler_TEMPLATE_MUL_LONG:
673/* File: armv5te/TEMPLATE_MUL_LONG.S */
674 /*
675 * Signed 64-bit integer multiply.
676 *
677 * For JIT: op1 in r0/r1, op2 in r2/r3, return in r0/r1
678 *
679 * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
680 * WX
681 * x YZ
682 * --------
683 * ZW ZX
684 * YW YX
685 *
686 * The low word of the result holds ZX, the high word holds
687 * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because
688 * it doesn't fit in the low 64 bits.
689 *
690 * Unlike most ARM math operations, multiply instructions have
691 * restrictions on using the same register more than once (Rd and Rm
692 * cannot be the same).
693 */
694 /* mul-long vAA, vBB, vCC */
695 mul ip, r2, r1 @ ip<- ZxW
696 umull r9, r10, r2, r0 @ r9/r10 <- ZxX
697 mla r2, r0, r3, ip @ r2<- YxX + (ZxW)
698 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX))
699 mov r0,r9
700 mov r1,r10
701 bx lr
702
703/* ------------------------------ */
704 .balign 4
705 .global dvmCompiler_TEMPLATE_SHL_LONG
706dvmCompiler_TEMPLATE_SHL_LONG:
707/* File: armv5te/TEMPLATE_SHL_LONG.S */
708 /*
709 * Long integer shift. This is different from the generic 32/64-bit
710 * binary operations because vAA/vBB are 64-bit but vCC (the shift
711 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
712 * 6 bits.
713 */
714 /* shl-long vAA, vBB, vCC */
715 and r2, r2, #63 @ r2<- r2 & 0x3f
716 mov r1, r1, asl r2 @ r1<- r1 << r2
717 rsb r3, r2, #32 @ r3<- 32 - r2
718 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2))
719 subs ip, r2, #32 @ ip<- r2 - 32
720 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32)
721 mov r0, r0, asl r2 @ r0<- r0 << r2
722 bx lr
723
724/* ------------------------------ */
725 .balign 4
726 .global dvmCompiler_TEMPLATE_SHR_LONG
727dvmCompiler_TEMPLATE_SHR_LONG:
728/* File: armv5te/TEMPLATE_SHR_LONG.S */
729 /*
730 * Long integer shift. This is different from the generic 32/64-bit
731 * binary operations because vAA/vBB are 64-bit but vCC (the shift
732 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
733 * 6 bits.
734 */
735 /* shr-long vAA, vBB, vCC */
736 and r2, r2, #63 @ r0<- r0 & 0x3f
737 mov r0, r0, lsr r2 @ r0<- r2 >> r2
738 rsb r3, r2, #32 @ r3<- 32 - r2
739 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
740 subs ip, r2, #32 @ ip<- r2 - 32
741 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32)
742 mov r1, r1, asr r2 @ r1<- r1 >> r2
743 bx lr
744
745
746/* ------------------------------ */
747 .balign 4
748 .global dvmCompiler_TEMPLATE_USHR_LONG
749dvmCompiler_TEMPLATE_USHR_LONG:
750/* File: armv5te/TEMPLATE_USHR_LONG.S */
751 /*
752 * Long integer shift. This is different from the generic 32/64-bit
753 * binary operations because vAA/vBB are 64-bit but vCC (the shift
754 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
755 * 6 bits.
756 */
757 /* ushr-long vAA, vBB, vCC */
758 and r2, r2, #63 @ r0<- r0 & 0x3f
759 mov r0, r0, lsr r2 @ r0<- r2 >> r2
760 rsb r3, r2, #32 @ r3<- 32 - r2
761 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
762 subs ip, r2, #32 @ ip<- r2 - 32
763 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32)
764 mov r1, r1, lsr r2 @ r1<- r1 >>> r2
765 bx lr
766
767
Ben Cheng4f489172009-09-27 17:08:35 -0700768/* ------------------------------ */
769 .balign 4
770 .global dvmCompiler_TEMPLATE_THROW_EXCEPTION_COMMON
771dvmCompiler_TEMPLATE_THROW_EXCEPTION_COMMON:
772/* File: armv5te/TEMPLATE_THROW_EXCEPTION_COMMON.S */
773 /*
774 * Throw an exception from JIT'ed code.
775 * On entry:
776 * r0 Dalvik PC that raises the exception
777 */
778 b .LhandleException
779
Bill Buzbee1465db52009-09-23 17:17:35 -0700780/* ------------------------------ */
781 .balign 4
782 .global dvmCompiler_TEMPLATE_SAVE_STATE
783dvmCompiler_TEMPLATE_SAVE_STATE:
784/* File: armv5te/TEMPLATE_SAVE_STATE.S */
785 /*
786 * This handler performs a register save for selfVerification mode.
787 * On entry:
788 * Top of stack + 4: r7 value to save
789 * Top of stack + 0: r0 value to save
790 * r0 - offset from rGLUE to the beginning of the heapArgSpace record
791 * r7 - the value of regMap
792 *
793 * The handler must save regMap, r0-r12 and then return with r0-r12
794 * with their original values (note that this means r0 and r7 must take
795 * the values on the stack - not the ones in those registers on entry.
796 * Finally, the two registers previously pushed must be popped.
797 */
798 add r0, r0, rGLUE @ pointer to heapArgSpace
799 stmia r0!, {r7} @ save regMap
800 ldr r7, [r13, #0] @ recover r0 value
801 stmia r0!, {r7} @ save r0
802 ldr r7, [r13, #4] @ recover r7 value
803 stmia r0!, {r1-r12}
804 pop {r0, r7} @ recover r0, r7
805 bx lr
806
807/* ------------------------------ */
808 .balign 4
809 .global dvmCompiler_TEMPLATE_RESTORE_STATE
810dvmCompiler_TEMPLATE_RESTORE_STATE:
811/* File: armv5te/TEMPLATE_RESTORE_STATE.S */
812 /*
813 * This handler restores state following a selfVerification memory access.
814 * On entry:
815 * r0 - offset from rGLUE to the 1st element of the coreRegs save array.
816 */
817 add r0, r0, rGLUE @ pointer to heapArgSpace.coreRegs[0]
818 ldmia r0, {r0-r12}
819 bx lr
820
Bill Buzbeefd023aa2009-11-02 09:23:49 -0800821/* ------------------------------ */
822 .balign 4
823 .global dvmCompiler_TEMPLATE_STRING_COMPARETO
824dvmCompiler_TEMPLATE_STRING_COMPARETO:
825/* File: armv5te/TEMPLATE_STRING_COMPARETO.S */
826 /*
827 * String's compareTo.
828 *
829 * Requires r0/r1 to have been previously checked for null. Will
830 * return negative if this's string is < comp, 0 if they are the
831 * same and positive if >.
832 *
833 * IMPORTANT NOTE:
834 *
835 * This code relies on hard-coded offsets for string objects, and must be
836 * kept in sync with definitions in UtfString.h. See asm-constants.h
837 *
838 * On entry:
839 * r0: this object pointer
840 * r1: comp object pointer
841 *
842 */
843
844 mov r2, r0 @ this to r2, opening up r0 for return value
845 subs r0, r2, r1 @ Same?
846 bxeq lr
847
848 ldr r4, [r2, #STRING_FIELDOFF_OFFSET]
849 ldr r9, [r1, #STRING_FIELDOFF_OFFSET]
850 ldr r7, [r2, #STRING_FIELDOFF_COUNT]
851 ldr r10, [r1, #STRING_FIELDOFF_COUNT]
852 ldr r2, [r2, #STRING_FIELDOFF_VALUE]
853 ldr r1, [r1, #STRING_FIELDOFF_VALUE]
854
855 /*
856 * At this point, we have:
857 * value: r2/r1
858 * offset: r4/r9
859 * count: r7/r10
860 * We're going to compute
861 * r11 <- countDiff
862 * r10 <- minCount
863 */
864 subs r11, r7, r10
865 movls r10, r7
866
867 /* Now, build pointers to the string data */
868 add r2, r2, r4, lsl #1
869 add r1, r1, r9, lsl #1
870 /*
871 * Note: data pointers point to previous element so we can use pre-index
872 * mode with base writeback.
873 */
874 add r2, #16-2 @ offset to contents[-1]
875 add r1, #16-2 @ offset to contents[-1]
876
877 /*
878 * At this point we have:
879 * r2: *this string data
880 * r1: *comp string data
881 * r10: iteration count for comparison
882 * r11: value to return if the first part of the string is equal
883 * r0: reserved for result
884 * r3, r4, r7, r8, r9, r12 available for loading string data
885 */
886
Bill Buzbee4c0dedf2009-11-16 12:51:22 -0800887 subs r10, #2
888 blt do_remainder2
889
890 /*
891 * Unroll the first two checks so we can quickly catch early mismatch
892 * on long strings (but preserve incoming alignment)
893 */
894
895 ldrh r3, [r2, #2]!
896 ldrh r4, [r1, #2]!
897 ldrh r7, [r2, #2]!
898 ldrh r8, [r1, #2]!
899 subs r0, r3, r4
900 subeqs r0, r7, r8
901 bxne lr
902 cmp r10, #28
903 bgt do_memcmp16
904 subs r10, #3
Bill Buzbeefd023aa2009-11-02 09:23:49 -0800905 blt do_remainder
Bill Buzbee4c0dedf2009-11-16 12:51:22 -0800906
Bill Buzbeefd023aa2009-11-02 09:23:49 -0800907loopback_triple:
908 ldrh r3, [r2, #2]!
909 ldrh r4, [r1, #2]!
910 ldrh r7, [r2, #2]!
911 ldrh r8, [r1, #2]!
912 ldrh r9, [r2, #2]!
913 ldrh r12,[r1, #2]!
914 subs r0, r3, r4
915 subeqs r0, r7, r8
916 subeqs r0, r9, r12
917 bxne lr
918 subs r10, #3
Bill Buzbee5965d472009-11-15 13:37:18 -0800919 bge loopback_triple
Bill Buzbeefd023aa2009-11-02 09:23:49 -0800920
921do_remainder:
Bill Buzbee5965d472009-11-15 13:37:18 -0800922 adds r10, #3
Bill Buzbeefd023aa2009-11-02 09:23:49 -0800923 beq returnDiff
924
925loopback_single:
926 ldrh r3, [r2, #2]!
927 ldrh r4, [r1, #2]!
928 subs r0, r3, r4
929 bxne lr
930 subs r10, #1
931 bne loopback_single
932
933returnDiff:
934 mov r0, r11
935 bx lr
936
Bill Buzbee4c0dedf2009-11-16 12:51:22 -0800937do_remainder2:
938 adds r10, #2
939 bne loopback_single
940 mov r0, r11
941 bx lr
942
943 /* Long string case */
944do_memcmp16:
945 mov r4, lr
946 ldr lr, .Lmemcmp16
947 mov r7, r11
948 add r0, r2, #2
949 add r1, r1, #2
950 mov r2, r10
951 blx lr
952 cmp r0, #0
953 bxne r4
954 mov r0, r7
955 bx r4
956
957.Lmemcmp16:
958 .word __memcmp16
959
Bill Buzbeefd023aa2009-11-02 09:23:49 -0800960
961/* ------------------------------ */
962 .balign 4
963 .global dvmCompiler_TEMPLATE_STRING_INDEXOF
964dvmCompiler_TEMPLATE_STRING_INDEXOF:
965/* File: armv5te/TEMPLATE_STRING_INDEXOF.S */
966 /*
967 * String's indexOf.
968 *
969 * Requires r0 to have been previously checked for null. Will
970 * return index of match of r1 in r0.
971 *
972 * IMPORTANT NOTE:
973 *
974 * This code relies on hard-coded offsets for string objects, and must be
975 * kept in sync wth definitions in UtfString.h See asm-constants.h
976 *
977 * On entry:
978 * r0: string object pointer
979 * r1: char to match
980 * r2: Starting offset in string data
981 */
982
983 ldr r7, [r0, #STRING_FIELDOFF_OFFSET]
984 ldr r8, [r0, #STRING_FIELDOFF_COUNT]
985 ldr r0, [r0, #STRING_FIELDOFF_VALUE]
986
987 /*
988 * At this point, we have:
Bill Buzbee49024492009-11-03 16:52:53 -0800989 * r0: object pointer
990 * r1: char to match
991 * r2: starting offset
992 * r7: offset
993 * r8: string length
Bill Buzbeefd023aa2009-11-02 09:23:49 -0800994 */
995
Bill Buzbee49024492009-11-03 16:52:53 -0800996 /* Build pointer to start of string data */
997 add r0, #16
998 add r0, r0, r7, lsl #1
999
1000 /* Save a copy of starting data in r7 */
1001 mov r7, r0
1002
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001003 /* Clamp start to [0..count] */
1004 cmp r2, #0
1005 movlt r2, #0
1006 cmp r2, r8
Bill Buzbee49024492009-11-03 16:52:53 -08001007 movgt r2, r8
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001008
Bill Buzbee49024492009-11-03 16:52:53 -08001009 /* Build pointer to start of data to compare and pre-bias */
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001010 add r0, r0, r2, lsl #1
Bill Buzbee49024492009-11-03 16:52:53 -08001011 sub r0, #2
1012
1013 /* Compute iteration count */
1014 sub r8, r2
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001015
1016 /*
1017 * At this point we have:
Bill Buzbee49024492009-11-03 16:52:53 -08001018 * r0: start of data to test
1019 * r1: chat to compare
1020 * r8: iteration count
1021 * r7: original start of string
1022 * r3, r4, r9, r10, r11, r12 available for loading string data
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001023 */
1024
Bill Buzbeeab875c72009-11-19 11:37:21 -08001025 subs r8, #4
Bill Buzbee49024492009-11-03 16:52:53 -08001026 blt indexof_remainder
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001027
Bill Buzbee49024492009-11-03 16:52:53 -08001028indexof_loop4:
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001029 ldrh r3, [r0, #2]!
1030 ldrh r4, [r0, #2]!
Bill Buzbee49024492009-11-03 16:52:53 -08001031 ldrh r10, [r0, #2]!
1032 ldrh r11, [r0, #2]!
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001033 cmp r3, r1
1034 beq match_0
1035 cmp r4, r1
1036 beq match_1
Bill Buzbee49024492009-11-03 16:52:53 -08001037 cmp r10, r1
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001038 beq match_2
Bill Buzbee49024492009-11-03 16:52:53 -08001039 cmp r11, r1
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001040 beq match_3
1041 subs r8, #4
Bill Buzbee49024492009-11-03 16:52:53 -08001042 bge indexof_loop4
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001043
Bill Buzbee49024492009-11-03 16:52:53 -08001044indexof_remainder:
1045 adds r8, #4
1046 beq indexof_nomatch
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001047
Bill Buzbee49024492009-11-03 16:52:53 -08001048indexof_loop1:
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001049 ldrh r3, [r0, #2]!
1050 cmp r3, r1
1051 beq match_3
1052 subs r8, #1
Bill Buzbee49024492009-11-03 16:52:53 -08001053 bne indexof_loop1
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001054
Bill Buzbee49024492009-11-03 16:52:53 -08001055indexof_nomatch:
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001056 mov r0, #-1
1057 bx lr
1058
1059match_0:
1060 sub r0, #6
Bill Buzbee49024492009-11-03 16:52:53 -08001061 sub r0, r7
1062 asr r0, r0, #1
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001063 bx lr
1064match_1:
1065 sub r0, #4
Bill Buzbee49024492009-11-03 16:52:53 -08001066 sub r0, r7
1067 asr r0, r0, #1
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001068 bx lr
1069match_2:
1070 sub r0, #2
Bill Buzbee49024492009-11-03 16:52:53 -08001071 sub r0, r7
1072 asr r0, r0, #1
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001073 bx lr
1074match_3:
Bill Buzbee49024492009-11-03 16:52:53 -08001075 sub r0, r7
1076 asr r0, r0, #1
Bill Buzbeefd023aa2009-11-02 09:23:49 -08001077 bx lr
1078
1079
Bill Buzbee9a8c75a2009-11-08 14:31:20 -08001080/* ------------------------------ */
1081 .balign 4
1082 .global dvmCompiler_TEMPLATE_INTERPRET
1083dvmCompiler_TEMPLATE_INTERPRET:
1084/* File: armv5te/TEMPLATE_INTERPRET.S */
1085 /*
1086 * This handler transfers control to the interpeter without performing
1087 * any lookups. It may be called either as part of a normal chaining
1088 * operation, or from the transition code in header.S. We distinquish
1089 * the two cases by looking at the link register. If called from a
1090 * translation chain, it will point to the chaining Dalvik PC + 1.
1091 * On entry:
1092 * lr - if NULL:
1093 * r1 - the Dalvik PC to begin interpretation.
1094 * else
1095 * [lr, #-1] contains Dalvik PC to begin interpretation
1096 * rGLUE - pointer to interpState
1097 * rFP - Dalvik frame pointer
1098 */
1099 cmp lr, #0
1100 ldrne r1,[lr, #-1]
1101 ldr r2, .LinterpPunt
1102 mov r0, r1 @ set Dalvik PC
1103 bx r2
1104 @ doesn't return
1105
1106.LinterpPunt:
1107 .word dvmJitToInterpPunt
1108
Ben Chengba4fc8b2009-06-01 13:00:29 -07001109 .size dvmCompilerTemplateStart, .-dvmCompilerTemplateStart
1110/* File: armv5te/footer.S */
1111/*
1112 * ===========================================================================
1113 * Common subroutines and data
1114 * ===========================================================================
1115 */
1116
1117 .text
1118 .align 2
1119.LinvokeNative:
1120 @ Prep for the native call
1121 @ r1 = newFP, r0 = methodToCall
1122 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self
Andy McFaddend5ab7262009-08-25 07:19:34 -07001123 ldr r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->...
Ben Chengba4fc8b2009-06-01 13:00:29 -07001124 str r1, [r3, #offThread_curFrame] @ self->curFrame = newFp
Andy McFaddend5ab7262009-08-25 07:19:34 -07001125 str r9, [r1, #(offStackSaveArea_localRefCookie - sizeofStackSaveArea)]
1126 @ newFp->localRefCookie=top
Ben Chengba4fc8b2009-06-01 13:00:29 -07001127 mov r9, r3 @ r9<- glue->self (preserve)
1128 SAVEAREA_FROM_FP(r10, r1) @ r10<- new stack save area
1129
1130 mov r2, r0 @ r2<- methodToCall
1131 mov r0, r1 @ r0<- newFP
1132 add r1, rGLUE, #offGlue_retval @ r1<- &retval
1133
1134 LDR_PC_LR "[r2, #offMethod_nativeFunc]"
1135
1136 @ native return; r9=self, r10=newSaveArea
1137 @ equivalent to dvmPopJniLocals
1138 ldr r2, [r10, #offStackSaveArea_returnAddr] @ r2 = chaining cell ret
Andy McFaddend5ab7262009-08-25 07:19:34 -07001139 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved->top
Ben Chengba4fc8b2009-06-01 13:00:29 -07001140 ldr r1, [r9, #offThread_exception] @ check for exception
1141 str rFP, [r9, #offThread_curFrame] @ self->curFrame = fp
1142 cmp r1, #0 @ null?
Andy McFaddend5ab7262009-08-25 07:19:34 -07001143 str r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top
Ben Cheng4f489172009-09-27 17:08:35 -07001144 ldr r0, [r10, #offStackSaveArea_savedPc] @ reload rPC
Ben Cheng60c24f42010-01-04 12:29:56 -08001145
1146 @ r0 = dalvikCallsitePC
1147 bne .LhandleException @ no, handle exception
1148
1149 cmp r2, #0 @ return chaining cell still exists?
1150 bxne r2 @ yes - go ahead
1151
1152 @ continue executing the next instruction through the interpreter
1153 ldr r1, .LdvmJitToInterpNoChain @ defined in footer.S
1154 add rPC, r0, #6 @ reconstruct new rPC (advance 6 bytes)
1155 mov pc, r1
Ben Chengba4fc8b2009-06-01 13:00:29 -07001156
Ben Cheng4f489172009-09-27 17:08:35 -07001157/*
1158 * On entry:
1159 * r0 Faulting Dalvik PC
1160 */
Ben Chengba4fc8b2009-06-01 13:00:29 -07001161.LhandleException:
Ben Cheng4f489172009-09-27 17:08:35 -07001162 ldr r1, .LdvmMterpCommonExceptionThrown @ PIC way of getting &func
Ben Chengcc6600c2009-06-22 14:45:16 -07001163 ldr rIBASE, .LdvmAsmInstructionStart @ same as above
Ben Cheng4f489172009-09-27 17:08:35 -07001164 mov rPC, r0 @ reload the faulting Dalvik address
1165 mov pc, r1 @ branch to dvmMterpCommonExceptionThrown
Ben Chengba4fc8b2009-06-01 13:00:29 -07001166
1167 .align 2
1168.LdvmAsmInstructionStart:
1169 .word dvmAsmInstructionStart
1170.LdvmJitToInterpNoChain:
1171 .word dvmJitToInterpNoChain
1172.LdvmMterpStdBail:
1173 .word dvmMterpStdBail
Ben Chengcc6600c2009-06-22 14:45:16 -07001174.LdvmMterpCommonExceptionThrown:
1175 .word dvmMterpCommonExceptionThrown
Ben Chengba4fc8b2009-06-01 13:00:29 -07001176.L__aeabi_cdcmple:
1177 .word __aeabi_cdcmple
1178.L__aeabi_cfcmple:
1179 .word __aeabi_cfcmple
1180
1181 .global dmvCompilerTemplateEnd
1182dmvCompilerTemplateEnd:
1183
1184#endif /* WITH_JIT */
1185