CompilerTemplateAsm-armv5te.S revision 6c10a977ec892c26c8e306356491833bbb073d40
1ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/*
2ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * This file was generated automatically by gen-template.py for 'armv5te'.
3ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *
4ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * --> DO NOT EDIT <--
5ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */
6ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
7ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/header.S */
8ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/*
9ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Copyright (C) 2008 The Android Open Source Project
10ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *
11ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Licensed under the Apache License, Version 2.0 (the "License");
12ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * you may not use this file except in compliance with the License.
13ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * You may obtain a copy of the License at
14ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *
15ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *      http://www.apache.org/licenses/LICENSE-2.0
16ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *
17ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Unless required by applicable law or agreed to in writing, software
18ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * distributed under the License is distributed on an "AS IS" BASIS,
19ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * See the License for the specific language governing permissions and
21ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * limitations under the License.
22ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */
23ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
24ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#if defined(WITH_JIT)
25ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
26ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/*
27ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * ARMv5 definitions and declarations.
28ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */
29ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
30ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/*
31ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengARM EABI general notes:
32ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
33ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengr0-r3 hold first 4 args to a method; they are not preserved across method calls
34ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengr4-r8 are available for general use
35ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengr9 is given special treatment in some situations, but not for us
36ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengr10 (sl) seems to be generally available
37ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengr11 (fp) is used by gcc (unless -fomit-frame-pointer is set)
38ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengr12 (ip) is scratch -- not preserved across method calls
39ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengr13 (sp) should be managed carefully in case a signal arrives
40ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengr14 (lr) must be preserved
41ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengr15 (pc) can be tinkered with directly
42ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
43ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengr0 holds returns of <= 4 bytes
44ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengr0-r1 hold returns of 8 bytes, low word in r0
45ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
46ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengCallee must save/restore r4+ (except r12) if it modifies them.
47ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
48ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengStack is "full descending".  Only the arguments that don't fit in the first 4
49ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengregisters are placed on the stack.  "sp" points at the first stacked argument
50ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng(i.e. the 5th arg).
51ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
52ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengVFP: single-precision results in s0, double-precision results in d0.
53ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
54ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengIn the EABI, "sp" must be 64-bit aligned on entry to a function, and any
55ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng64-bit quantities (long long, double) must be 64-bit aligned.
56ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng*/
57ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
58ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/*
59ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengJIT and ARM notes:
60ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
61ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengThe following registers have fixed assignments:
62ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
63ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng  reg nick      purpose
64ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng  r5  rFP       interpreted frame pointer, used for accessing locals and args
65ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng  r6  rGLUE     MterpGlue pointer
66ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
67ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengThe following registers have fixed assignments in mterp but are scratch
68ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengregisters in compiled code
69ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
70ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng  reg nick      purpose
71ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng  r4  rPC       interpreted program counter, used for fetching instructions
721da12167d913efde56ec3b40491524b051679f2cAndy McFadden  r7  rINST     first 16-bit code unit of current instruction
731da12167d913efde56ec3b40491524b051679f2cAndy McFadden  r8  rIBASE    interpreted instruction base pointer, used for computed goto
74ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
75ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengMacros are provided for common operations.  Each macro MUST emit only
76ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengone instruction to make instruction-counting easier.  They MUST NOT alter
77ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengunspecified registers or condition codes.
78ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng*/
79ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
80ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* single-purpose registers, given names for clarity */
81ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#define rPC     r4
82ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#define rFP     r5
83ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#define rGLUE   r6
841da12167d913efde56ec3b40491524b051679f2cAndy McFadden#define rINST   r7
851da12167d913efde56ec3b40491524b051679f2cAndy McFadden#define rIBASE  r8
86ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
87ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/*
88ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Given a frame pointer, find the stack save area.
89ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *
90ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * In C this is "((StackSaveArea*)(_fp) -1)".
91ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */
92ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#define SAVEAREA_FROM_FP(_reg, _fpreg) \
93ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    sub     _reg, _fpreg, #sizeofStackSaveArea
94ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
95ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/*
96ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * This is a #include, not a %include, because we want the C pre-processor
97ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * to expand the macros into assembler assignment statements.
98ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */
99ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#include "../../../mterp/common/asm-constants.h"
100ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
101ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
102ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/platform.S */
103ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/*
104ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * ===========================================================================
105ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *  CPU-version-specific defines
106ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * ===========================================================================
107ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */
108ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
109ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/*
110ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Macro for "MOV LR,PC / LDR PC,xxx", which is not allowed pre-ARMv5.
111ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Jump to subroutine.
112ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *
113ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * May modify IP and LR.
114ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */
115ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.macro  LDR_PC_LR source
116ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     lr, pc
117ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     pc, \source
118ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.endm
119ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
120ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
121ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompilerTemplateStart
122ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .type   dvmCompilerTemplateStart, %function
123ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .text
124ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
125ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompilerTemplateStart:
126ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
127ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
128ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
129ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_CMP_LONG
130ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_CMP_LONG:
131ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_CMP_LONG.S */
132ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
133ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
134ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * register based on the results of the comparison.
135ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
136ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * We load the full values with LDM, but in practice many values could
137ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * be resolved by only looking at the high word.  This could be made
138ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * faster or slower by splitting the LDM into a pair of LDRs.
139ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
140ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * If we just wanted to set condition flags, we could do this:
141ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *  subs    ip, r0, r2
142ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *  sbcs    ip, r1, r3
143ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *  subeqs  ip, r0, r2
144ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Leaving { <0, 0, >0 } in ip.  However, we have to set it to a specific
145ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * integer value, which we can do with 2 conditional mov/mvn instructions
146ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * (set 1, set -1; if they're equal we already have 0 in ip), giving
147ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * us a constant 5-cycle path plus a branch at the end to the
148ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * instruction epilogue code.  The multi-compare approach below needs
149ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch
150ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * in the worst case (the 64-bit values are equal).
151ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
152ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* cmp-long vAA, vBB, vCC */
153ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r1, r3                      @ compare (vBB+1, vCC+1)
154ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    blt     .LTEMPLATE_CMP_LONG_less            @ signed compare on high part
155ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bgt     .LTEMPLATE_CMP_LONG_greater
156ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    subs    r0, r0, r2                  @ r0<- r0 - r2
157ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bxeq     lr
158ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bhi     .LTEMPLATE_CMP_LONG_greater         @ unsigned compare on low part
159ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LTEMPLATE_CMP_LONG_less:
160ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mvn     r0, #0                      @ r0<- -1
161ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      lr
162ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LTEMPLATE_CMP_LONG_greater:
163ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, #1                      @ r0<- 1
164ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      lr
165ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
166ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
167ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
168ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
169ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_RETURN
170ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_RETURN:
171ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_RETURN.S */
172ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
173ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Unwind a frame from the Dalvik stack for compiled OP_RETURN_XXX.
174ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * If the stored value in returnAddr
175ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * is non-zero, the caller is compiled by the JIT thus return to the
176ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * address in the code cache following the invoke instruction. Otherwise
177ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * return to the special dvmJitToInterpNoChain entry point.
178ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
179ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    SAVEAREA_FROM_FP(r0, rFP)           @ r0<- saveArea (old)
180ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r10, [r0, #offStackSaveArea_prevFrame] @ r10<- saveArea->prevFrame
181ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
182ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     rPC, [r0, #offStackSaveArea_savedPc] @ rPC<- saveArea->savedPc
18397319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#if !defined(WITH_SELF_VERIFICATION)
184ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r9,  [r0, #offStackSaveArea_returnAddr] @ r9<- chaining cell ret
18597319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#else
18697319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao    mov     r9, #0                      @ disable chaining
18797319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#endif
188ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r2, [r10, #(offStackSaveArea_method - sizeofStackSaveArea)]
189ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                                        @ r2<- method we're returning to
190ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r3, [rGLUE, #offGlue_self]  @ r3<- glue->self
191ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r2, #0                      @ break frame?
19297319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#if !defined(WITH_SELF_VERIFICATION)
193ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    beq     1f                          @ bail to interpreter
19497319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#else
19597319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao    blxeq   lr                          @ punt to interpreter and compare state
19697319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#endif
1976c10a977ec892c26c8e306356491833bbb073d40Ben Cheng    ldr     r1, .LdvmJitToInterpNoChain @ defined in footer.S
198ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     rFP, r10                    @ publish new FP
199ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldrne   r10, [r2, #offMethod_clazz] @ r10<- method->clazz
200ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r8, [r8]                    @ r8<- suspendCount
201ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
202ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method
2036c10a977ec892c26c8e306356491833bbb073d40Ben Cheng    ldr     r0, [r10, #offClassObject_pDvmDex] @ r0<- method->clazz->pDvmDex
204ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rFP, [r3, #offThread_curFrame] @ self->curFrame = fp
205ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    add     rPC, rPC, #6                @ publish new rPC (advance 6 bytes)
2066c10a977ec892c26c8e306356491833bbb073d40Ben Cheng    str     r0, [rGLUE, #offGlue_methodClassDex]
207ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r8, #0                      @ check the suspendCount
208ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movne   r9, #0                      @ clear the chaining cell address
209ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r9, #0                      @ chaining cell exists?
210ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    blxne   r9                          @ jump to the chaining cell
2116c10a977ec892c26c8e306356491833bbb073d40Ben Cheng#if defined(EXIT_STATS)
2126c10a977ec892c26c8e306356491833bbb073d40Ben Cheng    mov     r0, #kCallsiteInterpreted
2136c10a977ec892c26c8e306356491833bbb073d40Ben Cheng#endif
2146c10a977ec892c26c8e306356491833bbb073d40Ben Cheng    mov     pc, r1                      @ callsite is interpreted
215ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng1:
216ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    stmia   rGLUE, {rPC, rFP}           @ SAVE_PC_FP_TO_GLUE()
217ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r2, .LdvmMterpStdBail       @ defined in footer.S
218ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r1, #0                      @ changeInterp = false
219ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, rGLUE                   @ Expecting rGLUE in r0
220ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    blx     r2                          @ exit the interpreter
221ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
222ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
223ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
224ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_INVOKE_METHOD_NO_OPT
225ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_INVOKE_METHOD_NO_OPT:
226ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_INVOKE_METHOD_NO_OPT.S */
227ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
228ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For polymorphic callsites - setup the Dalvik frame and load Dalvik PC
229ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * into rPC then jump to dvmJitToInterpNoChain to dispatch the
230ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * runtime-resolved callee.
231ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
232ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite
233ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldrh    r7, [r0, #offMethod_registersSize]  @ r7<- methodToCall->regsSize
234ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldrh    r2, [r0, #offMethod_outsSize]  @ r2<- methodToCall->outsSize
235ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r9, [rGLUE, #offGlue_interpStackEnd]    @ r9<- interpStackEnd
236ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
237ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    add     r3, r1, #1  @ Thumb addr is odd
238ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
239ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    sub     r1, r1, r7, lsl #2          @ r1<- newFp (old savearea - regsSize)
240ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    SAVEAREA_FROM_FP(r10, r1)           @ r10<- stack save area
241ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    sub     r10, r10, r2, lsl #2        @ r10<- bottom (newsave - outsSize)
242ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r8, [r8]                    @ r3<- suspendCount (int)
243ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r10, r9                     @ bottom < interpStackEnd?
244ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bxlt    lr                          @ return to raise stack overflow excep.
245ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite
246ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r9, [r0, #offMethod_clazz]      @ r9<- method->clazz
247ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r10, [r0, #offMethod_accessFlags] @ r10<- methodToCall->accessFlags
248ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)]
249ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)]
250ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     rPC, [r0, #offMethod_insns]     @ rPC<- methodToCall->insns
251ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
252ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
253ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ set up newSaveArea
254ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)]
255ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)]
256ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)]
257ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r8, #0                      @ suspendCount != 0
258ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bxne    lr                          @ bail to the interpreter
259ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    tst     r10, #ACC_NATIVE
26097319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#if !defined(WITH_SELF_VERIFICATION)
261ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bne     .LinvokeNative
26297319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#else
26397319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao    bxne    lr                          @ bail to the interpreter
26497319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#endif
265ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
266ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r10, .LdvmJitToInterpNoChain
267ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
268ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r2, [rGLUE, #offGlue_self]      @ r2<- glue->self
269ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
270ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Update "glue" values for the new method
271ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r0, [rGLUE, #offGlue_method]    @ glue->method = methodToCall
272ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ...
273ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     rFP, r1                         @ fp = newFp
274ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rFP, [r2, #offThread_curFrame]  @ self->curFrame = newFp
275ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
276ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Start executing the callee
2776c10a977ec892c26c8e306356491833bbb073d40Ben Cheng#if defined(EXIT_STATS)
2786c10a977ec892c26c8e306356491833bbb073d40Ben Cheng    mov     r0, #kInlineCacheMiss
2796c10a977ec892c26c8e306356491833bbb073d40Ben Cheng#endif
280ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     pc, r10                         @ dvmJitToInterpNoChain
281ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
282ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
283ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
284ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_INVOKE_METHOD_CHAIN
285ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_INVOKE_METHOD_CHAIN:
286ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_INVOKE_METHOD_CHAIN.S */
287ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
288ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For monomorphic callsite, setup the Dalvik frame and return to the
289ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Thumb code through the link register to transfer control to the callee
290ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * method through a dedicated chaining cell.
291ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
292ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite
29338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ methodToCall is guaranteed to be non-native
29438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng.LinvokeChain:
295ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldrh    r7, [r0, #offMethod_registersSize]  @ r7<- methodToCall->regsSize
296ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldrh    r2, [r0, #offMethod_outsSize]  @ r2<- methodToCall->outsSize
297ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r9, [rGLUE, #offGlue_interpStackEnd]    @ r9<- interpStackEnd
298ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
299ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    add     r3, r1, #1  @ Thumb addr is odd
300ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
301ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    sub     r1, r1, r7, lsl #2          @ r1<- newFp (old savearea - regsSize)
302ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    SAVEAREA_FROM_FP(r10, r1)           @ r10<- stack save area
303ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    add     r12, lr, #2                 @ setup the punt-to-interp address
304ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    sub     r10, r10, r2, lsl #2        @ r10<- bottom (newsave - outsSize)
305ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r8, [r8]                    @ r3<- suspendCount (int)
306ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r10, r9                     @ bottom < interpStackEnd?
307ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bxlt    r12                         @ return to raise stack overflow excep.
308ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite
309ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r9, [r0, #offMethod_clazz]      @ r9<- method->clazz
310ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)]
311ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)]
312ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     rPC, [r0, #offMethod_insns]     @ rPC<- methodToCall->insns
313ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
314ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
315ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ set up newSaveArea
316ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)]
317ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)]
318ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)]
319ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r8, #0                      @ suspendCount != 0
320ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bxne    r12                         @ bail to the interpreter
321ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
322ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
323ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r2, [rGLUE, #offGlue_self]      @ r2<- glue->self
324ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
325ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Update "glue" values for the new method
326ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r0, [rGLUE, #offGlue_method]    @ glue->method = methodToCall
327ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ...
328ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     rFP, r1                         @ fp = newFp
329ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rFP, [r2, #offThread_curFrame]  @ self->curFrame = newFp
330ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
331ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      lr                              @ return to the callee-chaining cell
332ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
333ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
334ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
335ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
336ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
33738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    .global dvmCompiler_TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN
33838329f5678fd7a4879528b02a0ab60322d38a897Ben ChengdvmCompiler_TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN:
33938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng/* File: armv5te/TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN.S */
34038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    /*
34138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * For polymorphic callsite, check whether the cached class pointer matches
34238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * the current one. If so setup the Dalvik frame and return to the
34338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * Thumb code through the link register to transfer control to the callee
34438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * method through a dedicated chaining cell.
34538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *
34689efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee     * The predicted chaining cell is declared in ArmLIR.h with the
34738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * following layout:
34838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *
34938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *  typedef struct PredictedChainingCell {
35038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *      u4 branch;
35138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *      const ClassObject *clazz;
35238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *      const Method *method;
35338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *      u4 counter;
35438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *  } PredictedChainingCell;
35538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *
35638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * Upon returning to the callsite:
35738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *    - lr  : to branch to the chaining cell
35838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *    - lr+2: to punt to the interpreter
35938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *    - lr+4: to fully resolve the callee and may rechain.
36038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *            r3 <- class
36138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *            r9 <- counter
36238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     */
36338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ r0 = this, r1 = returnCell, r2 = predictedChainCell, rPC = dalvikCallsite
36438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r3, [r0, #offObject_clazz]  @ r3 <- this->class
36538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r8, [r2, #4]    @ r8 <- predictedChainCell->clazz
36638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r0, [r2, #8]    @ r0 <- predictedChainCell->method
36738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r9, [r2, #12]   @ r9 <- predictedChainCell->counter
36838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    cmp     r3, r8          @ predicted class == actual class?
36938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    beq     .LinvokeChain   @ predicted chain is valid
37038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r7, [r3, #offClassObject_vtable] @ r7 <- this->class->vtable
37138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    sub     r1, r9, #1      @ count--
37238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     r1, [r2, #12]   @ write back to PredictedChainingCell->counter
37338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    add     lr, lr, #4      @ return to fully-resolve landing pad
37438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    /*
37538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * r1 <- count
37638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * r2 <- &predictedChainCell
37738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * r3 <- this->class
37838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * r4 <- dPC
37938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * r7 <- this->class->vtable
38038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     */
38138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    bx      lr
38238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
38338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng/* ------------------------------ */
38438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    .balign 4
38538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    .global dvmCompiler_TEMPLATE_INVOKE_METHOD_NATIVE
38638329f5678fd7a4879528b02a0ab60322d38a897Ben ChengdvmCompiler_TEMPLATE_INVOKE_METHOD_NATIVE:
38738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng/* File: armv5te/TEMPLATE_INVOKE_METHOD_NATIVE.S */
38838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite
38938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldrh    r7, [r0, #offMethod_registersSize]  @ r7<- methodToCall->regsSize
39038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r9, [rGLUE, #offGlue_interpStackEnd]    @ r9<- interpStackEnd
39138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
39238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    add     r3, r1, #1  @ Thumb addr is odd
39338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
39438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    sub     r1, r1, r7, lsl #2          @ r1<- newFp (old savearea - regsSize)
39538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    SAVEAREA_FROM_FP(r10, r1)           @ r10<- stack save area
39638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r8, [r8]                    @ r3<- suspendCount (int)
39738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    cmp     r10, r9                     @ bottom < interpStackEnd?
39838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    bxlt    lr                          @ return to raise stack overflow excep.
39938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite
40038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)]
40138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)]
40238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     rPC, [r0, #offMethod_insns]     @ rPC<- methodToCall->insns
40338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
40438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
40538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ set up newSaveArea
40638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)]
40738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)]
40838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r3, [rGLUE, #offGlue_self]      @ r3<- glue->self
40938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)]
41038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    cmp     r8, #0                      @ suspendCount != 0
41138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r8, [r0, #offMethod_nativeFunc] @ r8<- method->nativeFunc
41297319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#if !defined(WITH_SELF_VERIFICATION)
41338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    bxne    lr                          @ bail to the interpreter
41497319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#else
41597319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao    bx      lr                          @ bail to interpreter unconditionally
41697319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#endif
41738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
41838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ go ahead and transfer control to the native code
419d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden    ldr     r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->...
42038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     r1, [r3, #offThread_curFrame]   @ self->curFrame = newFp
421d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden    str     r9, [r1, #(offStackSaveArea_localRefCookie - sizeofStackSaveArea)]
422d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden                                        @ newFp->localRefCookie=top
42338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    mov     r9, r3                      @ r9<- glue->self (preserve)
42438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    SAVEAREA_FROM_FP(r10, r1)           @ r10<- new stack save area
42538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
42638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    mov     r2, r0                      @ r2<- methodToCall
42738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    mov     r0, r1                      @ r0<- newFP
42838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    add     r1, rGLUE, #offGlue_retval  @ r1<- &retval
42938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
43038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    blx     r8                          @ off to the native code
43138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
43238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ native return; r9=self, r10=newSaveArea
43338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ equivalent to dvmPopJniLocals
43438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r2, [r10, #offStackSaveArea_returnAddr] @ r2 = chaining cell ret
435d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden    ldr     r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved->top
43638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r1, [r9, #offThread_exception] @ check for exception
43738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     rFP, [r9, #offThread_curFrame]  @ self->curFrame = fp
43838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    cmp     r1, #0                      @ null?
439d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden    str     r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top
44038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    bne     .LhandleException             @ no, handle exception
44138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    bx      r2
44238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
44338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
44438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng/* ------------------------------ */
44538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    .balign 4
446ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_CMPG_DOUBLE
447ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_CMPG_DOUBLE:
448ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_CMPG_DOUBLE.S */
449ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_CMPL_DOUBLE.S */
450ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
4511465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * For the JIT: incoming arguments in r0-r1, r2-r3
452ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *              result in r0
453ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
454ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Compare two floating-point values.  Puts 0, 1, or -1 into the
455ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * destination register based on the results of the comparison.
456ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
457ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
458ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * on what value we'd like to return when one of the operands is NaN.
459ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
460ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * See OP_CMPL_FLOAT for an explanation.
461ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
462ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For: cmpl-double, cmpg-double
463ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
464ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* op vAA, vBB, vCC */
4651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    push    {r0-r3}                     @ save operands
4661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    mov     r11, lr                     @ save return address
467ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cdcmple"       @ PIC way of "bl __aeabi_cdcmple"
468ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bhi     .LTEMPLATE_CMPG_DOUBLE_gt_or_nan       @ C set and Z clear, disambiguate
469ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mvncc   r0, #0                      @ (less than) r1<- -1
470ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    moveq   r0, #0                      @ (equal) r1<- 0, trumps less than
4711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    add     sp, #16                     @ drop unused operands
4721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bx      r11
473ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
474ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Test for NaN with a second comparison.  EABI forbids testing bit
475ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
476ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ make the library call.
477ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LTEMPLATE_CMPG_DOUBLE_gt_or_nan:
4781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    pop     {r2-r3}                     @ restore operands in reverse order
4791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    pop     {r0-r1}                     @ restore operands in reverse order
480ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cdcmple"       @ r0<- Z set if eq, C clear if <
481ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movcc   r0, #1                      @ (greater than) r1<- 1
4821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bxcc    r11
483ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, #1                            @ r1<- 1 or -1 for NaN
4841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bx      r11
485ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
486ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
487ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
488ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
489ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
490ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_CMPL_DOUBLE
491ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_CMPL_DOUBLE:
492ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_CMPL_DOUBLE.S */
493ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
4941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * For the JIT: incoming arguments in r0-r1, r2-r3
495ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *              result in r0
496ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
497ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Compare two floating-point values.  Puts 0, 1, or -1 into the
498ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * destination register based on the results of the comparison.
499ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
500ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
501ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * on what value we'd like to return when one of the operands is NaN.
502ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
503ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * See OP_CMPL_FLOAT for an explanation.
504ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
505ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For: cmpl-double, cmpg-double
506ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
507ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* op vAA, vBB, vCC */
5081465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    push    {r0-r3}                     @ save operands
5091465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    mov     r11, lr                     @ save return address
510ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cdcmple"       @ PIC way of "bl __aeabi_cdcmple"
511ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bhi     .LTEMPLATE_CMPL_DOUBLE_gt_or_nan       @ C set and Z clear, disambiguate
512ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mvncc   r0, #0                      @ (less than) r1<- -1
513ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    moveq   r0, #0                      @ (equal) r1<- 0, trumps less than
5141465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    add     sp, #16                     @ drop unused operands
5151465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bx      r11
516ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
517ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Test for NaN with a second comparison.  EABI forbids testing bit
518ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
519ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ make the library call.
520ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LTEMPLATE_CMPL_DOUBLE_gt_or_nan:
5211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    pop     {r2-r3}                     @ restore operands in reverse order
5221465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    pop     {r0-r1}                     @ restore operands in reverse order
523ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cdcmple"       @ r0<- Z set if eq, C clear if <
524ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movcc   r0, #1                      @ (greater than) r1<- 1
5251465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bxcc    r11
526ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mvn     r0, #0                            @ r1<- 1 or -1 for NaN
5271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bx      r11
528ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
529ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
530ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
531ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
532ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_CMPG_FLOAT
533ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_CMPG_FLOAT:
534ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_CMPG_FLOAT.S */
535ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_CMPL_FLOAT.S */
536ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
5371465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * For the JIT: incoming arguments in r0-r1, r2-r3
538ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *              result in r0
539ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
540ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Compare two floating-point values.  Puts 0, 1, or -1 into the
541ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * destination register based on the results of the comparison.
542ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
543ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
544ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * on what value we'd like to return when one of the operands is NaN.
545ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
546ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * The operation we're implementing is:
547ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   if (x == y)
548ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return 0;
549ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   else if (x < y)
550ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return -1;
551ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   else if (x > y)
552ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return 1;
553ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   else
554ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return {-1,1};  // one or both operands was NaN
555ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
556ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * The straightforward implementation requires 3 calls to functions
557ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * that return a result in r0.  We can do it with two calls if our
558ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * EABI library supports __aeabi_cfcmple (only one if we want to check
559ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * for NaN directly):
560ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   check x <= y
561ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     if <, return -1
562ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     if ==, return 0
563ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   check y <= x
564ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     if <, return 1
565ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   return {-1,1}
566ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
567ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * for: cmpl-float, cmpg-float
568ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
569ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* op vAA, vBB, vCC */
570ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r9, r0                      @ Save copies - we may need to redo
571ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r10, r1
5721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    mov     r11, lr                     @ save return address
573ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cfcmple"       @ cmp <=: C clear if <, Z set if eq
574ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bhi     .LTEMPLATE_CMPG_FLOAT_gt_or_nan       @ C set and Z clear, disambiguate
575ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mvncc   r0, #0                      @ (less than) r0<- -1
576ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    moveq   r0, #0                      @ (equal) r0<- 0, trumps less than
5771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bx      r11
578ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Test for NaN with a second comparison.  EABI forbids testing bit
579ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
580ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ make the library call.
581ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LTEMPLATE_CMPG_FLOAT_gt_or_nan:
5821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    mov     r0, r10                     @ restore in reverse order
5831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    mov     r1, r9
584ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cfcmple"       @ r0<- Z set if eq, C clear if <
585ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movcc   r0, #1                      @ (greater than) r1<- 1
5861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bxcc    r11
587ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, #1                            @ r1<- 1 or -1 for NaN
5881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bx      r11
589ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
590ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
591ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
592ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
593ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
594ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
595ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_CMPL_FLOAT
596ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_CMPL_FLOAT:
597ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_CMPL_FLOAT.S */
598ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
5991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * For the JIT: incoming arguments in r0-r1, r2-r3
600ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *              result in r0
601ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
602ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Compare two floating-point values.  Puts 0, 1, or -1 into the
603ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * destination register based on the results of the comparison.
604ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
605ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
606ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * on what value we'd like to return when one of the operands is NaN.
607ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
608ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * The operation we're implementing is:
609ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   if (x == y)
610ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return 0;
611ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   else if (x < y)
612ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return -1;
613ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   else if (x > y)
614ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return 1;
615ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   else
616ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return {-1,1};  // one or both operands was NaN
617ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
618ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * The straightforward implementation requires 3 calls to functions
619ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * that return a result in r0.  We can do it with two calls if our
620ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * EABI library supports __aeabi_cfcmple (only one if we want to check
621ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * for NaN directly):
622ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   check x <= y
623ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     if <, return -1
624ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     if ==, return 0
625ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   check y <= x
626ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     if <, return 1
627ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   return {-1,1}
628ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
629ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * for: cmpl-float, cmpg-float
630ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
631ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* op vAA, vBB, vCC */
632ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r9, r0                      @ Save copies - we may need to redo
633ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r10, r1
6341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    mov     r11, lr                     @ save return address
635ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cfcmple"       @ cmp <=: C clear if <, Z set if eq
636ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bhi     .LTEMPLATE_CMPL_FLOAT_gt_or_nan       @ C set and Z clear, disambiguate
637ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mvncc   r0, #0                      @ (less than) r0<- -1
638ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    moveq   r0, #0                      @ (equal) r0<- 0, trumps less than
6391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bx      r11
640ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Test for NaN with a second comparison.  EABI forbids testing bit
641ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
642ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ make the library call.
643ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LTEMPLATE_CMPL_FLOAT_gt_or_nan:
6441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    mov     r0, r10                     @ restore in reverse order
6451465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    mov     r1, r9
646ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cfcmple"       @ r0<- Z set if eq, C clear if <
647ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movcc   r0, #1                      @ (greater than) r1<- 1
6481465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bxcc    r11
649ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mvn     r0, #0                            @ r1<- 1 or -1 for NaN
6501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bx      r11
651ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
652ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
653ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
654ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
655ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
656ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_MUL_LONG
657ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_MUL_LONG:
658ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_MUL_LONG.S */
659ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
660ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Signed 64-bit integer multiply.
661ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
662ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For JIT: op1 in r0/r1, op2 in r2/r3, return in r0/r1
663ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
664ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
665ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *        WX
666ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *      x YZ
667ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *  --------
668ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     ZW ZX
669ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *  YW YX
670ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
671ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * The low word of the result holds ZX, the high word holds
672ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
673ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * it doesn't fit in the low 64 bits.
674ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
675ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Unlike most ARM math operations, multiply instructions have
676ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * restrictions on using the same register more than once (Rd and Rm
677ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * cannot be the same).
678ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
679ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* mul-long vAA, vBB, vCC */
680ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mul     ip, r2, r1                  @  ip<- ZxW
681ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
682ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
683ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
684ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0,r9
685ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r1,r10
686ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      lr
687ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
688ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
689ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
690ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_SHL_LONG
691ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_SHL_LONG:
692ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_SHL_LONG.S */
693ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
694ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Long integer shift.  This is different from the generic 32/64-bit
695ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * binary operations because vAA/vBB are 64-bit but vCC (the shift
696ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * distance) is 32-bit.  Also, Dalvik requires us to ignore all but the low
697ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * 6 bits.
698ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
699ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* shl-long vAA, vBB, vCC */
700ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    and     r2, r2, #63                 @ r2<- r2 & 0x3f
701ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r1, r1, asl r2              @  r1<- r1 << r2
702ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    rsb     r3, r2, #32                 @  r3<- 32 - r2
703ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
704ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    subs    ip, r2, #32                 @  ip<- r2 - 32
705ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
706ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, r0, asl r2              @  r0<- r0 << r2
707ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      lr
708ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
709ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
710ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
711ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_SHR_LONG
712ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_SHR_LONG:
713ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_SHR_LONG.S */
714ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
715ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Long integer shift.  This is different from the generic 32/64-bit
716ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * binary operations because vAA/vBB are 64-bit but vCC (the shift
717ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * distance) is 32-bit.  Also, Dalvik requires us to ignore all but the low
718ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * 6 bits.
719ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
720ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* shr-long vAA, vBB, vCC */
721ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    and     r2, r2, #63                 @ r0<- r0 & 0x3f
722ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
723ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    rsb     r3, r2, #32                 @  r3<- 32 - r2
724ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
725ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    subs    ip, r2, #32                 @  ip<- r2 - 32
726ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
727ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r1, r1, asr r2              @  r1<- r1 >> r2
728ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      lr
729ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
730ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
731ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
732ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
733ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_USHR_LONG
734ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_USHR_LONG:
735ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_USHR_LONG.S */
736ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
737ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Long integer shift.  This is different from the generic 32/64-bit
738ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * binary operations because vAA/vBB are 64-bit but vCC (the shift
739ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * distance) is 32-bit.  Also, Dalvik requires us to ignore all but the low
740ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * 6 bits.
741ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
742ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* ushr-long vAA, vBB, vCC */
743ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    and     r2, r2, #63                 @ r0<- r0 & 0x3f
744ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
745ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    rsb     r3, r2, #32                 @  r3<- 32 - r2
746ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
747ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    subs    ip, r2, #32                 @  ip<- r2 - 32
748ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
749ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
750ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      lr
751ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
752ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
7534f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng/* ------------------------------ */
7544f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng    .balign 4
7554f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng    .global dvmCompiler_TEMPLATE_THROW_EXCEPTION_COMMON
7564f48917c0741e4d9b15ca7c45956aea05fea103fBen ChengdvmCompiler_TEMPLATE_THROW_EXCEPTION_COMMON:
7574f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng/* File: armv5te/TEMPLATE_THROW_EXCEPTION_COMMON.S */
7584f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng    /*
7594f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng     * Throw an exception from JIT'ed code.
7604f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng     * On entry:
7614f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng     *    r0    Dalvik PC that raises the exception
7624f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng     */
7634f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng    b       .LhandleException
7644f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng
7651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* ------------------------------ */
7661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    .balign 4
7671465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    .global dvmCompiler_TEMPLATE_SAVE_STATE
7681465db5ee2d3c4c4dcc8e017a294172e858765cbBill BuzbeedvmCompiler_TEMPLATE_SAVE_STATE:
7691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* File: armv5te/TEMPLATE_SAVE_STATE.S */
7701465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    /*
7711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * This handler performs a register save for selfVerification mode.
7721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * On entry:
7731465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     *    Top of stack + 4: r7 value to save
7741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     *    Top of stack + 0: r0 value to save
7751465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     *    r0 - offset from rGLUE to the beginning of the heapArgSpace record
7761465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     *    r7 - the value of regMap
7771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     *
7781465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * The handler must save regMap, r0-r12 and then return with r0-r12
7791465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * with their original values (note that this means r0 and r7 must take
7801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * the values on the stack - not the ones in those registers on entry.
7811465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * Finally, the two registers previously pushed must be popped.
7821465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     */
7831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    add     r0, r0, rGLUE               @ pointer to heapArgSpace
7841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    stmia   r0!, {r7}                   @ save regMap
7851465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ldr     r7, [r13, #0]               @ recover r0 value
7861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    stmia   r0!, {r7}                   @ save r0
7871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ldr     r7, [r13, #4]               @ recover r7 value
7881465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    stmia   r0!, {r1-r12}
7891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    pop     {r0, r7}                    @ recover r0, r7
7901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bx      lr
7911465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
7921465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* ------------------------------ */
7931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    .balign 4
7941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    .global dvmCompiler_TEMPLATE_RESTORE_STATE
7951465db5ee2d3c4c4dcc8e017a294172e858765cbBill BuzbeedvmCompiler_TEMPLATE_RESTORE_STATE:
7961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee/* File: armv5te/TEMPLATE_RESTORE_STATE.S */
7971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    /*
7981465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * This handler restores state following a selfVerification memory access.
7991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     * On entry:
8001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     *    r0 - offset from rGLUE to the 1st element of the coreRegs save array.
8011465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee     */
8021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    add     r0, r0, rGLUE               @ pointer to heapArgSpace.coreRegs[0]
8031465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    ldmia   r0, {r0-r12}
8041465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee    bx      lr
8051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee
806fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee/* ------------------------------ */
807fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    .balign 4
808fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    .global dvmCompiler_TEMPLATE_STRING_COMPARETO
809fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill BuzbeedvmCompiler_TEMPLATE_STRING_COMPARETO:
810fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee/* File: armv5te/TEMPLATE_STRING_COMPARETO.S */
811fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    /*
812fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * String's compareTo.
813fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *
814fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * Requires r0/r1 to have been previously checked for null.  Will
815fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * return negative if this's string is < comp, 0 if they are the
816fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * same and positive if >.
817fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *
818fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * IMPORTANT NOTE:
819fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *
820fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * This code relies on hard-coded offsets for string objects, and must be
821fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * kept in sync with definitions in UtfString.h.  See asm-constants.h
822fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *
823fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * On entry:
824fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *    r0:   this object pointer
825fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *    r1:   comp object pointer
826fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *
827fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     */
828fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
829fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    mov    r2, r0         @ this to r2, opening up r0 for return value
830fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    subs   r0, r2, r1     @ Same?
831fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    bxeq   lr
832fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
833fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldr    r4, [r2, #STRING_FIELDOFF_OFFSET]
834fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldr    r9, [r1, #STRING_FIELDOFF_OFFSET]
835fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldr    r7, [r2, #STRING_FIELDOFF_COUNT]
836fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldr    r10, [r1, #STRING_FIELDOFF_COUNT]
837fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldr    r2, [r2, #STRING_FIELDOFF_VALUE]
838fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldr    r1, [r1, #STRING_FIELDOFF_VALUE]
839fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
840fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    /*
841fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * At this point, we have:
842fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *    value:  r2/r1
843fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *    offset: r4/r9
844fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *    count:  r7/r10
845fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * We're going to compute
846fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *    r11 <- countDiff
847fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *    r10 <- minCount
848fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     */
849fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     subs  r11, r7, r10
850fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     movls r10, r7
851fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
852fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     /* Now, build pointers to the string data */
853fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     add   r2, r2, r4, lsl #1
854fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     add   r1, r1, r9, lsl #1
855fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     /*
856fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      * Note: data pointers point to previous element so we can use pre-index
857fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      * mode with base writeback.
858fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      */
859fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     add   r2, #16-2   @ offset to contents[-1]
860fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     add   r1, #16-2   @ offset to contents[-1]
861fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
862fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     /*
863fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      * At this point we have:
864fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      *   r2: *this string data
865fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      *   r1: *comp string data
866fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      *   r10: iteration count for comparison
867fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      *   r11: value to return if the first part of the string is equal
868fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      *   r0: reserved for result
869fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      *   r3, r4, r7, r8, r9, r12 available for loading string data
870fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      */
871fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
872fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    cmp   r10, #3
873fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    blt   do_remainder
874fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbeeloopback_triple:
875fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldrh  r3, [r2, #2]!
876fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldrh  r4, [r1, #2]!
877fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldrh  r7, [r2, #2]!
878fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldrh  r8, [r1, #2]!
879fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldrh  r9, [r2, #2]!
880fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldrh  r12,[r1, #2]!
881fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    subs  r0, r3, r4
882fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    subeqs  r0, r7, r8
883fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    subeqs  r0, r9, r12
884fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    bxne  lr
885fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    subs  r10, #3
886fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    bgt   loopback_triple
887fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
888fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbeedo_remainder:
889fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    cmp   r10, #0
890fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    beq   returnDiff
891fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
892fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbeeloopback_single:
893fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldrh  r3, [r2, #2]!
894fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldrh  r4, [r1, #2]!
895fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    subs  r0, r3, r4
896fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    bxne  lr
897fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    subs  r10, #1
898fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    bne     loopback_single
899fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
900fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill BuzbeereturnDiff:
901fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    mov   r0, r11
902fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    bx    lr
903fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
904fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
905fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee/* ------------------------------ */
906fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    .balign 4
907fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    .global dvmCompiler_TEMPLATE_STRING_INDEXOF
908fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill BuzbeedvmCompiler_TEMPLATE_STRING_INDEXOF:
909fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee/* File: armv5te/TEMPLATE_STRING_INDEXOF.S */
910fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    /*
911fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * String's indexOf.
912fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *
913fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * Requires r0 to have been previously checked for null.  Will
914fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * return index of match of r1 in r0.
915fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *
916fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * IMPORTANT NOTE:
917fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *
918fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * This code relies on hard-coded offsets for string objects, and must be
919fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * kept in sync wth definitions in UtfString.h  See asm-constants.h
920fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *
921fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * On entry:
922fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *    r0:   string object pointer
923fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *    r1:   char to match
924fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *    r2:   Starting offset in string data
925fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     */
926fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
927fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldr    r7, [r0, #STRING_FIELDOFF_OFFSET]
928fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldr    r8, [r0, #STRING_FIELDOFF_COUNT]
929fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldr    r0, [r0, #STRING_FIELDOFF_VALUE]
930fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
931fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    /*
932fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     * At this point, we have:
933fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *    value:  r0
934fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *    offset: r7
935fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     *    count:  r8
936fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     */
937fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
938fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     /* Clamp start to [0..count] */
939fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     cmp   r2, #0
940fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     movlt r2, #0
941fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     cmp   r2, r8
942fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     movgt r2, r0
943fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
944fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     /* Fold start & offset, and set data pointer to contents[-1] */
945fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     add   r2, r7
946fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     add   r0, r0, r2, lsl #1
947fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     add   r0, #16-2   @ offset to contents[-1]
948fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     add   r2, r0, #2  @ remember true start of data
949fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
950fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee     /*
951fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      * At this point we have:
952fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      *   r0: *next[-1] char to test
953fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      *   r2: *start
954fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      *   r1: char to compare
955fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      *   r8: max count
956fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      *   r3, r4, r7, r9, r12 available for loading string data
957fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee      */
958fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
959fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    /* Unroll x 4 */
960fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
961fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    cmp   r8, #4
962fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    blt   do_rest
963fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbeeloopback_quad:
964fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldrh  r3, [r0, #2]!
965fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldrh  r4, [r0, #2]!
966fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldrh  r7, [r0, #2]!
967fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldrh  r9, [r0, #2]!
968fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    cmp   r3, r1
969fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    beq   match_0
970fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    cmp   r4, r1
971fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    beq   match_1
972fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    cmp   r7, r1
973fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    beq   match_2
974fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    cmp   r9, r1
975fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    beq   match_3
976fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    subs  r8, #4
977fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    bgt   loopback_quad
978fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
979fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbeedo_rest:
980fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    cmp   r8, #0
981fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    beq   no_match
982fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
983fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbeeloopback_indexof:
984fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    ldrh  r3, [r0, #2]!
985fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    cmp   r3, r1
986fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    beq   match_3
987fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    subs  r8, #1
988fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    bne     loopback_indexof
989fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
990fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbeeno_match:
991fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    mov   r0, #-1
992fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    bx    lr
993fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
994fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbeematch_0:
995fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    sub   r0, #6
996fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    sub   r0, r2
997fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    bx    lr
998fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbeematch_1:
999fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    sub   r0, #4
1000fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    sub   r0, r2
1001fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    bx    lr
1002fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbeematch_2:
1003fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    sub   r0, #2
1004fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    sub   r0, r2
1005fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    bx    lr
1006fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbeematch_3:
1007fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    sub   r0, r2
1008fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee    bx    lr
1009fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
1010fd023aaec5f2b0df61d1702ea2f29a70abe90158Bill Buzbee
1011ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .size   dvmCompilerTemplateStart, .-dvmCompilerTemplateStart
1012ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/footer.S */
1013ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/*
1014ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * ===========================================================================
1015ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *  Common subroutines and data
1016ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * ===========================================================================
1017ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */
1018ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
1019ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .text
1020ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .align  2
1021ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LinvokeNative:
1022ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Prep for the native call
1023ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ r1 = newFP, r0 = methodToCall
1024ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r3, [rGLUE, #offGlue_self]      @ r3<- glue->self
1025d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden    ldr     r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->...
1026ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r1, [r3, #offThread_curFrame]   @ self->curFrame = newFp
1027d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden    str     r9, [r1, #(offStackSaveArea_localRefCookie - sizeofStackSaveArea)]
1028d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden                                        @ newFp->localRefCookie=top
1029ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r9, r3                      @ r9<- glue->self (preserve)
1030ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    SAVEAREA_FROM_FP(r10, r1)           @ r10<- new stack save area
1031ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
1032ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r2, r0                      @ r2<- methodToCall
1033ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, r1                      @ r0<- newFP
1034ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    add     r1, rGLUE, #offGlue_retval  @ r1<- &retval
1035ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
1036ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR "[r2, #offMethod_nativeFunc]"
1037ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
1038ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ native return; r9=self, r10=newSaveArea
1039ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ equivalent to dvmPopJniLocals
1040ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r2, [r10, #offStackSaveArea_returnAddr] @ r2 = chaining cell ret
1041d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden    ldr     r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved->top
1042ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r1, [r9, #offThread_exception] @ check for exception
1043ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rFP, [r9, #offThread_curFrame]  @ self->curFrame = fp
1044ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r1, #0                      @ null?
1045d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden    str     r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top
10464f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng    ldr     r0, [r10, #offStackSaveArea_savedPc] @ reload rPC
1047ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bne     .LhandleException             @ no, handle exception
1048ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      r2
1049ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
10504f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng/*
10514f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng * On entry:
10524f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng * r0  Faulting Dalvik PC
10534f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng */
1054ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LhandleException:
10554f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng    ldr     r1, .LdvmMterpCommonExceptionThrown @ PIC way of getting &func
1056cc6600c2702c0b29457836acde1cfc4f25c63b67Ben Cheng    ldr     rIBASE, .LdvmAsmInstructionStart    @ same as above
10574f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng    mov     rPC, r0                 @ reload the faulting Dalvik address
10584f48917c0741e4d9b15ca7c45956aea05fea103fBen Cheng    mov     pc, r1                  @ branch to dvmMterpCommonExceptionThrown
1059ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
1060ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .align  2
1061ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LdvmAsmInstructionStart:
1062ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .word   dvmAsmInstructionStart
1063ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LdvmJitToInterpNoChain:
1064ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .word   dvmJitToInterpNoChain
1065ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LdvmMterpStdBail:
1066ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .word   dvmMterpStdBail
1067cc6600c2702c0b29457836acde1cfc4f25c63b67Ben Cheng.LdvmMterpCommonExceptionThrown:
1068cc6600c2702c0b29457836acde1cfc4f25c63b67Ben Cheng    .word   dvmMterpCommonExceptionThrown
1069ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.L__aeabi_cdcmple:
1070ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .word   __aeabi_cdcmple
1071ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.L__aeabi_cfcmple:
1072ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .word   __aeabi_cfcmple
1073ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
1074ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dmvCompilerTemplateEnd
1075ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdmvCompilerTemplateEnd:
1076ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
1077ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#endif /* WITH_JIT */
1078ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
1079