blob: 75388fb212f2d7916d79fd63cf8038fe3399f927 [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
95/*
96 * This is a #include, not a %include, because we want the C pre-processor
97 * to expand the macros into assembler assignment statements.
98 */
99#include "../../../mterp/common/asm-constants.h"
100
101
102/* File: armv5te/platform.S */
103/*
104 * ===========================================================================
105 * CPU-version-specific defines
106 * ===========================================================================
107 */
108
109/*
110 * Macro for "MOV LR,PC / LDR PC,xxx", which is not allowed pre-ARMv5.
111 * Jump to subroutine.
112 *
113 * May modify IP and LR.
114 */
115.macro LDR_PC_LR source
116 mov lr, pc
117 ldr pc, \source
118.endm
119
120
121 .global dvmCompilerTemplateStart
122 .type dvmCompilerTemplateStart, %function
123 .text
124
125dvmCompilerTemplateStart:
126
127/* ------------------------------ */
128 .balign 4
129 .global dvmCompiler_TEMPLATE_CMP_LONG
130dvmCompiler_TEMPLATE_CMP_LONG:
131/* File: armv5te/TEMPLATE_CMP_LONG.S */
132 /*
133 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination
134 * register based on the results of the comparison.
135 *
136 * We load the full values with LDM, but in practice many values could
137 * be resolved by only looking at the high word. This could be made
138 * faster or slower by splitting the LDM into a pair of LDRs.
139 *
140 * If we just wanted to set condition flags, we could do this:
141 * subs ip, r0, r2
142 * sbcs ip, r1, r3
143 * subeqs ip, r0, r2
144 * Leaving { <0, 0, >0 } in ip. However, we have to set it to a specific
145 * integer value, which we can do with 2 conditional mov/mvn instructions
146 * (set 1, set -1; if they're equal we already have 0 in ip), giving
147 * us a constant 5-cycle path plus a branch at the end to the
148 * instruction epilogue code. The multi-compare approach below needs
149 * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch
150 * in the worst case (the 64-bit values are equal).
151 */
152 /* cmp-long vAA, vBB, vCC */
153 cmp r1, r3 @ compare (vBB+1, vCC+1)
154 blt .LTEMPLATE_CMP_LONG_less @ signed compare on high part
155 bgt .LTEMPLATE_CMP_LONG_greater
156 subs r0, r0, r2 @ r0<- r0 - r2
157 bxeq lr
158 bhi .LTEMPLATE_CMP_LONG_greater @ unsigned compare on low part
159.LTEMPLATE_CMP_LONG_less:
160 mvn r0, #0 @ r0<- -1
161 bx lr
162.LTEMPLATE_CMP_LONG_greater:
163 mov r0, #1 @ r0<- 1
164 bx lr
165
166
167/* ------------------------------ */
168 .balign 4
169 .global dvmCompiler_TEMPLATE_RETURN
170dvmCompiler_TEMPLATE_RETURN:
171/* File: armv5te/TEMPLATE_RETURN.S */
172 /*
173 * Unwind a frame from the Dalvik stack for compiled OP_RETURN_XXX.
174 * If the stored value in returnAddr
175 * is non-zero, the caller is compiled by the JIT thus return to the
176 * address in the code cache following the invoke instruction. Otherwise
177 * return to the special dvmJitToInterpNoChain entry point.
178 */
179 SAVEAREA_FROM_FP(r0, rFP) @ r0<- saveArea (old)
180 ldr r10, [r0, #offStackSaveArea_prevFrame] @ r10<- saveArea->prevFrame
181 ldr r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
182 ldr rPC, [r0, #offStackSaveArea_savedPc] @ rPC<- saveArea->savedPc
Jeff Hao97319a82009-08-12 16:57:15 -0700183#if !defined(WITH_SELF_VERIFICATION)
Ben Chengba4fc8b2009-06-01 13:00:29 -0700184 ldr r9, [r0, #offStackSaveArea_returnAddr] @ r9<- chaining cell ret
Jeff Hao97319a82009-08-12 16:57:15 -0700185#else
186 mov r9, #0 @ disable chaining
187#endif
Ben Chengba4fc8b2009-06-01 13:00:29 -0700188 ldr r2, [r10, #(offStackSaveArea_method - sizeofStackSaveArea)]
189 @ r2<- method we're returning to
190 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self
191 cmp r2, #0 @ break frame?
Jeff Hao97319a82009-08-12 16:57:15 -0700192#if !defined(WITH_SELF_VERIFICATION)
Ben Chengba4fc8b2009-06-01 13:00:29 -0700193 beq 1f @ bail to interpreter
Jeff Hao97319a82009-08-12 16:57:15 -0700194#else
195 blxeq lr @ punt to interpreter and compare state
196#endif
Ben Cheng6c10a972009-10-29 14:39:18 -0700197 ldr r1, .LdvmJitToInterpNoChain @ defined in footer.S
Ben Chengba4fc8b2009-06-01 13:00:29 -0700198 mov rFP, r10 @ publish new FP
199 ldrne r10, [r2, #offMethod_clazz] @ r10<- method->clazz
200 ldr r8, [r8] @ r8<- suspendCount
201
202 str r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method
Ben Cheng6c10a972009-10-29 14:39:18 -0700203 ldr r0, [r10, #offClassObject_pDvmDex] @ r0<- method->clazz->pDvmDex
Ben Chengba4fc8b2009-06-01 13:00:29 -0700204 str rFP, [r3, #offThread_curFrame] @ self->curFrame = fp
205 add rPC, rPC, #6 @ publish new rPC (advance 6 bytes)
Ben Cheng6c10a972009-10-29 14:39:18 -0700206 str r0, [rGLUE, #offGlue_methodClassDex]
Ben Chengba4fc8b2009-06-01 13:00:29 -0700207 cmp r8, #0 @ check the suspendCount
208 movne r9, #0 @ clear the chaining cell address
209 cmp r9, #0 @ chaining cell exists?
210 blxne r9 @ jump to the chaining cell
Ben Cheng6c10a972009-10-29 14:39:18 -0700211#if defined(EXIT_STATS)
212 mov r0, #kCallsiteInterpreted
213#endif
214 mov pc, r1 @ callsite is interpreted
Ben Chengba4fc8b2009-06-01 13:00:29 -07002151:
216 stmia rGLUE, {rPC, rFP} @ SAVE_PC_FP_TO_GLUE()
217 ldr r2, .LdvmMterpStdBail @ defined in footer.S
218 mov r1, #0 @ changeInterp = false
219 mov r0, rGLUE @ Expecting rGLUE in r0
220 blx r2 @ exit the interpreter
221
222/* ------------------------------ */
223 .balign 4
224 .global dvmCompiler_TEMPLATE_INVOKE_METHOD_NO_OPT
225dvmCompiler_TEMPLATE_INVOKE_METHOD_NO_OPT:
226/* File: armv5te/TEMPLATE_INVOKE_METHOD_NO_OPT.S */
227 /*
228 * For polymorphic callsites - setup the Dalvik frame and load Dalvik PC
229 * into rPC then jump to dvmJitToInterpNoChain to dispatch the
230 * runtime-resolved callee.
231 */
232 @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite
233 ldrh r7, [r0, #offMethod_registersSize] @ r7<- methodToCall->regsSize
234 ldrh r2, [r0, #offMethod_outsSize] @ r2<- methodToCall->outsSize
235 ldr r9, [rGLUE, #offGlue_interpStackEnd] @ r9<- interpStackEnd
236 ldr r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
237 add r3, r1, #1 @ Thumb addr is odd
238 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area
239 sub r1, r1, r7, lsl #2 @ r1<- newFp (old savearea - regsSize)
240 SAVEAREA_FROM_FP(r10, r1) @ r10<- stack save area
241 sub r10, r10, r2, lsl #2 @ r10<- bottom (newsave - outsSize)
242 ldr r8, [r8] @ r3<- suspendCount (int)
243 cmp r10, r9 @ bottom < interpStackEnd?
244 bxlt lr @ return to raise stack overflow excep.
245 @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite
246 ldr r9, [r0, #offMethod_clazz] @ r9<- method->clazz
247 ldr r10, [r0, #offMethod_accessFlags] @ r10<- methodToCall->accessFlags
248 str rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)]
249 str rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)]
250 ldr rPC, [r0, #offMethod_insns] @ rPC<- methodToCall->insns
251
252
253 @ set up newSaveArea
254 str rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)]
255 str r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)]
256 str r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)]
257 cmp r8, #0 @ suspendCount != 0
258 bxne lr @ bail to the interpreter
259 tst r10, #ACC_NATIVE
Jeff Hao97319a82009-08-12 16:57:15 -0700260#if !defined(WITH_SELF_VERIFICATION)
Ben Chengba4fc8b2009-06-01 13:00:29 -0700261 bne .LinvokeNative
Jeff Hao97319a82009-08-12 16:57:15 -0700262#else
263 bxne lr @ bail to the interpreter
264#endif
Ben Chengba4fc8b2009-06-01 13:00:29 -0700265
266 ldr r10, .LdvmJitToInterpNoChain
267 ldr r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
268 ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self
269
270 @ Update "glue" values for the new method
271 str r0, [rGLUE, #offGlue_method] @ glue->method = methodToCall
272 str r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ...
273 mov rFP, r1 @ fp = newFp
274 str rFP, [r2, #offThread_curFrame] @ self->curFrame = newFp
275
276 @ Start executing the callee
Ben Cheng6c10a972009-10-29 14:39:18 -0700277#if defined(EXIT_STATS)
278 mov r0, #kInlineCacheMiss
279#endif
Ben Chengba4fc8b2009-06-01 13:00:29 -0700280 mov pc, r10 @ dvmJitToInterpNoChain
281
282/* ------------------------------ */
283 .balign 4
284 .global dvmCompiler_TEMPLATE_INVOKE_METHOD_CHAIN
285dvmCompiler_TEMPLATE_INVOKE_METHOD_CHAIN:
286/* File: armv5te/TEMPLATE_INVOKE_METHOD_CHAIN.S */
287 /*
288 * For monomorphic callsite, setup the Dalvik frame and return to the
289 * Thumb code through the link register to transfer control to the callee
290 * method through a dedicated chaining cell.
291 */
292 @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite
Ben Cheng38329f52009-07-07 14:19:20 -0700293 @ methodToCall is guaranteed to be non-native
294.LinvokeChain:
Ben Chengba4fc8b2009-06-01 13:00:29 -0700295 ldrh r7, [r0, #offMethod_registersSize] @ r7<- methodToCall->regsSize
296 ldrh r2, [r0, #offMethod_outsSize] @ r2<- methodToCall->outsSize
297 ldr r9, [rGLUE, #offGlue_interpStackEnd] @ r9<- interpStackEnd
298 ldr r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
299 add r3, r1, #1 @ Thumb addr is odd
300 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area
301 sub r1, r1, r7, lsl #2 @ r1<- newFp (old savearea - regsSize)
302 SAVEAREA_FROM_FP(r10, r1) @ r10<- stack save area
303 add r12, lr, #2 @ setup the punt-to-interp address
304 sub r10, r10, r2, lsl #2 @ r10<- bottom (newsave - outsSize)
305 ldr r8, [r8] @ r3<- suspendCount (int)
306 cmp r10, r9 @ bottom < interpStackEnd?
307 bxlt r12 @ return to raise stack overflow excep.
308 @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite
309 ldr r9, [r0, #offMethod_clazz] @ r9<- method->clazz
Ben Chengba4fc8b2009-06-01 13:00:29 -0700310 str rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)]
311 str rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)]
312 ldr rPC, [r0, #offMethod_insns] @ rPC<- methodToCall->insns
313
314
315 @ set up newSaveArea
316 str rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)]
317 str r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)]
318 str r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)]
319 cmp r8, #0 @ suspendCount != 0
320 bxne r12 @ bail to the interpreter
Ben Chengba4fc8b2009-06-01 13:00:29 -0700321
322 ldr r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
323 ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self
324
325 @ Update "glue" values for the new method
326 str r0, [rGLUE, #offGlue_method] @ glue->method = methodToCall
327 str r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ...
328 mov rFP, r1 @ fp = newFp
329 str rFP, [r2, #offThread_curFrame] @ self->curFrame = newFp
330
331 bx lr @ return to the callee-chaining cell
332
333
334
335/* ------------------------------ */
336 .balign 4
Ben Cheng38329f52009-07-07 14:19:20 -0700337 .global dvmCompiler_TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN
338dvmCompiler_TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN:
339/* File: armv5te/TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN.S */
340 /*
341 * For polymorphic callsite, check whether the cached class pointer matches
342 * the current one. If so setup the Dalvik frame and return to the
343 * Thumb code through the link register to transfer control to the callee
344 * method through a dedicated chaining cell.
345 *
Bill Buzbee89efc3d2009-07-28 11:22:22 -0700346 * The predicted chaining cell is declared in ArmLIR.h with the
Ben Cheng38329f52009-07-07 14:19:20 -0700347 * following layout:
348 *
349 * typedef struct PredictedChainingCell {
350 * u4 branch;
351 * const ClassObject *clazz;
352 * const Method *method;
353 * u4 counter;
354 * } PredictedChainingCell;
355 *
356 * Upon returning to the callsite:
357 * - lr : to branch to the chaining cell
358 * - lr+2: to punt to the interpreter
359 * - lr+4: to fully resolve the callee and may rechain.
360 * r3 <- class
361 * r9 <- counter
362 */
363 @ r0 = this, r1 = returnCell, r2 = predictedChainCell, rPC = dalvikCallsite
364 ldr r3, [r0, #offObject_clazz] @ r3 <- this->class
365 ldr r8, [r2, #4] @ r8 <- predictedChainCell->clazz
366 ldr r0, [r2, #8] @ r0 <- predictedChainCell->method
367 ldr r9, [r2, #12] @ r9 <- predictedChainCell->counter
368 cmp r3, r8 @ predicted class == actual class?
369 beq .LinvokeChain @ predicted chain is valid
370 ldr r7, [r3, #offClassObject_vtable] @ r7 <- this->class->vtable
371 sub r1, r9, #1 @ count--
372 str r1, [r2, #12] @ write back to PredictedChainingCell->counter
373 add lr, lr, #4 @ return to fully-resolve landing pad
374 /*
375 * r1 <- count
376 * r2 <- &predictedChainCell
377 * r3 <- this->class
378 * r4 <- dPC
379 * r7 <- this->class->vtable
380 */
381 bx lr
382
383/* ------------------------------ */
384 .balign 4
385 .global dvmCompiler_TEMPLATE_INVOKE_METHOD_NATIVE
386dvmCompiler_TEMPLATE_INVOKE_METHOD_NATIVE:
387/* File: armv5te/TEMPLATE_INVOKE_METHOD_NATIVE.S */
388 @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite
389 ldrh r7, [r0, #offMethod_registersSize] @ r7<- methodToCall->regsSize
390 ldr r9, [rGLUE, #offGlue_interpStackEnd] @ r9<- interpStackEnd
391 ldr r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
392 add r3, r1, #1 @ Thumb addr is odd
393 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area
394 sub r1, r1, r7, lsl #2 @ r1<- newFp (old savearea - regsSize)
395 SAVEAREA_FROM_FP(r10, r1) @ r10<- stack save area
396 ldr r8, [r8] @ r3<- suspendCount (int)
397 cmp r10, r9 @ bottom < interpStackEnd?
398 bxlt lr @ return to raise stack overflow excep.
399 @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite
400 str rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)]
401 str rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)]
402 ldr rPC, [r0, #offMethod_insns] @ rPC<- methodToCall->insns
403
404
405 @ set up newSaveArea
406 str rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)]
407 str r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)]
408 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self
409 str r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)]
410 cmp r8, #0 @ suspendCount != 0
411 ldr r8, [r0, #offMethod_nativeFunc] @ r8<- method->nativeFunc
Jeff Hao97319a82009-08-12 16:57:15 -0700412#if !defined(WITH_SELF_VERIFICATION)
Ben Cheng38329f52009-07-07 14:19:20 -0700413 bxne lr @ bail to the interpreter
Jeff Hao97319a82009-08-12 16:57:15 -0700414#else
415 bx lr @ bail to interpreter unconditionally
416#endif
Ben Cheng38329f52009-07-07 14:19:20 -0700417
418 @ go ahead and transfer control to the native code
Andy McFaddend5ab7262009-08-25 07:19:34 -0700419 ldr r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->...
Ben Cheng38329f52009-07-07 14:19:20 -0700420 str r1, [r3, #offThread_curFrame] @ self->curFrame = newFp
Andy McFaddend5ab7262009-08-25 07:19:34 -0700421 str r9, [r1, #(offStackSaveArea_localRefCookie - sizeofStackSaveArea)]
422 @ newFp->localRefCookie=top
Ben Cheng38329f52009-07-07 14:19:20 -0700423 mov r9, r3 @ r9<- glue->self (preserve)
424 SAVEAREA_FROM_FP(r10, r1) @ r10<- new stack save area
425
426 mov r2, r0 @ r2<- methodToCall
427 mov r0, r1 @ r0<- newFP
428 add r1, rGLUE, #offGlue_retval @ r1<- &retval
429
430 blx r8 @ off to the native code
431
432 @ native return; r9=self, r10=newSaveArea
433 @ equivalent to dvmPopJniLocals
434 ldr r2, [r10, #offStackSaveArea_returnAddr] @ r2 = chaining cell ret
Andy McFaddend5ab7262009-08-25 07:19:34 -0700435 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved->top
Ben Cheng38329f52009-07-07 14:19:20 -0700436 ldr r1, [r9, #offThread_exception] @ check for exception
437 str rFP, [r9, #offThread_curFrame] @ self->curFrame = fp
438 cmp r1, #0 @ null?
Andy McFaddend5ab7262009-08-25 07:19:34 -0700439 str r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top
Ben Cheng38329f52009-07-07 14:19:20 -0700440 bne .LhandleException @ no, handle exception
441 bx r2
442
443
444/* ------------------------------ */
445 .balign 4
Ben Chengba4fc8b2009-06-01 13:00:29 -0700446 .global dvmCompiler_TEMPLATE_CMPG_DOUBLE
447dvmCompiler_TEMPLATE_CMPG_DOUBLE:
448/* File: armv5te/TEMPLATE_CMPG_DOUBLE.S */
449/* File: armv5te/TEMPLATE_CMPL_DOUBLE.S */
450 /*
Bill Buzbee1465db52009-09-23 17:17:35 -0700451 * For the JIT: incoming arguments in r0-r1, r2-r3
Ben Chengba4fc8b2009-06-01 13:00:29 -0700452 * result in r0
453 *
454 * Compare two floating-point values. Puts 0, 1, or -1 into the
455 * destination register based on the results of the comparison.
456 *
457 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
458 * on what value we'd like to return when one of the operands is NaN.
459 *
460 * See OP_CMPL_FLOAT for an explanation.
461 *
462 * For: cmpl-double, cmpg-double
463 */
464 /* op vAA, vBB, vCC */
Bill Buzbee1465db52009-09-23 17:17:35 -0700465 push {r0-r3} @ save operands
466 mov r11, lr @ save return address
Ben Chengba4fc8b2009-06-01 13:00:29 -0700467 LDR_PC_LR ".L__aeabi_cdcmple" @ PIC way of "bl __aeabi_cdcmple"
468 bhi .LTEMPLATE_CMPG_DOUBLE_gt_or_nan @ C set and Z clear, disambiguate
469 mvncc r0, #0 @ (less than) r1<- -1
470 moveq r0, #0 @ (equal) r1<- 0, trumps less than
Bill Buzbee1465db52009-09-23 17:17:35 -0700471 add sp, #16 @ drop unused operands
472 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700473
474 @ Test for NaN with a second comparison. EABI forbids testing bit
475 @ patterns, and we can't represent 0x7fc00000 in immediate form, so
476 @ make the library call.
477.LTEMPLATE_CMPG_DOUBLE_gt_or_nan:
Bill Buzbee1465db52009-09-23 17:17:35 -0700478 pop {r2-r3} @ restore operands in reverse order
479 pop {r0-r1} @ restore operands in reverse order
Ben Chengba4fc8b2009-06-01 13:00:29 -0700480 LDR_PC_LR ".L__aeabi_cdcmple" @ r0<- Z set if eq, C clear if <
481 movcc r0, #1 @ (greater than) r1<- 1
Bill Buzbee1465db52009-09-23 17:17:35 -0700482 bxcc r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700483 mov r0, #1 @ r1<- 1 or -1 for NaN
Bill Buzbee1465db52009-09-23 17:17:35 -0700484 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700485
486
487
488/* ------------------------------ */
489 .balign 4
490 .global dvmCompiler_TEMPLATE_CMPL_DOUBLE
491dvmCompiler_TEMPLATE_CMPL_DOUBLE:
492/* File: armv5te/TEMPLATE_CMPL_DOUBLE.S */
493 /*
Bill Buzbee1465db52009-09-23 17:17:35 -0700494 * For the JIT: incoming arguments in r0-r1, r2-r3
Ben Chengba4fc8b2009-06-01 13:00:29 -0700495 * result in r0
496 *
497 * Compare two floating-point values. Puts 0, 1, or -1 into the
498 * destination register based on the results of the comparison.
499 *
500 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
501 * on what value we'd like to return when one of the operands is NaN.
502 *
503 * See OP_CMPL_FLOAT for an explanation.
504 *
505 * For: cmpl-double, cmpg-double
506 */
507 /* op vAA, vBB, vCC */
Bill Buzbee1465db52009-09-23 17:17:35 -0700508 push {r0-r3} @ save operands
509 mov r11, lr @ save return address
Ben Chengba4fc8b2009-06-01 13:00:29 -0700510 LDR_PC_LR ".L__aeabi_cdcmple" @ PIC way of "bl __aeabi_cdcmple"
511 bhi .LTEMPLATE_CMPL_DOUBLE_gt_or_nan @ C set and Z clear, disambiguate
512 mvncc r0, #0 @ (less than) r1<- -1
513 moveq r0, #0 @ (equal) r1<- 0, trumps less than
Bill Buzbee1465db52009-09-23 17:17:35 -0700514 add sp, #16 @ drop unused operands
515 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700516
517 @ Test for NaN with a second comparison. EABI forbids testing bit
518 @ patterns, and we can't represent 0x7fc00000 in immediate form, so
519 @ make the library call.
520.LTEMPLATE_CMPL_DOUBLE_gt_or_nan:
Bill Buzbee1465db52009-09-23 17:17:35 -0700521 pop {r2-r3} @ restore operands in reverse order
522 pop {r0-r1} @ restore operands in reverse order
Ben Chengba4fc8b2009-06-01 13:00:29 -0700523 LDR_PC_LR ".L__aeabi_cdcmple" @ r0<- Z set if eq, C clear if <
524 movcc r0, #1 @ (greater than) r1<- 1
Bill Buzbee1465db52009-09-23 17:17:35 -0700525 bxcc r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700526 mvn r0, #0 @ r1<- 1 or -1 for NaN
Bill Buzbee1465db52009-09-23 17:17:35 -0700527 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700528
529
530/* ------------------------------ */
531 .balign 4
532 .global dvmCompiler_TEMPLATE_CMPG_FLOAT
533dvmCompiler_TEMPLATE_CMPG_FLOAT:
534/* File: armv5te/TEMPLATE_CMPG_FLOAT.S */
535/* File: armv5te/TEMPLATE_CMPL_FLOAT.S */
536 /*
Bill Buzbee1465db52009-09-23 17:17:35 -0700537 * For the JIT: incoming arguments in r0-r1, r2-r3
Ben Chengba4fc8b2009-06-01 13:00:29 -0700538 * result in r0
539 *
540 * Compare two floating-point values. Puts 0, 1, or -1 into the
541 * destination register based on the results of the comparison.
542 *
543 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
544 * on what value we'd like to return when one of the operands is NaN.
545 *
546 * The operation we're implementing is:
547 * if (x == y)
548 * return 0;
549 * else if (x < y)
550 * return -1;
551 * else if (x > y)
552 * return 1;
553 * else
554 * return {-1,1}; // one or both operands was NaN
555 *
556 * The straightforward implementation requires 3 calls to functions
557 * that return a result in r0. We can do it with two calls if our
558 * EABI library supports __aeabi_cfcmple (only one if we want to check
559 * for NaN directly):
560 * check x <= y
561 * if <, return -1
562 * if ==, return 0
563 * check y <= x
564 * if <, return 1
565 * return {-1,1}
566 *
567 * for: cmpl-float, cmpg-float
568 */
569 /* op vAA, vBB, vCC */
Ben Chengba4fc8b2009-06-01 13:00:29 -0700570 mov r9, r0 @ Save copies - we may need to redo
571 mov r10, r1
Bill Buzbee1465db52009-09-23 17:17:35 -0700572 mov r11, lr @ save return address
Ben Chengba4fc8b2009-06-01 13:00:29 -0700573 LDR_PC_LR ".L__aeabi_cfcmple" @ cmp <=: C clear if <, Z set if eq
574 bhi .LTEMPLATE_CMPG_FLOAT_gt_or_nan @ C set and Z clear, disambiguate
575 mvncc r0, #0 @ (less than) r0<- -1
576 moveq r0, #0 @ (equal) r0<- 0, trumps less than
Bill Buzbee1465db52009-09-23 17:17:35 -0700577 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700578 @ Test for NaN with a second comparison. EABI forbids testing bit
579 @ patterns, and we can't represent 0x7fc00000 in immediate form, so
580 @ make the library call.
581.LTEMPLATE_CMPG_FLOAT_gt_or_nan:
Bill Buzbee1465db52009-09-23 17:17:35 -0700582 mov r0, r10 @ restore in reverse order
583 mov r1, r9
Ben Chengba4fc8b2009-06-01 13:00:29 -0700584 LDR_PC_LR ".L__aeabi_cfcmple" @ r0<- Z set if eq, C clear if <
585 movcc r0, #1 @ (greater than) r1<- 1
Bill Buzbee1465db52009-09-23 17:17:35 -0700586 bxcc r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700587 mov r0, #1 @ r1<- 1 or -1 for NaN
Bill Buzbee1465db52009-09-23 17:17:35 -0700588 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700589
590
591
592
593/* ------------------------------ */
594 .balign 4
595 .global dvmCompiler_TEMPLATE_CMPL_FLOAT
596dvmCompiler_TEMPLATE_CMPL_FLOAT:
597/* File: armv5te/TEMPLATE_CMPL_FLOAT.S */
598 /*
Bill Buzbee1465db52009-09-23 17:17:35 -0700599 * For the JIT: incoming arguments in r0-r1, r2-r3
Ben Chengba4fc8b2009-06-01 13:00:29 -0700600 * result in r0
601 *
602 * Compare two floating-point values. Puts 0, 1, or -1 into the
603 * destination register based on the results of the comparison.
604 *
605 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
606 * on what value we'd like to return when one of the operands is NaN.
607 *
608 * The operation we're implementing is:
609 * if (x == y)
610 * return 0;
611 * else if (x < y)
612 * return -1;
613 * else if (x > y)
614 * return 1;
615 * else
616 * return {-1,1}; // one or both operands was NaN
617 *
618 * The straightforward implementation requires 3 calls to functions
619 * that return a result in r0. We can do it with two calls if our
620 * EABI library supports __aeabi_cfcmple (only one if we want to check
621 * for NaN directly):
622 * check x <= y
623 * if <, return -1
624 * if ==, return 0
625 * check y <= x
626 * if <, return 1
627 * return {-1,1}
628 *
629 * for: cmpl-float, cmpg-float
630 */
631 /* op vAA, vBB, vCC */
Ben Chengba4fc8b2009-06-01 13:00:29 -0700632 mov r9, r0 @ Save copies - we may need to redo
633 mov r10, r1
Bill Buzbee1465db52009-09-23 17:17:35 -0700634 mov r11, lr @ save return address
Ben Chengba4fc8b2009-06-01 13:00:29 -0700635 LDR_PC_LR ".L__aeabi_cfcmple" @ cmp <=: C clear if <, Z set if eq
636 bhi .LTEMPLATE_CMPL_FLOAT_gt_or_nan @ C set and Z clear, disambiguate
637 mvncc r0, #0 @ (less than) r0<- -1
638 moveq r0, #0 @ (equal) r0<- 0, trumps less than
Bill Buzbee1465db52009-09-23 17:17:35 -0700639 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700640 @ Test for NaN with a second comparison. EABI forbids testing bit
641 @ patterns, and we can't represent 0x7fc00000 in immediate form, so
642 @ make the library call.
643.LTEMPLATE_CMPL_FLOAT_gt_or_nan:
Bill Buzbee1465db52009-09-23 17:17:35 -0700644 mov r0, r10 @ restore in reverse order
645 mov r1, r9
Ben Chengba4fc8b2009-06-01 13:00:29 -0700646 LDR_PC_LR ".L__aeabi_cfcmple" @ r0<- Z set if eq, C clear if <
647 movcc r0, #1 @ (greater than) r1<- 1
Bill Buzbee1465db52009-09-23 17:17:35 -0700648 bxcc r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700649 mvn r0, #0 @ r1<- 1 or -1 for NaN
Bill Buzbee1465db52009-09-23 17:17:35 -0700650 bx r11
Ben Chengba4fc8b2009-06-01 13:00:29 -0700651
652
653
654/* ------------------------------ */
655 .balign 4
656 .global dvmCompiler_TEMPLATE_MUL_LONG
657dvmCompiler_TEMPLATE_MUL_LONG:
658/* File: armv5te/TEMPLATE_MUL_LONG.S */
659 /*
660 * Signed 64-bit integer multiply.
661 *
662 * For JIT: op1 in r0/r1, op2 in r2/r3, return in r0/r1
663 *
664 * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
665 * WX
666 * x YZ
667 * --------
668 * ZW ZX
669 * YW YX
670 *
671 * The low word of the result holds ZX, the high word holds
672 * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because
673 * it doesn't fit in the low 64 bits.
674 *
675 * Unlike most ARM math operations, multiply instructions have
676 * restrictions on using the same register more than once (Rd and Rm
677 * cannot be the same).
678 */
679 /* mul-long vAA, vBB, vCC */
680 mul ip, r2, r1 @ ip<- ZxW
681 umull r9, r10, r2, r0 @ r9/r10 <- ZxX
682 mla r2, r0, r3, ip @ r2<- YxX + (ZxW)
683 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX))
684 mov r0,r9
685 mov r1,r10
686 bx lr
687
688/* ------------------------------ */
689 .balign 4
690 .global dvmCompiler_TEMPLATE_SHL_LONG
691dvmCompiler_TEMPLATE_SHL_LONG:
692/* File: armv5te/TEMPLATE_SHL_LONG.S */
693 /*
694 * Long integer shift. This is different from the generic 32/64-bit
695 * binary operations because vAA/vBB are 64-bit but vCC (the shift
696 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
697 * 6 bits.
698 */
699 /* shl-long vAA, vBB, vCC */
700 and r2, r2, #63 @ r2<- r2 & 0x3f
701 mov r1, r1, asl r2 @ r1<- r1 << r2
702 rsb r3, r2, #32 @ r3<- 32 - r2
703 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2))
704 subs ip, r2, #32 @ ip<- r2 - 32
705 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32)
706 mov r0, r0, asl r2 @ r0<- r0 << r2
707 bx lr
708
709/* ------------------------------ */
710 .balign 4
711 .global dvmCompiler_TEMPLATE_SHR_LONG
712dvmCompiler_TEMPLATE_SHR_LONG:
713/* File: armv5te/TEMPLATE_SHR_LONG.S */
714 /*
715 * Long integer shift. This is different from the generic 32/64-bit
716 * binary operations because vAA/vBB are 64-bit but vCC (the shift
717 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
718 * 6 bits.
719 */
720 /* shr-long vAA, vBB, vCC */
721 and r2, r2, #63 @ r0<- r0 & 0x3f
722 mov r0, r0, lsr r2 @ r0<- r2 >> r2
723 rsb r3, r2, #32 @ r3<- 32 - r2
724 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
725 subs ip, r2, #32 @ ip<- r2 - 32
726 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32)
727 mov r1, r1, asr r2 @ r1<- r1 >> r2
728 bx lr
729
730
731/* ------------------------------ */
732 .balign 4
733 .global dvmCompiler_TEMPLATE_USHR_LONG
734dvmCompiler_TEMPLATE_USHR_LONG:
735/* File: armv5te/TEMPLATE_USHR_LONG.S */
736 /*
737 * Long integer shift. This is different from the generic 32/64-bit
738 * binary operations because vAA/vBB are 64-bit but vCC (the shift
739 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
740 * 6 bits.
741 */
742 /* ushr-long vAA, vBB, vCC */
743 and r2, r2, #63 @ r0<- r0 & 0x3f
744 mov r0, r0, lsr r2 @ r0<- r2 >> r2
745 rsb r3, r2, #32 @ r3<- 32 - r2
746 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
747 subs ip, r2, #32 @ ip<- r2 - 32
748 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32)
749 mov r1, r1, lsr r2 @ r1<- r1 >>> r2
750 bx lr
751
752
Ben Cheng4f489172009-09-27 17:08:35 -0700753/* ------------------------------ */
754 .balign 4
755 .global dvmCompiler_TEMPLATE_THROW_EXCEPTION_COMMON
756dvmCompiler_TEMPLATE_THROW_EXCEPTION_COMMON:
757/* File: armv5te/TEMPLATE_THROW_EXCEPTION_COMMON.S */
758 /*
759 * Throw an exception from JIT'ed code.
760 * On entry:
761 * r0 Dalvik PC that raises the exception
762 */
763 b .LhandleException
764
Bill Buzbee1465db52009-09-23 17:17:35 -0700765/* ------------------------------ */
766 .balign 4
767 .global dvmCompiler_TEMPLATE_SAVE_STATE
768dvmCompiler_TEMPLATE_SAVE_STATE:
769/* File: armv5te/TEMPLATE_SAVE_STATE.S */
770 /*
771 * This handler performs a register save for selfVerification mode.
772 * On entry:
773 * Top of stack + 4: r7 value to save
774 * Top of stack + 0: r0 value to save
775 * r0 - offset from rGLUE to the beginning of the heapArgSpace record
776 * r7 - the value of regMap
777 *
778 * The handler must save regMap, r0-r12 and then return with r0-r12
779 * with their original values (note that this means r0 and r7 must take
780 * the values on the stack - not the ones in those registers on entry.
781 * Finally, the two registers previously pushed must be popped.
782 */
783 add r0, r0, rGLUE @ pointer to heapArgSpace
784 stmia r0!, {r7} @ save regMap
785 ldr r7, [r13, #0] @ recover r0 value
786 stmia r0!, {r7} @ save r0
787 ldr r7, [r13, #4] @ recover r7 value
788 stmia r0!, {r1-r12}
789 pop {r0, r7} @ recover r0, r7
790 bx lr
791
792/* ------------------------------ */
793 .balign 4
794 .global dvmCompiler_TEMPLATE_RESTORE_STATE
795dvmCompiler_TEMPLATE_RESTORE_STATE:
796/* File: armv5te/TEMPLATE_RESTORE_STATE.S */
797 /*
798 * This handler restores state following a selfVerification memory access.
799 * On entry:
800 * r0 - offset from rGLUE to the 1st element of the coreRegs save array.
801 */
802 add r0, r0, rGLUE @ pointer to heapArgSpace.coreRegs[0]
803 ldmia r0, {r0-r12}
804 bx lr
805
Bill Buzbeefd023aa2009-11-02 09:23:49 -0800806/* ------------------------------ */
807 .balign 4
808 .global dvmCompiler_TEMPLATE_STRING_COMPARETO
809dvmCompiler_TEMPLATE_STRING_COMPARETO:
810/* File: armv5te/TEMPLATE_STRING_COMPARETO.S */
811 /*
812 * String's compareTo.
813 *
814 * Requires r0/r1 to have been previously checked for null. Will
815 * return negative if this's string is < comp, 0 if they are the
816 * same and positive if >.
817 *
818 * IMPORTANT NOTE:
819 *
820 * This code relies on hard-coded offsets for string objects, and must be
821 * kept in sync with definitions in UtfString.h. See asm-constants.h
822 *
823 * On entry:
824 * r0: this object pointer
825 * r1: comp object pointer
826 *
827 */
828
829 mov r2, r0 @ this to r2, opening up r0 for return value
830 subs r0, r2, r1 @ Same?
831 bxeq lr
832
833 ldr r4, [r2, #STRING_FIELDOFF_OFFSET]
834 ldr r9, [r1, #STRING_FIELDOFF_OFFSET]
835 ldr r7, [r2, #STRING_FIELDOFF_COUNT]
836 ldr r10, [r1, #STRING_FIELDOFF_COUNT]
837 ldr r2, [r2, #STRING_FIELDOFF_VALUE]
838 ldr r1, [r1, #STRING_FIELDOFF_VALUE]
839
840 /*
841 * At this point, we have:
842 * value: r2/r1
843 * offset: r4/r9
844 * count: r7/r10
845 * We're going to compute
846 * r11 <- countDiff
847 * r10 <- minCount
848 */
849 subs r11, r7, r10
850 movls r10, r7
851
852 /* Now, build pointers to the string data */
853 add r2, r2, r4, lsl #1
854 add r1, r1, r9, lsl #1
855 /*
856 * Note: data pointers point to previous element so we can use pre-index
857 * mode with base writeback.
858 */
859 add r2, #16-2 @ offset to contents[-1]
860 add r1, #16-2 @ offset to contents[-1]
861
862 /*
863 * At this point we have:
864 * r2: *this string data
865 * r1: *comp string data
866 * r10: iteration count for comparison
867 * r11: value to return if the first part of the string is equal
868 * r0: reserved for result
869 * r3, r4, r7, r8, r9, r12 available for loading string data
870 */
871
872 cmp r10, #3
873 blt do_remainder
874loopback_triple:
875 ldrh r3, [r2, #2]!
876 ldrh r4, [r1, #2]!
877 ldrh r7, [r2, #2]!
878 ldrh r8, [r1, #2]!
879 ldrh r9, [r2, #2]!
880 ldrh r12,[r1, #2]!
881 subs r0, r3, r4
882 subeqs r0, r7, r8
883 subeqs r0, r9, r12
884 bxne lr
885 subs r10, #3
886 bgt loopback_triple
887
888do_remainder:
889 cmp r10, #0
890 beq returnDiff
891
892loopback_single:
893 ldrh r3, [r2, #2]!
894 ldrh r4, [r1, #2]!
895 subs r0, r3, r4
896 bxne lr
897 subs r10, #1
898 bne loopback_single
899
900returnDiff:
901 mov r0, r11
902 bx lr
903
904
905/* ------------------------------ */
906 .balign 4
907 .global dvmCompiler_TEMPLATE_STRING_INDEXOF
908dvmCompiler_TEMPLATE_STRING_INDEXOF:
909/* File: armv5te/TEMPLATE_STRING_INDEXOF.S */
910 /*
911 * String's indexOf.
912 *
913 * Requires r0 to have been previously checked for null. Will
914 * return index of match of r1 in r0.
915 *
916 * IMPORTANT NOTE:
917 *
918 * This code relies on hard-coded offsets for string objects, and must be
919 * kept in sync wth definitions in UtfString.h See asm-constants.h
920 *
921 * On entry:
922 * r0: string object pointer
923 * r1: char to match
924 * r2: Starting offset in string data
925 */
926
927 ldr r7, [r0, #STRING_FIELDOFF_OFFSET]
928 ldr r8, [r0, #STRING_FIELDOFF_COUNT]
929 ldr r0, [r0, #STRING_FIELDOFF_VALUE]
930
931 /*
932 * At this point, we have:
933 * value: r0
934 * offset: r7
935 * count: r8
936 */
937
938 /* Clamp start to [0..count] */
939 cmp r2, #0
940 movlt r2, #0
941 cmp r2, r8
942 movgt r2, r0
943
944 /* Fold start & offset, and set data pointer to contents[-1] */
945 add r2, r7
946 add r0, r0, r2, lsl #1
947 add r0, #16-2 @ offset to contents[-1]
948 add r2, r0, #2 @ remember true start of data
949
950 /*
951 * At this point we have:
952 * r0: *next[-1] char to test
953 * r2: *start
954 * r1: char to compare
955 * r8: max count
956 * r3, r4, r7, r9, r12 available for loading string data
957 */
958
959 /* Unroll x 4 */
960
961 cmp r8, #4
962 blt do_rest
963loopback_quad:
964 ldrh r3, [r0, #2]!
965 ldrh r4, [r0, #2]!
966 ldrh r7, [r0, #2]!
967 ldrh r9, [r0, #2]!
968 cmp r3, r1
969 beq match_0
970 cmp r4, r1
971 beq match_1
972 cmp r7, r1
973 beq match_2
974 cmp r9, r1
975 beq match_3
976 subs r8, #4
977 bgt loopback_quad
978
979do_rest:
980 cmp r8, #0
981 beq no_match
982
983loopback_indexof:
984 ldrh r3, [r0, #2]!
985 cmp r3, r1
986 beq match_3
987 subs r8, #1
988 bne loopback_indexof
989
990no_match:
991 mov r0, #-1
992 bx lr
993
994match_0:
995 sub r0, #6
996 sub r0, r2
997 bx lr
998match_1:
999 sub r0, #4
1000 sub r0, r2
1001 bx lr
1002match_2:
1003 sub r0, #2
1004 sub r0, r2
1005 bx lr
1006match_3:
1007 sub r0, r2
1008 bx lr
1009
1010
Ben Chengba4fc8b2009-06-01 13:00:29 -07001011 .size dvmCompilerTemplateStart, .-dvmCompilerTemplateStart
1012/* File: armv5te/footer.S */
1013/*
1014 * ===========================================================================
1015 * Common subroutines and data
1016 * ===========================================================================
1017 */
1018
1019 .text
1020 .align 2
1021.LinvokeNative:
1022 @ Prep for the native call
1023 @ r1 = newFP, r0 = methodToCall
1024 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self
Andy McFaddend5ab7262009-08-25 07:19:34 -07001025 ldr r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->...
Ben Chengba4fc8b2009-06-01 13:00:29 -07001026 str r1, [r3, #offThread_curFrame] @ self->curFrame = newFp
Andy McFaddend5ab7262009-08-25 07:19:34 -07001027 str r9, [r1, #(offStackSaveArea_localRefCookie - sizeofStackSaveArea)]
1028 @ newFp->localRefCookie=top
Ben Chengba4fc8b2009-06-01 13:00:29 -07001029 mov r9, r3 @ r9<- glue->self (preserve)
1030 SAVEAREA_FROM_FP(r10, r1) @ r10<- new stack save area
1031
1032 mov r2, r0 @ r2<- methodToCall
1033 mov r0, r1 @ r0<- newFP
1034 add r1, rGLUE, #offGlue_retval @ r1<- &retval
1035
1036 LDR_PC_LR "[r2, #offMethod_nativeFunc]"
1037
1038 @ native return; r9=self, r10=newSaveArea
1039 @ equivalent to dvmPopJniLocals
1040 ldr r2, [r10, #offStackSaveArea_returnAddr] @ r2 = chaining cell ret
Andy McFaddend5ab7262009-08-25 07:19:34 -07001041 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved->top
Ben Chengba4fc8b2009-06-01 13:00:29 -07001042 ldr r1, [r9, #offThread_exception] @ check for exception
1043 str rFP, [r9, #offThread_curFrame] @ self->curFrame = fp
1044 cmp r1, #0 @ null?
Andy McFaddend5ab7262009-08-25 07:19:34 -07001045 str r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top
Ben Cheng4f489172009-09-27 17:08:35 -07001046 ldr r0, [r10, #offStackSaveArea_savedPc] @ reload rPC
Ben Chengba4fc8b2009-06-01 13:00:29 -07001047 bne .LhandleException @ no, handle exception
1048 bx r2
1049
Ben Cheng4f489172009-09-27 17:08:35 -07001050/*
1051 * On entry:
1052 * r0 Faulting Dalvik PC
1053 */
Ben Chengba4fc8b2009-06-01 13:00:29 -07001054.LhandleException:
Ben Cheng4f489172009-09-27 17:08:35 -07001055 ldr r1, .LdvmMterpCommonExceptionThrown @ PIC way of getting &func
Ben Chengcc6600c2009-06-22 14:45:16 -07001056 ldr rIBASE, .LdvmAsmInstructionStart @ same as above
Ben Cheng4f489172009-09-27 17:08:35 -07001057 mov rPC, r0 @ reload the faulting Dalvik address
1058 mov pc, r1 @ branch to dvmMterpCommonExceptionThrown
Ben Chengba4fc8b2009-06-01 13:00:29 -07001059
1060 .align 2
1061.LdvmAsmInstructionStart:
1062 .word dvmAsmInstructionStart
1063.LdvmJitToInterpNoChain:
1064 .word dvmJitToInterpNoChain
1065.LdvmMterpStdBail:
1066 .word dvmMterpStdBail
Ben Chengcc6600c2009-06-22 14:45:16 -07001067.LdvmMterpCommonExceptionThrown:
1068 .word dvmMterpCommonExceptionThrown
Ben Chengba4fc8b2009-06-01 13:00:29 -07001069.L__aeabi_cdcmple:
1070 .word __aeabi_cdcmple
1071.L__aeabi_cfcmple:
1072 .word __aeabi_cfcmple
1073
1074 .global dmvCompilerTemplateEnd
1075dmvCompilerTemplateEnd:
1076
1077#endif /* WITH_JIT */
1078