CompilerTemplateAsm-armv5te.S revision 97319a8a234e9fe1cf90ca39aa6eca37d729afd5
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
197ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r0, .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
203ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r1, [r10, #offClassObject_pDvmDex] @ r1<- 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)
206ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r1, [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
211ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     pc, r0                      @ callsite is interpreted
212ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng1:
213ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    stmia   rGLUE, {rPC, rFP}           @ SAVE_PC_FP_TO_GLUE()
214ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r2, .LdvmMterpStdBail       @ defined in footer.S
215ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r1, #0                      @ changeInterp = false
216ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, rGLUE                   @ Expecting rGLUE in r0
217ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    blx     r2                          @ exit the interpreter
218ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
219ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
220ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
221ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_INVOKE_METHOD_NO_OPT
222ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_INVOKE_METHOD_NO_OPT:
223ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_INVOKE_METHOD_NO_OPT.S */
224ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
225ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For polymorphic callsites - setup the Dalvik frame and load Dalvik PC
226ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * into rPC then jump to dvmJitToInterpNoChain to dispatch the
227ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * runtime-resolved callee.
228ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
229ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite
230ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldrh    r7, [r0, #offMethod_registersSize]  @ r7<- methodToCall->regsSize
231ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldrh    r2, [r0, #offMethod_outsSize]  @ r2<- methodToCall->outsSize
232ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r9, [rGLUE, #offGlue_interpStackEnd]    @ r9<- interpStackEnd
233ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
234ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    add     r3, r1, #1  @ Thumb addr is odd
235ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
236ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    sub     r1, r1, r7, lsl #2          @ r1<- newFp (old savearea - regsSize)
237ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    SAVEAREA_FROM_FP(r10, r1)           @ r10<- stack save area
238ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    sub     r10, r10, r2, lsl #2        @ r10<- bottom (newsave - outsSize)
239ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r8, [r8]                    @ r3<- suspendCount (int)
240ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r10, r9                     @ bottom < interpStackEnd?
241ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bxlt    lr                          @ return to raise stack overflow excep.
242ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite
243ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r9, [r0, #offMethod_clazz]      @ r9<- method->clazz
244ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r10, [r0, #offMethod_accessFlags] @ r10<- methodToCall->accessFlags
245ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)]
246ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)]
247ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     rPC, [r0, #offMethod_insns]     @ rPC<- methodToCall->insns
248ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
249ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
250ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ set up newSaveArea
251ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)]
252ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)]
253ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)]
254ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r8, #0                      @ suspendCount != 0
255ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bxne    lr                          @ bail to the interpreter
256ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    tst     r10, #ACC_NATIVE
25797319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#if !defined(WITH_SELF_VERIFICATION)
258ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bne     .LinvokeNative
25997319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#else
26097319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao    bxne    lr                          @ bail to the interpreter
26197319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#endif
262ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
263ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r10, .LdvmJitToInterpNoChain
264ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
265ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r2, [rGLUE, #offGlue_self]      @ r2<- glue->self
266ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
267ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Update "glue" values for the new method
268ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r0, [rGLUE, #offGlue_method]    @ glue->method = methodToCall
269ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ...
270ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     rFP, r1                         @ fp = newFp
271ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rFP, [r2, #offThread_curFrame]  @ self->curFrame = newFp
272ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
273ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Start executing the callee
274ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     pc, r10                         @ dvmJitToInterpNoChain
275ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
276ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
277ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
278ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_INVOKE_METHOD_CHAIN
279ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_INVOKE_METHOD_CHAIN:
280ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_INVOKE_METHOD_CHAIN.S */
281ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
282ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For monomorphic callsite, setup the Dalvik frame and return to the
283ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Thumb code through the link register to transfer control to the callee
284ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * method through a dedicated chaining cell.
285ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
286ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite
28738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ methodToCall is guaranteed to be non-native
28838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng.LinvokeChain:
289ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldrh    r7, [r0, #offMethod_registersSize]  @ r7<- methodToCall->regsSize
290ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldrh    r2, [r0, #offMethod_outsSize]  @ r2<- methodToCall->outsSize
291ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r9, [rGLUE, #offGlue_interpStackEnd]    @ r9<- interpStackEnd
292ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
293ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    add     r3, r1, #1  @ Thumb addr is odd
294ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
295ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    sub     r1, r1, r7, lsl #2          @ r1<- newFp (old savearea - regsSize)
296ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    SAVEAREA_FROM_FP(r10, r1)           @ r10<- stack save area
297ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    add     r12, lr, #2                 @ setup the punt-to-interp address
298ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    sub     r10, r10, r2, lsl #2        @ r10<- bottom (newsave - outsSize)
299ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r8, [r8]                    @ r3<- suspendCount (int)
300ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r10, r9                     @ bottom < interpStackEnd?
301ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bxlt    r12                         @ return to raise stack overflow excep.
302ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite
303ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r9, [r0, #offMethod_clazz]      @ r9<- method->clazz
304ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)]
305ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)]
306ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     rPC, [r0, #offMethod_insns]     @ rPC<- methodToCall->insns
307ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
308ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
309ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ set up newSaveArea
310ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)]
311ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)]
312ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)]
313ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r8, #0                      @ suspendCount != 0
314ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bxne    r12                         @ bail to the interpreter
315ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
316ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
317ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r2, [rGLUE, #offGlue_self]      @ r2<- glue->self
318ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
319ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Update "glue" values for the new method
320ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r0, [rGLUE, #offGlue_method]    @ glue->method = methodToCall
321ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ...
322ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     rFP, r1                         @ fp = newFp
323ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rFP, [r2, #offThread_curFrame]  @ self->curFrame = newFp
324ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
325ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      lr                              @ return to the callee-chaining cell
326ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
327ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
328ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
329ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
330ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
33138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    .global dvmCompiler_TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN
33238329f5678fd7a4879528b02a0ab60322d38a897Ben ChengdvmCompiler_TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN:
33338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng/* File: armv5te/TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN.S */
33438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    /*
33538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * For polymorphic callsite, check whether the cached class pointer matches
33638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * the current one. If so setup the Dalvik frame and return to the
33738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * Thumb code through the link register to transfer control to the callee
33838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * method through a dedicated chaining cell.
33938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *
34089efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee     * The predicted chaining cell is declared in ArmLIR.h with the
34138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * following layout:
34238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *
34338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *  typedef struct PredictedChainingCell {
34438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *      u4 branch;
34538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *      const ClassObject *clazz;
34638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *      const Method *method;
34738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *      u4 counter;
34838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *  } PredictedChainingCell;
34938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *
35038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * Upon returning to the callsite:
35138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *    - lr  : to branch to the chaining cell
35238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *    - lr+2: to punt to the interpreter
35338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *    - lr+4: to fully resolve the callee and may rechain.
35438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *            r3 <- class
35538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     *            r9 <- counter
35638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     */
35738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ r0 = this, r1 = returnCell, r2 = predictedChainCell, rPC = dalvikCallsite
35838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r3, [r0, #offObject_clazz]  @ r3 <- this->class
35938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r8, [r2, #4]    @ r8 <- predictedChainCell->clazz
36038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r0, [r2, #8]    @ r0 <- predictedChainCell->method
36138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r9, [r2, #12]   @ r9 <- predictedChainCell->counter
36238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    cmp     r3, r8          @ predicted class == actual class?
36338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    beq     .LinvokeChain   @ predicted chain is valid
36438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r7, [r3, #offClassObject_vtable] @ r7 <- this->class->vtable
36538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    sub     r1, r9, #1      @ count--
36638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     r1, [r2, #12]   @ write back to PredictedChainingCell->counter
36738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    add     lr, lr, #4      @ return to fully-resolve landing pad
36838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    /*
36938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * r1 <- count
37038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * r2 <- &predictedChainCell
37138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * r3 <- this->class
37238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * r4 <- dPC
37338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     * r7 <- this->class->vtable
37438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng     */
37538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    bx      lr
37638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
37738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng/* ------------------------------ */
37838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    .balign 4
37938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    .global dvmCompiler_TEMPLATE_INVOKE_METHOD_NATIVE
38038329f5678fd7a4879528b02a0ab60322d38a897Ben ChengdvmCompiler_TEMPLATE_INVOKE_METHOD_NATIVE:
38138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng/* File: armv5te/TEMPLATE_INVOKE_METHOD_NATIVE.S */
38238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite
38338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldrh    r7, [r0, #offMethod_registersSize]  @ r7<- methodToCall->regsSize
38438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r9, [rGLUE, #offGlue_interpStackEnd]    @ r9<- interpStackEnd
38538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount
38638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    add     r3, r1, #1  @ Thumb addr is odd
38738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
38838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    sub     r1, r1, r7, lsl #2          @ r1<- newFp (old savearea - regsSize)
38938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    SAVEAREA_FROM_FP(r10, r1)           @ r10<- stack save area
39038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r8, [r8]                    @ r3<- suspendCount (int)
39138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    cmp     r10, r9                     @ bottom < interpStackEnd?
39238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    bxlt    lr                          @ return to raise stack overflow excep.
39338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite
39438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)]
39538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)]
39638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     rPC, [r0, #offMethod_insns]     @ rPC<- methodToCall->insns
39738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
39838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
39938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ set up newSaveArea
40038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)]
40138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)]
40238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r3, [rGLUE, #offGlue_self]      @ r3<- glue->self
40338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)]
40438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    cmp     r8, #0                      @ suspendCount != 0
40538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r8, [r0, #offMethod_nativeFunc] @ r8<- method->nativeFunc
40697319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#if !defined(WITH_SELF_VERIFICATION)
40738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    bxne    lr                          @ bail to the interpreter
40897319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#else
40997319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao    bx      lr                          @ bail to interpreter unconditionally
41097319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao#endif
41138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
41238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ go ahead and transfer control to the native code
41338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r9, [r3, #offThread_jniLocal_nextEntry] @ r9<- thread->refNext
41438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     r1, [r3, #offThread_curFrame]   @ self->curFrame = newFp
41538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     r9, [r1, #(offStackSaveArea_localRefTop - sizeofStackSaveArea)]
41638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng                                        @ newFp->localRefTop=refNext
41738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    mov     r9, r3                      @ r9<- glue->self (preserve)
41838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    SAVEAREA_FROM_FP(r10, r1)           @ r10<- new stack save area
41938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
42038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    mov     r2, r0                      @ r2<- methodToCall
42138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    mov     r0, r1                      @ r0<- newFP
42238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    add     r1, rGLUE, #offGlue_retval  @ r1<- &retval
42338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
42438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    blx     r8                          @ off to the native code
42538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
42638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ native return; r9=self, r10=newSaveArea
42738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    @ equivalent to dvmPopJniLocals
42838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r2, [r10, #offStackSaveArea_returnAddr] @ r2 = chaining cell ret
42938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r0, [r10, #offStackSaveArea_localRefTop] @ r0<- newSave->localRefTop
43038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    ldr     r1, [r9, #offThread_exception] @ check for exception
43138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     rFP, [r9, #offThread_curFrame]  @ self->curFrame = fp
43238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    cmp     r1, #0                      @ null?
43338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    str     r0, [r9, #offThread_jniLocal_nextEntry] @ self->refNext<- r0
43438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    bne     .LhandleException             @ no, handle exception
43538329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    bx      r2
43638329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
43738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng
43838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng/* ------------------------------ */
43938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng    .balign 4
440ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_CMPG_DOUBLE
441ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_CMPG_DOUBLE:
442ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_CMPG_DOUBLE.S */
443ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_CMPL_DOUBLE.S */
444ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
445ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For the JIT: incoming arguments are pointers to the arguments in r0/r1
446ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *              result in r0
447ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
448ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Compare two floating-point values.  Puts 0, 1, or -1 into the
449ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * destination register based on the results of the comparison.
450ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
451ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
452ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * on what value we'd like to return when one of the operands is NaN.
453ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
454ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * See OP_CMPL_FLOAT for an explanation.
455ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
456ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For: cmpl-double, cmpg-double
457ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
458ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* op vAA, vBB, vCC */
459ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r4, lr                      @ save return address
460ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r9, r0                      @ save copy of &arg1
461ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r10, r1                     @ save copy of &arg2
462ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldmia   r9, {r0-r1}                 @ r0/r1<- vBB/vBB+1
463ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldmia   r10, {r2-r3}                @ r2/r3<- vCC/vCC+1
464ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cdcmple"       @ PIC way of "bl __aeabi_cdcmple"
465ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bhi     .LTEMPLATE_CMPG_DOUBLE_gt_or_nan       @ C set and Z clear, disambiguate
466ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mvncc   r0, #0                      @ (less than) r1<- -1
467ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    moveq   r0, #0                      @ (equal) r1<- 0, trumps less than
468ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      r4
469ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
470ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Test for NaN with a second comparison.  EABI forbids testing bit
471ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
472ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ make the library call.
473ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LTEMPLATE_CMPG_DOUBLE_gt_or_nan:
474ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldmia   r10, {r0-r1}                @ reverse order
475ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldmia   r9, {r2-r3}
476ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cdcmple"       @ r0<- Z set if eq, C clear if <
477ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movcc   r0, #1                      @ (greater than) r1<- 1
478ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bxcc    r4
479ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, #1                            @ r1<- 1 or -1 for NaN
480ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      r4
481ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
482ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
483ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
484ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
485ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
486ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_CMPL_DOUBLE
487ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_CMPL_DOUBLE:
488ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_CMPL_DOUBLE.S */
489ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
490ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For the JIT: incoming arguments are pointers to the arguments in r0/r1
491ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *              result in r0
492ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
493ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Compare two floating-point values.  Puts 0, 1, or -1 into the
494ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * destination register based on the results of the comparison.
495ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
496ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
497ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * on what value we'd like to return when one of the operands is NaN.
498ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
499ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * See OP_CMPL_FLOAT for an explanation.
500ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
501ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For: cmpl-double, cmpg-double
502ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
503ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* op vAA, vBB, vCC */
504ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r4, lr                      @ save return address
505ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r9, r0                      @ save copy of &arg1
506ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r10, r1                     @ save copy of &arg2
507ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldmia   r9, {r0-r1}                 @ r0/r1<- vBB/vBB+1
508ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldmia   r10, {r2-r3}                @ r2/r3<- vCC/vCC+1
509ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cdcmple"       @ PIC way of "bl __aeabi_cdcmple"
510ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bhi     .LTEMPLATE_CMPL_DOUBLE_gt_or_nan       @ C set and Z clear, disambiguate
511ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mvncc   r0, #0                      @ (less than) r1<- -1
512ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    moveq   r0, #0                      @ (equal) r1<- 0, trumps less than
513ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      r4
514ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
515ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Test for NaN with a second comparison.  EABI forbids testing bit
516ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
517ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ make the library call.
518ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LTEMPLATE_CMPL_DOUBLE_gt_or_nan:
519ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldmia   r10, {r0-r1}                @ reverse order
520ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldmia   r9, {r2-r3}
521ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cdcmple"       @ r0<- Z set if eq, C clear if <
522ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movcc   r0, #1                      @ (greater than) r1<- 1
523ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bxcc    r4
524ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mvn     r0, #0                            @ r1<- 1 or -1 for NaN
525ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      r4
526ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
527ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
528ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
529ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
530ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_CMPG_FLOAT
531ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_CMPG_FLOAT:
532ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_CMPG_FLOAT.S */
533ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_CMPL_FLOAT.S */
534ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
535ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For the JIT: incoming arguments in r0, r1
536ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *              result in r0
537ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
538ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Compare two floating-point values.  Puts 0, 1, or -1 into the
539ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * destination register based on the results of the comparison.
540ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
541ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
542ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * on what value we'd like to return when one of the operands is NaN.
543ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
544ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * The operation we're implementing is:
545ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   if (x == y)
546ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return 0;
547ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   else if (x < y)
548ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return -1;
549ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   else if (x > y)
550ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return 1;
551ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   else
552ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return {-1,1};  // one or both operands was NaN
553ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
554ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * The straightforward implementation requires 3 calls to functions
555ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * that return a result in r0.  We can do it with two calls if our
556ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * EABI library supports __aeabi_cfcmple (only one if we want to check
557ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * for NaN directly):
558ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   check x <= y
559ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     if <, return -1
560ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     if ==, return 0
561ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   check y <= x
562ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     if <, return 1
563ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   return {-1,1}
564ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
565ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * for: cmpl-float, cmpg-float
566ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
567ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* op vAA, vBB, vCC */
568ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r4, lr                      @ save return address
569ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r9, r0                      @ Save copies - we may need to redo
570ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r10, r1
571ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cfcmple"       @ cmp <=: C clear if <, Z set if eq
572ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bhi     .LTEMPLATE_CMPG_FLOAT_gt_or_nan       @ C set and Z clear, disambiguate
573ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mvncc   r0, #0                      @ (less than) r0<- -1
574ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    moveq   r0, #0                      @ (equal) r0<- 0, trumps less than
575ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      r4
576ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Test for NaN with a second comparison.  EABI forbids testing bit
577ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
578ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ make the library call.
579ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LTEMPLATE_CMPG_FLOAT_gt_or_nan:
580ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r1, r9                      @ reverse order
581ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, r10
582ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cfcmple"       @ r0<- Z set if eq, C clear if <
583ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movcc   r0, #1                      @ (greater than) r1<- 1
584ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bxcc    r4
585ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, #1                            @ r1<- 1 or -1 for NaN
586ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      r4
587ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
588ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
589ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
590ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
591ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
592ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
593ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_CMPL_FLOAT
594ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_CMPL_FLOAT:
595ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_CMPL_FLOAT.S */
596ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
597ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For the JIT: incoming arguments in r0, r1
598ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *              result in r0
599ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
600ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Compare two floating-point values.  Puts 0, 1, or -1 into the
601ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * destination register based on the results of the comparison.
602ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
603ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
604ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * on what value we'd like to return when one of the operands is NaN.
605ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
606ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * The operation we're implementing is:
607ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   if (x == y)
608ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return 0;
609ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   else if (x < y)
610ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return -1;
611ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   else if (x > y)
612ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return 1;
613ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   else
614ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     return {-1,1};  // one or both operands was NaN
615ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
616ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * The straightforward implementation requires 3 calls to functions
617ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * that return a result in r0.  We can do it with two calls if our
618ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * EABI library supports __aeabi_cfcmple (only one if we want to check
619ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * for NaN directly):
620ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   check x <= y
621ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     if <, return -1
622ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     if ==, return 0
623ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   check y <= x
624ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     if <, return 1
625ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *   return {-1,1}
626ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
627ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * for: cmpl-float, cmpg-float
628ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
629ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* op vAA, vBB, vCC */
630ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r4, lr                      @ save return address
631ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r9, r0                      @ Save copies - we may need to redo
632ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r10, r1
633ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cfcmple"       @ cmp <=: C clear if <, Z set if eq
634ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bhi     .LTEMPLATE_CMPL_FLOAT_gt_or_nan       @ C set and Z clear, disambiguate
635ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mvncc   r0, #0                      @ (less than) r0<- -1
636ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    moveq   r0, #0                      @ (equal) r0<- 0, trumps less than
637ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      r4
638ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Test for NaN with a second comparison.  EABI forbids testing bit
639ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
640ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ make the library call.
641ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LTEMPLATE_CMPL_FLOAT_gt_or_nan:
642ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r1, r9                      @ reverse order
643ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, r10
644ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR ".L__aeabi_cfcmple"       @ r0<- Z set if eq, C clear if <
645ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movcc   r0, #1                      @ (greater than) r1<- 1
646ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bxcc    r4
647ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mvn     r0, #0                            @ r1<- 1 or -1 for NaN
648ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      r4
649ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
650ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
651ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
652ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
653ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
654ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_MUL_LONG
655ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_MUL_LONG:
656ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_MUL_LONG.S */
657ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
658ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Signed 64-bit integer multiply.
659ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
660ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * For JIT: op1 in r0/r1, op2 in r2/r3, return in r0/r1
661ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
662ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
663ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *        WX
664ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *      x YZ
665ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *  --------
666ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *     ZW ZX
667ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *  YW YX
668ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
669ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * The low word of the result holds ZX, the high word holds
670ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
671ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * it doesn't fit in the low 64 bits.
672ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     *
673ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Unlike most ARM math operations, multiply instructions have
674ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * restrictions on using the same register more than once (Rd and Rm
675ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * cannot be the same).
676ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
677ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* mul-long vAA, vBB, vCC */
678ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mul     ip, r2, r1                  @  ip<- ZxW
679ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
680ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
681ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
682ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0,r9
683ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r1,r10
684ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      lr
685ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
686ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
687ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
688ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_SHL_LONG
689ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_SHL_LONG:
690ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_SHL_LONG.S */
691ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
692ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Long integer shift.  This is different from the generic 32/64-bit
693ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * binary operations because vAA/vBB are 64-bit but vCC (the shift
694ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * distance) is 32-bit.  Also, Dalvik requires us to ignore all but the low
695ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * 6 bits.
696ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
697ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* shl-long vAA, vBB, vCC */
698ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    and     r2, r2, #63                 @ r2<- r2 & 0x3f
699ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r1, r1, asl r2              @  r1<- r1 << r2
700ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    rsb     r3, r2, #32                 @  r3<- 32 - r2
701ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
702ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    subs    ip, r2, #32                 @  ip<- r2 - 32
703ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
704ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, r0, asl r2              @  r0<- r0 << r2
705ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      lr
706ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
707ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
708ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
709ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_SHR_LONG
710ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_SHR_LONG:
711ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_SHR_LONG.S */
712ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
713ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Long integer shift.  This is different from the generic 32/64-bit
714ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * binary operations because vAA/vBB are 64-bit but vCC (the shift
715ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * distance) is 32-bit.  Also, Dalvik requires us to ignore all but the low
716ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * 6 bits.
717ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
718ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* shr-long vAA, vBB, vCC */
719ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    and     r2, r2, #63                 @ r0<- r0 & 0x3f
720ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
721ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    rsb     r3, r2, #32                 @  r3<- 32 - r2
722ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
723ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    subs    ip, r2, #32                 @  ip<- r2 - 32
724ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
725ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r1, r1, asr r2              @  r1<- r1 >> r2
726ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      lr
727ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
728ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
729ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* ------------------------------ */
730ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .balign 4
731ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dvmCompiler_TEMPLATE_USHR_LONG
732ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdvmCompiler_TEMPLATE_USHR_LONG:
733ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/TEMPLATE_USHR_LONG.S */
734ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
735ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Long integer shift.  This is different from the generic 32/64-bit
736ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * binary operations because vAA/vBB are 64-bit but vCC (the shift
737ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * distance) is 32-bit.  Also, Dalvik requires us to ignore all but the low
738ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * 6 bits.
739ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
740ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* ushr-long vAA, vBB, vCC */
741ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    and     r2, r2, #63                 @ r0<- r0 & 0x3f
742ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
743ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    rsb     r3, r2, #32                 @  r3<- 32 - r2
744ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
745ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    subs    ip, r2, #32                 @  ip<- r2 - 32
746ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
747ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
748ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      lr
749ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
750ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
751ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .size   dvmCompilerTemplateStart, .-dvmCompilerTemplateStart
752ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* File: armv5te/footer.S */
753ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/*
754ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * ===========================================================================
755ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *  Common subroutines and data
756ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * ===========================================================================
757ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */
758ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
759ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .text
760ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .align  2
761ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LinvokeNative:
762ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ Prep for the native call
763ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ r1 = newFP, r0 = methodToCall
764ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r3, [rGLUE, #offGlue_self]      @ r3<- glue->self
765ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r9, [r3, #offThread_jniLocal_nextEntry] @ r9<- thread->refNext
766ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r1, [r3, #offThread_curFrame]   @ self->curFrame = newFp
767ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r9, [r1, #(offStackSaveArea_localRefTop - sizeofStackSaveArea)]
768ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                                        @ newFp->localRefTop=refNext
769ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r9, r3                      @ r9<- glue->self (preserve)
770ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    SAVEAREA_FROM_FP(r10, r1)           @ r10<- new stack save area
771ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
772ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r2, r0                      @ r2<- methodToCall
773ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    mov     r0, r1                      @ r0<- newFP
774ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    add     r1, rGLUE, #offGlue_retval  @ r1<- &retval
775ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
776ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    LDR_PC_LR "[r2, #offMethod_nativeFunc]"
777ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
778ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ native return; r9=self, r10=newSaveArea
779ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    @ equivalent to dvmPopJniLocals
780ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r2, [r10, #offStackSaveArea_returnAddr] @ r2 = chaining cell ret
781ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r0, [r10, #offStackSaveArea_localRefTop] @ r0<- newSave->localRefTop
782ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     r1, [r9, #offThread_exception] @ check for exception
783ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     rFP, [r9, #offThread_curFrame]  @ self->curFrame = fp
784ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cmp     r1, #0                      @ null?
785ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    str     r0, [r9, #offThread_jniLocal_nextEntry] @ self->refNext<- r0
786ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bne     .LhandleException             @ no, handle exception
787ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    bx      r2
788ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
78938329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng/* NOTE - this path can be exercised if the JIT threshold is set to 5 */
790ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LhandleException:
791cc6600c2702c0b29457836acde1cfc4f25c63b67Ben Cheng    ldr     r0, .LdvmMterpCommonExceptionThrown @ PIC way of getting &func
792cc6600c2702c0b29457836acde1cfc4f25c63b67Ben Cheng    ldr     rIBASE, .LdvmAsmInstructionStart    @ same as above
793ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    ldr     rPC, [r10, #offStackSaveArea_savedPc] @ reload rPC
794cc6600c2702c0b29457836acde1cfc4f25c63b67Ben Cheng    mov     pc, r0                  @ branch to dvmMterpCommonExceptionThrown
795ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
796ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .align  2
797ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LdvmAsmInstructionStart:
798ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .word   dvmAsmInstructionStart
799ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LdvmJitToInterpNoChain:
800ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .word   dvmJitToInterpNoChain
801ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.LdvmMterpStdBail:
802ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .word   dvmMterpStdBail
803cc6600c2702c0b29457836acde1cfc4f25c63b67Ben Cheng.LdvmMterpCommonExceptionThrown:
804cc6600c2702c0b29457836acde1cfc4f25c63b67Ben Cheng    .word   dvmMterpCommonExceptionThrown
805ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.L__aeabi_cdcmple:
806ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .word   __aeabi_cdcmple
807ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng.L__aeabi_cfcmple:
808ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .word   __aeabi_cfcmple
809ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
810ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    .global dmvCompilerTemplateEnd
811ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben ChengdmvCompilerTemplateEnd:
812ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
813ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#endif /* WITH_JIT */
814ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
815