1/* 2 * This file was generated automatically by gen-template.py for 'armv5te'. 3 * 4 * --> DO NOT EDIT <-- 5 */ 6 7/* File: armv5te/header.S */ 8/* 9 * Copyright (C) 2008 The Android Open Source Project 10 * 11 * Licensed under the Apache License, Version 2.0 (the "License"); 12 * you may not use this file except in compliance with the License. 13 * You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, software 18 * distributed under the License is distributed on an "AS IS" BASIS, 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 * See the License for the specific language governing permissions and 21 * limitations under the License. 22 */ 23 24#if defined(WITH_JIT) 25 26/* 27 * ARMv5 definitions and declarations. 28 */ 29 30/* 31ARM EABI general notes: 32 33r0-r3 hold first 4 args to a method; they are not preserved across method calls 34r4-r8 are available for general use 35r9 is given special treatment in some situations, but not for us 36r10 (sl) seems to be generally available 37r11 (fp) is used by gcc (unless -fomit-frame-pointer is set) 38r12 (ip) is scratch -- not preserved across method calls 39r13 (sp) should be managed carefully in case a signal arrives 40r14 (lr) must be preserved 41r15 (pc) can be tinkered with directly 42 43r0 holds returns of <= 4 bytes 44r0-r1 hold returns of 8 bytes, low word in r0 45 46Callee must save/restore r4+ (except r12) if it modifies them. 47 48Stack is "full descending". Only the arguments that don't fit in the first 4 49registers are placed on the stack. "sp" points at the first stacked argument 50(i.e. the 5th arg). 51 52VFP: single-precision results in s0, double-precision results in d0. 53 54In the EABI, "sp" must be 64-bit aligned on entry to a function, and any 5564-bit quantities (long long, double) must be 64-bit aligned. 56*/ 57 58/* 59JIT and ARM notes: 60 61The following registers have fixed assignments: 62 63 reg nick purpose 64 r5 rFP interpreted frame pointer, used for accessing locals and args 65 r6 rGLUE MterpGlue pointer 66 67The following registers have fixed assignments in mterp but are scratch 68registers in compiled code 69 70 reg nick purpose 71 r4 rPC interpreted program counter, used for fetching instructions 72 r7 rINST first 16-bit code unit of current instruction 73 r8 rIBASE interpreted instruction base pointer, used for computed goto 74 75Macros are provided for common operations. Each macro MUST emit only 76one instruction to make instruction-counting easier. They MUST NOT alter 77unspecified registers or condition codes. 78*/ 79 80/* single-purpose registers, given names for clarity */ 81#define rPC r4 82#define rFP r5 83#define rGLUE r6 84#define rINST r7 85#define rIBASE r8 86 87/* 88 * Given a frame pointer, find the stack save area. 89 * 90 * In C this is "((StackSaveArea*)(_fp) -1)". 91 */ 92#define SAVEAREA_FROM_FP(_reg, _fpreg) \ 93 sub _reg, _fpreg, #sizeofStackSaveArea 94 95#define EXPORT_PC() \ 96 str rPC, [rFP, #(-sizeofStackSaveArea + offStackSaveArea_currentPc)] 97 98/* 99 * This is a #include, not a %include, because we want the C pre-processor 100 * to expand the macros into assembler assignment statements. 101 */ 102#include "../../../mterp/common/asm-constants.h" 103 104/* File: armv5te/platform.S */ 105/* 106 * =========================================================================== 107 * CPU-version-specific defines and utility 108 * =========================================================================== 109 */ 110 111/* 112 * Macro for "MOV LR,PC / LDR PC,xxx", which is not allowed pre-ARMv5. 113 * Jump to subroutine. 114 * 115 * May modify IP and LR. 116 */ 117.macro LDR_PC_LR source 118 mov lr, pc 119 ldr pc, \source 120.endm 121 122 123 .global dvmCompilerTemplateStart 124 .type dvmCompilerTemplateStart, %function 125 .text 126 127dvmCompilerTemplateStart: 128 129/* ------------------------------ */ 130 .balign 4 131 .global dvmCompiler_TEMPLATE_CMP_LONG 132dvmCompiler_TEMPLATE_CMP_LONG: 133/* File: armv5te/TEMPLATE_CMP_LONG.S */ 134 /* 135 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 136 * register based on the results of the comparison. 137 * 138 * We load the full values with LDM, but in practice many values could 139 * be resolved by only looking at the high word. This could be made 140 * faster or slower by splitting the LDM into a pair of LDRs. 141 * 142 * If we just wanted to set condition flags, we could do this: 143 * subs ip, r0, r2 144 * sbcs ip, r1, r3 145 * subeqs ip, r0, r2 146 * Leaving { <0, 0, >0 } in ip. However, we have to set it to a specific 147 * integer value, which we can do with 2 conditional mov/mvn instructions 148 * (set 1, set -1; if they're equal we already have 0 in ip), giving 149 * us a constant 5-cycle path plus a branch at the end to the 150 * instruction epilogue code. The multi-compare approach below needs 151 * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch 152 * in the worst case (the 64-bit values are equal). 153 */ 154 /* cmp-long vAA, vBB, vCC */ 155 cmp r1, r3 @ compare (vBB+1, vCC+1) 156 blt .LTEMPLATE_CMP_LONG_less @ signed compare on high part 157 bgt .LTEMPLATE_CMP_LONG_greater 158 subs r0, r0, r2 @ r0<- r0 - r2 159 bxeq lr 160 bhi .LTEMPLATE_CMP_LONG_greater @ unsigned compare on low part 161.LTEMPLATE_CMP_LONG_less: 162 mvn r0, #0 @ r0<- -1 163 bx lr 164.LTEMPLATE_CMP_LONG_greater: 165 mov r0, #1 @ r0<- 1 166 bx lr 167 168/* ------------------------------ */ 169 .balign 4 170 .global dvmCompiler_TEMPLATE_RETURN 171dvmCompiler_TEMPLATE_RETURN: 172/* File: armv5te/TEMPLATE_RETURN.S */ 173 /* 174 * Unwind a frame from the Dalvik stack for compiled OP_RETURN_XXX. 175 * If the stored value in returnAddr 176 * is non-zero, the caller is compiled by the JIT thus return to the 177 * address in the code cache following the invoke instruction. Otherwise 178 * return to the special dvmJitToInterpNoChain entry point. 179 */ 180 SAVEAREA_FROM_FP(r0, rFP) @ r0<- saveArea (old) 181 ldr r10, [r0, #offStackSaveArea_prevFrame] @ r10<- saveArea->prevFrame 182 ldr r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount 183 ldr rPC, [r0, #offStackSaveArea_savedPc] @ rPC<- saveArea->savedPc 184#if !defined(WITH_SELF_VERIFICATION) 185 ldr r9, [r0, #offStackSaveArea_returnAddr] @ r9<- chaining cell ret 186#else 187 mov r9, #0 @ disable chaining 188#endif 189 ldr r2, [r10, #(offStackSaveArea_method - sizeofStackSaveArea)] 190 @ r2<- method we're returning to 191 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self 192 cmp r2, #0 @ break frame? 193#if !defined(WITH_SELF_VERIFICATION) 194 beq 1f @ bail to interpreter 195#else 196 blxeq lr @ punt to interpreter and compare state 197#endif 198 ldr r1, .LdvmJitToInterpNoChainNoProfile @ defined in footer.S 199 mov rFP, r10 @ publish new FP 200 ldrne r10, [r2, #offMethod_clazz] @ r10<- method->clazz 201 ldr r8, [r8] @ r8<- suspendCount 202 203 str r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method 204 ldr r0, [r10, #offClassObject_pDvmDex] @ r0<- method->clazz->pDvmDex 205 str rFP, [r3, #offThread_curFrame] @ self->curFrame = fp 206 add rPC, rPC, #6 @ publish new rPC (advance 6 bytes) 207 str r0, [rGLUE, #offGlue_methodClassDex] 208 cmp r8, #0 @ check the suspendCount 209 movne r9, #0 @ clear the chaining cell address 210 str r9, [r3, #offThread_inJitCodeCache] @ in code cache or not 211 cmp r9, #0 @ chaining cell exists? 212 blxne r9 @ jump to the chaining cell 213#if defined(WITH_JIT_TUNING) 214 mov r0, #kCallsiteInterpreted 215#endif 216 mov pc, r1 @ callsite is interpreted 2171: 218 stmia rGLUE, {rPC, rFP} @ SAVE_PC_FP_TO_GLUE() 219 ldr r2, .LdvmMterpStdBail @ defined in footer.S 220 mov r1, #0 @ changeInterp = false 221 mov r0, rGLUE @ Expecting rGLUE in r0 222 blx r2 @ exit the interpreter 223 224/* ------------------------------ */ 225 .balign 4 226 .global dvmCompiler_TEMPLATE_INVOKE_METHOD_NO_OPT 227dvmCompiler_TEMPLATE_INVOKE_METHOD_NO_OPT: 228/* File: armv5te/TEMPLATE_INVOKE_METHOD_NO_OPT.S */ 229 /* 230 * For polymorphic callsites - setup the Dalvik frame and load Dalvik PC 231 * into rPC then jump to dvmJitToInterpNoChain to dispatch the 232 * runtime-resolved callee. 233 */ 234 @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite 235 ldrh r7, [r0, #offMethod_registersSize] @ r7<- methodToCall->regsSize 236 ldrh r2, [r0, #offMethod_outsSize] @ r2<- methodToCall->outsSize 237 ldr r9, [rGLUE, #offGlue_interpStackEnd] @ r9<- interpStackEnd 238 ldr r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount 239 add r3, r1, #1 @ Thumb addr is odd 240 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area 241 sub r1, r1, r7, lsl #2 @ r1<- newFp (old savearea - regsSize) 242 SAVEAREA_FROM_FP(r10, r1) @ r10<- stack save area 243 sub r10, r10, r2, lsl #2 @ r10<- bottom (newsave - outsSize) 244 ldr r8, [r8] @ r8<- suspendCount (int) 245 cmp r10, r9 @ bottom < interpStackEnd? 246 bxlo lr @ return to raise stack overflow excep. 247 @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite 248 ldr r9, [r0, #offMethod_clazz] @ r9<- method->clazz 249 ldr r10, [r0, #offMethod_accessFlags] @ r10<- methodToCall->accessFlags 250 str rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)] 251 str rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)] 252 ldr rPC, [r0, #offMethod_insns] @ rPC<- methodToCall->insns 253 254 255 @ set up newSaveArea 256 str rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)] 257 str r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)] 258 str r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)] 259 cmp r8, #0 @ suspendCount != 0 260 bxne lr @ bail to the interpreter 261 tst r10, #ACC_NATIVE 262#if !defined(WITH_SELF_VERIFICATION) 263 bne .LinvokeNative 264#else 265 bxne lr @ bail to the interpreter 266#endif 267 268 ldr r10, .LdvmJitToInterpTraceSelectNoChain 269 ldr r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex 270 ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self 271 272 @ Update "glue" values for the new method 273 str r0, [rGLUE, #offGlue_method] @ glue->method = methodToCall 274 str r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ... 275 mov rFP, r1 @ fp = newFp 276 str rFP, [r2, #offThread_curFrame] @ self->curFrame = newFp 277 278 @ Start executing the callee 279#if defined(WITH_JIT_TUNING) 280 mov r0, #kInlineCacheMiss 281#endif 282 mov pc, r10 @ dvmJitToInterpTraceSelectNoChain 283 284/* ------------------------------ */ 285 .balign 4 286 .global dvmCompiler_TEMPLATE_INVOKE_METHOD_CHAIN 287dvmCompiler_TEMPLATE_INVOKE_METHOD_CHAIN: 288/* File: armv5te/TEMPLATE_INVOKE_METHOD_CHAIN.S */ 289 /* 290 * For monomorphic callsite, setup the Dalvik frame and return to the 291 * Thumb code through the link register to transfer control to the callee 292 * method through a dedicated chaining cell. 293 */ 294 @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite 295 @ methodToCall is guaranteed to be non-native 296.LinvokeChain: 297 ldrh r7, [r0, #offMethod_registersSize] @ r7<- methodToCall->regsSize 298 ldrh r2, [r0, #offMethod_outsSize] @ r2<- methodToCall->outsSize 299 ldr r9, [rGLUE, #offGlue_interpStackEnd] @ r9<- interpStackEnd 300 ldr r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount 301 add r3, r1, #1 @ Thumb addr is odd 302 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area 303 sub r1, r1, r7, lsl #2 @ r1<- newFp (old savearea - regsSize) 304 SAVEAREA_FROM_FP(r10, r1) @ r10<- stack save area 305 add r12, lr, #2 @ setup the punt-to-interp address 306 sub r10, r10, r2, lsl #2 @ r10<- bottom (newsave - outsSize) 307 ldr r8, [r8] @ r8<- suspendCount (int) 308 cmp r10, r9 @ bottom < interpStackEnd? 309 bxlo r12 @ return to raise stack overflow excep. 310 @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite 311 ldr r9, [r0, #offMethod_clazz] @ r9<- method->clazz 312 str rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)] 313 str rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)] 314 ldr rPC, [r0, #offMethod_insns] @ rPC<- methodToCall->insns 315 316 317 @ set up newSaveArea 318 str rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)] 319 str r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)] 320 str r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)] 321 cmp r8, #0 @ suspendCount != 0 322 bxne r12 @ bail to the interpreter 323 324 ldr r3, [r9, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex 325 ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self 326 327 @ Update "glue" values for the new method 328 str r0, [rGLUE, #offGlue_method] @ glue->method = methodToCall 329 str r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ... 330 mov rFP, r1 @ fp = newFp 331 str rFP, [r2, #offThread_curFrame] @ self->curFrame = newFp 332 333 bx lr @ return to the callee-chaining cell 334 335/* ------------------------------ */ 336 .balign 4 337 .global dvmCompiler_TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN 338dvmCompiler_TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN: 339/* File: armv5te/TEMPLATE_INVOKE_METHOD_PREDICTED_CHAIN.S */ 340 /* 341 * For polymorphic callsite, check whether the cached class pointer matches 342 * the current one. If so setup the Dalvik frame and return to the 343 * Thumb code through the link register to transfer control to the callee 344 * method through a dedicated chaining cell. 345 * 346 * The predicted chaining cell is declared in ArmLIR.h with the 347 * following layout: 348 * 349 * typedef struct PredictedChainingCell { 350 * u4 branch; 351 * const ClassObject *clazz; 352 * const Method *method; 353 * u4 counter; 354 * } PredictedChainingCell; 355 * 356 * Upon returning to the callsite: 357 * - lr : to branch to the chaining cell 358 * - lr+2: to punt to the interpreter 359 * - lr+4: to fully resolve the callee and may rechain. 360 * r3 <- class 361 * r9 <- counter 362 */ 363 @ r0 = this, r1 = returnCell, r2 = predictedChainCell, rPC = dalvikCallsite 364 ldr r3, [r0, #offObject_clazz] @ r3 <- this->class 365 ldr r8, [r2, #4] @ r8 <- predictedChainCell->clazz 366 ldr r0, [r2, #8] @ r0 <- predictedChainCell->method 367 ldr r9, [rGLUE, #offGlue_icRechainCount] @ r1 <- shared rechainCount 368 cmp r3, r8 @ predicted class == actual class? 369#if defined(WITH_JIT_TUNING) 370 ldr r7, .LdvmICHitCount 371 ldreq r10, [r7, #0] 372 add r10, r10, #1 373 streq r10, [r7, #0] 374#endif 375 beq .LinvokeChain @ predicted chain is valid 376 ldr r7, [r3, #offClassObject_vtable] @ r7 <- this->class->vtable 377 cmp r8, #0 @ initialized class or not 378 moveq r1, #0 379 subne r1, r9, #1 @ count-- 380 strne r1, [rGLUE, #offGlue_icRechainCount] @ write back to InterpState 381 add lr, lr, #4 @ return to fully-resolve landing pad 382 /* 383 * r1 <- count 384 * r2 <- &predictedChainCell 385 * r3 <- this->class 386 * r4 <- dPC 387 * r7 <- this->class->vtable 388 */ 389 bx lr 390 391/* ------------------------------ */ 392 .balign 4 393 .global dvmCompiler_TEMPLATE_INVOKE_METHOD_NATIVE 394dvmCompiler_TEMPLATE_INVOKE_METHOD_NATIVE: 395/* File: armv5te/TEMPLATE_INVOKE_METHOD_NATIVE.S */ 396 @ r0 = methodToCall, r1 = returnCell, rPC = dalvikCallsite 397 ldrh r7, [r0, #offMethod_registersSize] @ r7<- methodToCall->regsSize 398 ldr r9, [rGLUE, #offGlue_interpStackEnd] @ r9<- interpStackEnd 399 ldr r8, [rGLUE, #offGlue_pSelfSuspendCount] @ r8<- &suspendCount 400 add r3, r1, #1 @ Thumb addr is odd 401 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area 402 sub r1, r1, r7, lsl #2 @ r1<- newFp (old savearea - regsSize) 403 SAVEAREA_FROM_FP(r10, r1) @ r10<- stack save area 404 ldr r8, [r8] @ r3<- suspendCount (int) 405 cmp r10, r9 @ bottom < interpStackEnd? 406 bxlo lr @ return to raise stack overflow excep. 407 @ r1 = newFP, r0 = methodToCall, r3 = returnCell, rPC = dalvikCallsite 408 str rPC, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)] 409 str rPC, [r1, #(offStackSaveArea_savedPc - sizeofStackSaveArea)] 410 ldr rPC, [r0, #offMethod_insns] @ rPC<- methodToCall->insns 411 412 413 @ set up newSaveArea 414 str rFP, [r1, #(offStackSaveArea_prevFrame - sizeofStackSaveArea)] 415 str r3, [r1, #(offStackSaveArea_returnAddr - sizeofStackSaveArea)] 416 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self 417 str r0, [r1, #(offStackSaveArea_method - sizeofStackSaveArea)] 418 cmp r8, #0 @ suspendCount != 0 419 ldr r8, [r0, #offMethod_nativeFunc] @ r8<- method->nativeFunc 420#if !defined(WITH_SELF_VERIFICATION) 421 bxne lr @ bail to the interpreter 422#else 423 bx lr @ bail to interpreter unconditionally 424#endif 425 426 @ go ahead and transfer control to the native code 427 ldr r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->... 428 mov r2, #0 429 str r1, [r3, #offThread_curFrame] @ self->curFrame = newFp 430 str r2, [r3, #offThread_inJitCodeCache] @ not in the jit code cache 431 str r9, [r1, #(offStackSaveArea_localRefCookie - sizeofStackSaveArea)] 432 @ newFp->localRefCookie=top 433 mov r9, r3 @ r9<- glue->self (preserve) 434 SAVEAREA_FROM_FP(r10, r1) @ r10<- new stack save area 435 436 mov r2, r0 @ r2<- methodToCall 437 mov r0, r1 @ r0<- newFP 438 add r1, rGLUE, #offGlue_retval @ r1<- &retval 439 440 blx r8 @ off to the native code 441 442 @ native return; r9=self, r10=newSaveArea 443 @ equivalent to dvmPopJniLocals 444 ldr r2, [r10, #offStackSaveArea_returnAddr] @ r2 = chaining cell ret 445 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved->top 446 ldr r1, [r9, #offThread_exception] @ check for exception 447 str rFP, [r9, #offThread_curFrame] @ self->curFrame = fp 448 cmp r1, #0 @ null? 449 str r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top 450 ldr r0, [rFP, #(offStackSaveArea_currentPc - sizeofStackSaveArea)] 451 452 @ r0 = dalvikCallsitePC 453 bne .LhandleException @ no, handle exception 454 455 str r2, [r9, #offThread_inJitCodeCache] @ set the mode properly 456 cmp r2, #0 @ return chaining cell still exists? 457 bxne r2 @ yes - go ahead 458 459 @ continue executing the next instruction through the interpreter 460 ldr r1, .LdvmJitToInterpTraceSelectNoChain @ defined in footer.S 461 add rPC, r0, #6 @ reconstruct new rPC (advance 6 bytes) 462#if defined(WITH_JIT_TUNING) 463 mov r0, #kCallsiteInterpreted 464#endif 465 mov pc, r1 466 467/* ------------------------------ */ 468 .balign 4 469 .global dvmCompiler_TEMPLATE_CMPG_DOUBLE 470dvmCompiler_TEMPLATE_CMPG_DOUBLE: 471/* File: armv5te/TEMPLATE_CMPG_DOUBLE.S */ 472/* File: armv5te/TEMPLATE_CMPL_DOUBLE.S */ 473 /* 474 * For the JIT: incoming arguments in r0-r1, r2-r3 475 * result in r0 476 * 477 * Compare two floating-point values. Puts 0, 1, or -1 into the 478 * destination register based on the results of the comparison. 479 * 480 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending 481 * on what value we'd like to return when one of the operands is NaN. 482 * 483 * See OP_CMPL_FLOAT for an explanation. 484 * 485 * For: cmpl-double, cmpg-double 486 */ 487 /* op vAA, vBB, vCC */ 488 push {r0-r3} @ save operands 489 mov r11, lr @ save return address 490 LDR_PC_LR ".L__aeabi_cdcmple" @ PIC way of "bl __aeabi_cdcmple" 491 bhi .LTEMPLATE_CMPG_DOUBLE_gt_or_nan @ C set and Z clear, disambiguate 492 mvncc r0, #0 @ (less than) r1<- -1 493 moveq r0, #0 @ (equal) r1<- 0, trumps less than 494 add sp, #16 @ drop unused operands 495 bx r11 496 497 @ Test for NaN with a second comparison. EABI forbids testing bit 498 @ patterns, and we can't represent 0x7fc00000 in immediate form, so 499 @ make the library call. 500.LTEMPLATE_CMPG_DOUBLE_gt_or_nan: 501 pop {r2-r3} @ restore operands in reverse order 502 pop {r0-r1} @ restore operands in reverse order 503 LDR_PC_LR ".L__aeabi_cdcmple" @ r0<- Z set if eq, C clear if < 504 movcc r0, #1 @ (greater than) r1<- 1 505 bxcc r11 506 mov r0, #1 @ r1<- 1 or -1 for NaN 507 bx r11 508 509 510/* ------------------------------ */ 511 .balign 4 512 .global dvmCompiler_TEMPLATE_CMPL_DOUBLE 513dvmCompiler_TEMPLATE_CMPL_DOUBLE: 514/* File: armv5te/TEMPLATE_CMPL_DOUBLE.S */ 515 /* 516 * For the JIT: incoming arguments in r0-r1, r2-r3 517 * result in r0 518 * 519 * Compare two floating-point values. Puts 0, 1, or -1 into the 520 * destination register based on the results of the comparison. 521 * 522 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending 523 * on what value we'd like to return when one of the operands is NaN. 524 * 525 * See OP_CMPL_FLOAT for an explanation. 526 * 527 * For: cmpl-double, cmpg-double 528 */ 529 /* op vAA, vBB, vCC */ 530 push {r0-r3} @ save operands 531 mov r11, lr @ save return address 532 LDR_PC_LR ".L__aeabi_cdcmple" @ PIC way of "bl __aeabi_cdcmple" 533 bhi .LTEMPLATE_CMPL_DOUBLE_gt_or_nan @ C set and Z clear, disambiguate 534 mvncc r0, #0 @ (less than) r1<- -1 535 moveq r0, #0 @ (equal) r1<- 0, trumps less than 536 add sp, #16 @ drop unused operands 537 bx r11 538 539 @ Test for NaN with a second comparison. EABI forbids testing bit 540 @ patterns, and we can't represent 0x7fc00000 in immediate form, so 541 @ make the library call. 542.LTEMPLATE_CMPL_DOUBLE_gt_or_nan: 543 pop {r2-r3} @ restore operands in reverse order 544 pop {r0-r1} @ restore operands in reverse order 545 LDR_PC_LR ".L__aeabi_cdcmple" @ r0<- Z set if eq, C clear if < 546 movcc r0, #1 @ (greater than) r1<- 1 547 bxcc r11 548 mvn r0, #0 @ r1<- 1 or -1 for NaN 549 bx r11 550 551/* ------------------------------ */ 552 .balign 4 553 .global dvmCompiler_TEMPLATE_CMPG_FLOAT 554dvmCompiler_TEMPLATE_CMPG_FLOAT: 555/* File: armv5te/TEMPLATE_CMPG_FLOAT.S */ 556/* File: armv5te/TEMPLATE_CMPL_FLOAT.S */ 557 /* 558 * For the JIT: incoming arguments in r0-r1, r2-r3 559 * result in r0 560 * 561 * Compare two floating-point values. Puts 0, 1, or -1 into the 562 * destination register based on the results of the comparison. 563 * 564 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending 565 * on what value we'd like to return when one of the operands is NaN. 566 * 567 * The operation we're implementing is: 568 * if (x == y) 569 * return 0; 570 * else if (x < y) 571 * return -1; 572 * else if (x > y) 573 * return 1; 574 * else 575 * return {-1,1}; // one or both operands was NaN 576 * 577 * The straightforward implementation requires 3 calls to functions 578 * that return a result in r0. We can do it with two calls if our 579 * EABI library supports __aeabi_cfcmple (only one if we want to check 580 * for NaN directly): 581 * check x <= y 582 * if <, return -1 583 * if ==, return 0 584 * check y <= x 585 * if <, return 1 586 * return {-1,1} 587 * 588 * for: cmpl-float, cmpg-float 589 */ 590 /* op vAA, vBB, vCC */ 591 mov r9, r0 @ Save copies - we may need to redo 592 mov r10, r1 593 mov r11, lr @ save return address 594 LDR_PC_LR ".L__aeabi_cfcmple" @ cmp <=: C clear if <, Z set if eq 595 bhi .LTEMPLATE_CMPG_FLOAT_gt_or_nan @ C set and Z clear, disambiguate 596 mvncc r0, #0 @ (less than) r0<- -1 597 moveq r0, #0 @ (equal) r0<- 0, trumps less than 598 bx r11 599 @ Test for NaN with a second comparison. EABI forbids testing bit 600 @ patterns, and we can't represent 0x7fc00000 in immediate form, so 601 @ make the library call. 602.LTEMPLATE_CMPG_FLOAT_gt_or_nan: 603 mov r0, r10 @ restore in reverse order 604 mov r1, r9 605 LDR_PC_LR ".L__aeabi_cfcmple" @ r0<- Z set if eq, C clear if < 606 movcc r0, #1 @ (greater than) r1<- 1 607 bxcc r11 608 mov r0, #1 @ r1<- 1 or -1 for NaN 609 bx r11 610 611 612/* ------------------------------ */ 613 .balign 4 614 .global dvmCompiler_TEMPLATE_CMPL_FLOAT 615dvmCompiler_TEMPLATE_CMPL_FLOAT: 616/* File: armv5te/TEMPLATE_CMPL_FLOAT.S */ 617 /* 618 * For the JIT: incoming arguments in r0-r1, r2-r3 619 * result in r0 620 * 621 * Compare two floating-point values. Puts 0, 1, or -1 into the 622 * destination register based on the results of the comparison. 623 * 624 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending 625 * on what value we'd like to return when one of the operands is NaN. 626 * 627 * The operation we're implementing is: 628 * if (x == y) 629 * return 0; 630 * else if (x < y) 631 * return -1; 632 * else if (x > y) 633 * return 1; 634 * else 635 * return {-1,1}; // one or both operands was NaN 636 * 637 * The straightforward implementation requires 3 calls to functions 638 * that return a result in r0. We can do it with two calls if our 639 * EABI library supports __aeabi_cfcmple (only one if we want to check 640 * for NaN directly): 641 * check x <= y 642 * if <, return -1 643 * if ==, return 0 644 * check y <= x 645 * if <, return 1 646 * return {-1,1} 647 * 648 * for: cmpl-float, cmpg-float 649 */ 650 /* op vAA, vBB, vCC */ 651 mov r9, r0 @ Save copies - we may need to redo 652 mov r10, r1 653 mov r11, lr @ save return address 654 LDR_PC_LR ".L__aeabi_cfcmple" @ cmp <=: C clear if <, Z set if eq 655 bhi .LTEMPLATE_CMPL_FLOAT_gt_or_nan @ C set and Z clear, disambiguate 656 mvncc r0, #0 @ (less than) r0<- -1 657 moveq r0, #0 @ (equal) r0<- 0, trumps less than 658 bx r11 659 @ Test for NaN with a second comparison. EABI forbids testing bit 660 @ patterns, and we can't represent 0x7fc00000 in immediate form, so 661 @ make the library call. 662.LTEMPLATE_CMPL_FLOAT_gt_or_nan: 663 mov r0, r10 @ restore in reverse order 664 mov r1, r9 665 LDR_PC_LR ".L__aeabi_cfcmple" @ r0<- Z set if eq, C clear if < 666 movcc r0, #1 @ (greater than) r1<- 1 667 bxcc r11 668 mvn r0, #0 @ r1<- 1 or -1 for NaN 669 bx r11 670 671/* ------------------------------ */ 672 .balign 4 673 .global dvmCompiler_TEMPLATE_MUL_LONG 674dvmCompiler_TEMPLATE_MUL_LONG: 675/* File: armv5te/TEMPLATE_MUL_LONG.S */ 676 /* 677 * Signed 64-bit integer multiply. 678 * 679 * For JIT: op1 in r0/r1, op2 in r2/r3, return in r0/r1 680 * 681 * Consider WXxYZ (r1r0 x r3r2) with a long multiply: 682 * WX 683 * x YZ 684 * -------- 685 * ZW ZX 686 * YW YX 687 * 688 * The low word of the result holds ZX, the high word holds 689 * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because 690 * it doesn't fit in the low 64 bits. 691 * 692 * Unlike most ARM math operations, multiply instructions have 693 * restrictions on using the same register more than once (Rd and Rm 694 * cannot be the same). 695 */ 696 /* mul-long vAA, vBB, vCC */ 697 mul ip, r2, r1 @ ip<- ZxW 698 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 699 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 700 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 701 mov r0,r9 702 mov r1,r10 703 bx lr 704 705/* ------------------------------ */ 706 .balign 4 707 .global dvmCompiler_TEMPLATE_SHL_LONG 708dvmCompiler_TEMPLATE_SHL_LONG: 709/* File: armv5te/TEMPLATE_SHL_LONG.S */ 710 /* 711 * Long integer shift. This is different from the generic 32/64-bit 712 * binary operations because vAA/vBB are 64-bit but vCC (the shift 713 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low 714 * 6 bits. 715 */ 716 /* shl-long vAA, vBB, vCC */ 717 and r2, r2, #63 @ r2<- r2 & 0x3f 718 mov r1, r1, asl r2 @ r1<- r1 << r2 719 rsb r3, r2, #32 @ r3<- 32 - r2 720 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 721 subs ip, r2, #32 @ ip<- r2 - 32 722 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 723 mov r0, r0, asl r2 @ r0<- r0 << r2 724 bx lr 725 726/* ------------------------------ */ 727 .balign 4 728 .global dvmCompiler_TEMPLATE_SHR_LONG 729dvmCompiler_TEMPLATE_SHR_LONG: 730/* File: armv5te/TEMPLATE_SHR_LONG.S */ 731 /* 732 * Long integer shift. This is different from the generic 32/64-bit 733 * binary operations because vAA/vBB are 64-bit but vCC (the shift 734 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low 735 * 6 bits. 736 */ 737 /* shr-long vAA, vBB, vCC */ 738 and r2, r2, #63 @ r0<- r0 & 0x3f 739 mov r0, r0, lsr r2 @ r0<- r2 >> r2 740 rsb r3, r2, #32 @ r3<- 32 - r2 741 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 742 subs ip, r2, #32 @ ip<- r2 - 32 743 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 744 mov r1, r1, asr r2 @ r1<- r1 >> r2 745 bx lr 746 747/* ------------------------------ */ 748 .balign 4 749 .global dvmCompiler_TEMPLATE_USHR_LONG 750dvmCompiler_TEMPLATE_USHR_LONG: 751/* File: armv5te/TEMPLATE_USHR_LONG.S */ 752 /* 753 * Long integer shift. This is different from the generic 32/64-bit 754 * binary operations because vAA/vBB are 64-bit but vCC (the shift 755 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low 756 * 6 bits. 757 */ 758 /* ushr-long vAA, vBB, vCC */ 759 and r2, r2, #63 @ r0<- r0 & 0x3f 760 mov r0, r0, lsr r2 @ r0<- r2 >> r2 761 rsb r3, r2, #32 @ r3<- 32 - r2 762 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 763 subs ip, r2, #32 @ ip<- r2 - 32 764 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 765 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 766 bx lr 767 768/* ------------------------------ */ 769 .balign 4 770 .global dvmCompiler_TEMPLATE_THROW_EXCEPTION_COMMON 771dvmCompiler_TEMPLATE_THROW_EXCEPTION_COMMON: 772/* File: armv5te/TEMPLATE_THROW_EXCEPTION_COMMON.S */ 773 /* 774 * Throw an exception from JIT'ed code. 775 * On entry: 776 * r0 Dalvik PC that raises the exception 777 */ 778 b .LhandleException 779 780/* ------------------------------ */ 781 .balign 4 782 .global dvmCompiler_TEMPLATE_MEM_OP_DECODE 783dvmCompiler_TEMPLATE_MEM_OP_DECODE: 784/* File: armv5te/TEMPLATE_MEM_OP_DECODE.S */ 785#if defined(WITH_SELF_VERIFICATION) 786 /* 787 * This handler encapsulates heap memory ops for selfVerification mode. 788 * 789 * The call to the handler is inserted prior to a heap memory operation. 790 * This handler then calls a function to decode the memory op, and process 791 * it accordingly. Afterwards, the handler changes the return address to 792 * skip the memory op so it never gets executed. 793 */ 794 push {r0-r12,lr} @ save out all registers 795 mov r0, lr @ arg0 <- link register 796 mov r1, sp @ arg1 <- stack pointer 797 ldr r2, .LdvmSelfVerificationMemOpDecode @ defined in footer.S 798 blx r2 @ decode and handle the mem op 799 pop {r0-r12,lr} @ restore all registers 800 bx lr @ return to compiled code 801#endif 802 803/* ------------------------------ */ 804 .balign 4 805 .global dvmCompiler_TEMPLATE_STRING_COMPARETO 806dvmCompiler_TEMPLATE_STRING_COMPARETO: 807/* File: armv5te/TEMPLATE_STRING_COMPARETO.S */ 808 /* 809 * String's compareTo. 810 * 811 * Requires r0/r1 to have been previously checked for null. Will 812 * return negative if this's string is < comp, 0 if they are the 813 * same and positive if >. 814 * 815 * IMPORTANT NOTE: 816 * 817 * This code relies on hard-coded offsets for string objects, and must be 818 * kept in sync with definitions in UtfString.h. See asm-constants.h 819 * 820 * On entry: 821 * r0: this object pointer 822 * r1: comp object pointer 823 * 824 */ 825 826 mov r2, r0 @ this to r2, opening up r0 for return value 827 subs r0, r2, r1 @ Same? 828 bxeq lr 829 830 ldr r4, [r2, #STRING_FIELDOFF_OFFSET] 831 ldr r9, [r1, #STRING_FIELDOFF_OFFSET] 832 ldr r7, [r2, #STRING_FIELDOFF_COUNT] 833 ldr r10, [r1, #STRING_FIELDOFF_COUNT] 834 ldr r2, [r2, #STRING_FIELDOFF_VALUE] 835 ldr r1, [r1, #STRING_FIELDOFF_VALUE] 836 837 /* 838 * At this point, we have: 839 * value: r2/r1 840 * offset: r4/r9 841 * count: r7/r10 842 * We're going to compute 843 * r11 <- countDiff 844 * r10 <- minCount 845 */ 846 subs r11, r7, r10 847 movls r10, r7 848 849 /* Now, build pointers to the string data */ 850 add r2, r2, r4, lsl #1 851 add r1, r1, r9, lsl #1 852 /* 853 * Note: data pointers point to previous element so we can use pre-index 854 * mode with base writeback. 855 */ 856 add r2, #16-2 @ offset to contents[-1] 857 add r1, #16-2 @ offset to contents[-1] 858 859 /* 860 * At this point we have: 861 * r2: *this string data 862 * r1: *comp string data 863 * r10: iteration count for comparison 864 * r11: value to return if the first part of the string is equal 865 * r0: reserved for result 866 * r3, r4, r7, r8, r9, r12 available for loading string data 867 */ 868 869 subs r10, #2 870 blt do_remainder2 871 872 /* 873 * Unroll the first two checks so we can quickly catch early mismatch 874 * on long strings (but preserve incoming alignment) 875 */ 876 877 ldrh r3, [r2, #2]! 878 ldrh r4, [r1, #2]! 879 ldrh r7, [r2, #2]! 880 ldrh r8, [r1, #2]! 881 subs r0, r3, r4 882 subeqs r0, r7, r8 883 bxne lr 884 cmp r10, #28 885 bgt do_memcmp16 886 subs r10, #3 887 blt do_remainder 888 889loopback_triple: 890 ldrh r3, [r2, #2]! 891 ldrh r4, [r1, #2]! 892 ldrh r7, [r2, #2]! 893 ldrh r8, [r1, #2]! 894 ldrh r9, [r2, #2]! 895 ldrh r12,[r1, #2]! 896 subs r0, r3, r4 897 subeqs r0, r7, r8 898 subeqs r0, r9, r12 899 bxne lr 900 subs r10, #3 901 bge loopback_triple 902 903do_remainder: 904 adds r10, #3 905 beq returnDiff 906 907loopback_single: 908 ldrh r3, [r2, #2]! 909 ldrh r4, [r1, #2]! 910 subs r0, r3, r4 911 bxne lr 912 subs r10, #1 913 bne loopback_single 914 915returnDiff: 916 mov r0, r11 917 bx lr 918 919do_remainder2: 920 adds r10, #2 921 bne loopback_single 922 mov r0, r11 923 bx lr 924 925 /* Long string case */ 926do_memcmp16: 927 mov r4, lr 928 ldr lr, .Lmemcmp16 929 mov r7, r11 930 add r0, r2, #2 931 add r1, r1, #2 932 mov r2, r10 933 blx lr 934 cmp r0, #0 935 bxne r4 936 mov r0, r7 937 bx r4 938 939.Lmemcmp16: 940 .word __memcmp16 941 942/* ------------------------------ */ 943 .balign 4 944 .global dvmCompiler_TEMPLATE_STRING_INDEXOF 945dvmCompiler_TEMPLATE_STRING_INDEXOF: 946/* File: armv5te/TEMPLATE_STRING_INDEXOF.S */ 947 /* 948 * String's indexOf. 949 * 950 * Requires r0 to have been previously checked for null. Will 951 * return index of match of r1 in r0. 952 * 953 * IMPORTANT NOTE: 954 * 955 * This code relies on hard-coded offsets for string objects, and must be 956 * kept in sync wth definitions in UtfString.h See asm-constants.h 957 * 958 * On entry: 959 * r0: string object pointer 960 * r1: char to match 961 * r2: Starting offset in string data 962 */ 963 964 ldr r7, [r0, #STRING_FIELDOFF_OFFSET] 965 ldr r8, [r0, #STRING_FIELDOFF_COUNT] 966 ldr r0, [r0, #STRING_FIELDOFF_VALUE] 967 968 /* 969 * At this point, we have: 970 * r0: object pointer 971 * r1: char to match 972 * r2: starting offset 973 * r7: offset 974 * r8: string length 975 */ 976 977 /* Build pointer to start of string data */ 978 add r0, #16 979 add r0, r0, r7, lsl #1 980 981 /* Save a copy of starting data in r7 */ 982 mov r7, r0 983 984 /* Clamp start to [0..count] */ 985 cmp r2, #0 986 movlt r2, #0 987 cmp r2, r8 988 movgt r2, r8 989 990 /* Build pointer to start of data to compare and pre-bias */ 991 add r0, r0, r2, lsl #1 992 sub r0, #2 993 994 /* Compute iteration count */ 995 sub r8, r2 996 997 /* 998 * At this point we have: 999 * r0: start of data to test 1000 * r1: chat to compare 1001 * r8: iteration count 1002 * r7: original start of string 1003 * r3, r4, r9, r10, r11, r12 available for loading string data 1004 */ 1005 1006 subs r8, #4 1007 blt indexof_remainder 1008 1009indexof_loop4: 1010 ldrh r3, [r0, #2]! 1011 ldrh r4, [r0, #2]! 1012 ldrh r10, [r0, #2]! 1013 ldrh r11, [r0, #2]! 1014 cmp r3, r1 1015 beq match_0 1016 cmp r4, r1 1017 beq match_1 1018 cmp r10, r1 1019 beq match_2 1020 cmp r11, r1 1021 beq match_3 1022 subs r8, #4 1023 bge indexof_loop4 1024 1025indexof_remainder: 1026 adds r8, #4 1027 beq indexof_nomatch 1028 1029indexof_loop1: 1030 ldrh r3, [r0, #2]! 1031 cmp r3, r1 1032 beq match_3 1033 subs r8, #1 1034 bne indexof_loop1 1035 1036indexof_nomatch: 1037 mov r0, #-1 1038 bx lr 1039 1040match_0: 1041 sub r0, #6 1042 sub r0, r7 1043 asr r0, r0, #1 1044 bx lr 1045match_1: 1046 sub r0, #4 1047 sub r0, r7 1048 asr r0, r0, #1 1049 bx lr 1050match_2: 1051 sub r0, #2 1052 sub r0, r7 1053 asr r0, r0, #1 1054 bx lr 1055match_3: 1056 sub r0, r7 1057 asr r0, r0, #1 1058 bx lr 1059 1060/* ------------------------------ */ 1061 .balign 4 1062 .global dvmCompiler_TEMPLATE_INTERPRET 1063dvmCompiler_TEMPLATE_INTERPRET: 1064/* File: armv5te/TEMPLATE_INTERPRET.S */ 1065 /* 1066 * This handler transfers control to the interpeter without performing 1067 * any lookups. It may be called either as part of a normal chaining 1068 * operation, or from the transition code in header.S. We distinquish 1069 * the two cases by looking at the link register. If called from a 1070 * translation chain, it will point to the chaining Dalvik PC -3. 1071 * On entry: 1072 * lr - if NULL: 1073 * r1 - the Dalvik PC to begin interpretation. 1074 * else 1075 * [lr, #3] contains Dalvik PC to begin interpretation 1076 * rGLUE - pointer to interpState 1077 * rFP - Dalvik frame pointer 1078 */ 1079 cmp lr, #0 1080 ldrne r1,[lr, #3] 1081 ldr r2, .LinterpPunt 1082 mov r0, r1 @ set Dalvik PC 1083 bx r2 1084 @ doesn't return 1085 1086.LinterpPunt: 1087 .word dvmJitToInterpPunt 1088 1089/* ------------------------------ */ 1090 .balign 4 1091 .global dvmCompiler_TEMPLATE_MONITOR_ENTER 1092dvmCompiler_TEMPLATE_MONITOR_ENTER: 1093/* File: armv5te/TEMPLATE_MONITOR_ENTER.S */ 1094 /* 1095 * Call out to the runtime to lock an object. Because this thread 1096 * may have been suspended in THREAD_MONITOR state and the Jit's 1097 * translation cache subsequently cleared, we cannot return directly. 1098 * Instead, unconditionally transition to the interpreter to resume. 1099 * 1100 * On entry: 1101 * r0 - self pointer 1102 * r1 - the object (which has already been null-checked by the caller 1103 * r4 - the Dalvik PC of the following instruction. 1104 */ 1105 ldr r2, .LdvmLockObject 1106 mov r3, #0 @ Record that we're not returning 1107 str r3, [r0, #offThread_inJitCodeCache] 1108 blx r2 @ dvmLockObject(self, obj) 1109 @ refresh Jit's on/off status 1110 ldr r0, [rGLUE, #offGlue_ppJitProfTable] 1111 ldr r0, [r0] 1112 ldr r2, .LdvmJitToInterpNoChain 1113 str r0, [rGLUE, #offGlue_pJitProfTable] 1114 @ Bail to interpreter - no chain [note - r4 still contains rPC] 1115#if defined(WITH_JIT_TUNING) 1116 mov r0, #kHeavyweightMonitor 1117#endif 1118 bx r2 1119 1120/* ------------------------------ */ 1121 .balign 4 1122 .global dvmCompiler_TEMPLATE_MONITOR_ENTER_DEBUG 1123dvmCompiler_TEMPLATE_MONITOR_ENTER_DEBUG: 1124/* File: armv5te/TEMPLATE_MONITOR_ENTER_DEBUG.S */ 1125 /* 1126 * To support deadlock prediction, this version of MONITOR_ENTER 1127 * will always call the heavyweight dvmLockObject, check for an 1128 * exception and then bail out to the interpreter. 1129 * 1130 * On entry: 1131 * r0 - self pointer 1132 * r1 - the object (which has already been null-checked by the caller 1133 * r4 - the Dalvik PC of the following instruction. 1134 * 1135 */ 1136 ldr r2, .LdvmLockObject 1137 mov r3, #0 @ Record that we're not returning 1138 str r3, [r0, #offThread_inJitCodeCache] 1139 blx r2 @ dvmLockObject(self, obj) 1140 @ refresh Jit's on/off status & test for exception 1141 ldr r0, [rGLUE, #offGlue_ppJitProfTable] 1142 ldr r1, [rGLUE, #offGlue_self] 1143 ldr r0, [r0] 1144 ldr r1, [r1, #offThread_exception] 1145 str r0, [rGLUE, #offGlue_pJitProfTable] 1146 cmp r1, #0 1147 beq 1f 1148 ldr r2, .LhandleException 1149 sub r0, r4, #2 @ roll dPC back to this monitor instruction 1150 bx r2 11511: 1152 @ Bail to interpreter - no chain [note - r4 still contains rPC] 1153#if defined(WITH_JIT_TUNING) 1154 mov r0, #kHeavyweightMonitor 1155#endif 1156 ldr pc, .LdvmJitToInterpNoChain 1157 1158 .size dvmCompilerTemplateStart, .-dvmCompilerTemplateStart 1159/* File: armv5te/footer.S */ 1160/* 1161 * =========================================================================== 1162 * Common subroutines and data 1163 * =========================================================================== 1164 */ 1165 1166 .text 1167 .align 2 1168.LinvokeNative: 1169 @ Prep for the native call 1170 @ r1 = newFP, r0 = methodToCall 1171 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self 1172 mov r2, #0 1173 ldr r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->... 1174 str r2, [r3, #offThread_inJitCodeCache] @ not in jit code cache 1175 str r1, [r3, #offThread_curFrame] @ self->curFrame = newFp 1176 str r9, [r1, #(offStackSaveArea_localRefCookie - sizeofStackSaveArea)] 1177 @ newFp->localRefCookie=top 1178 mov r9, r3 @ r9<- glue->self (preserve) 1179 SAVEAREA_FROM_FP(r10, r1) @ r10<- new stack save area 1180 1181 mov r2, r0 @ r2<- methodToCall 1182 mov r0, r1 @ r0<- newFP 1183 add r1, rGLUE, #offGlue_retval @ r1<- &retval 1184 1185 LDR_PC_LR "[r2, #offMethod_nativeFunc]" 1186 1187 @ Refresh Jit's on/off status 1188 ldr r3, [rGLUE, #offGlue_ppJitProfTable] 1189 1190 @ native return; r9=self, r10=newSaveArea 1191 @ equivalent to dvmPopJniLocals 1192 ldr r2, [r10, #offStackSaveArea_returnAddr] @ r2 = chaining cell ret 1193 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved->top 1194 ldr r1, [r9, #offThread_exception] @ check for exception 1195 ldr r3, [r3] @ r1 <- pointer to Jit profile table 1196 str rFP, [r9, #offThread_curFrame] @ self->curFrame = fp 1197 cmp r1, #0 @ null? 1198 str r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top 1199 ldr r0, [r10, #offStackSaveArea_savedPc] @ reload rPC 1200 str r3, [rGLUE, #offGlue_pJitProfTable] @ cache current JitProfTable 1201 1202 @ r0 = dalvikCallsitePC 1203 bne .LhandleException @ no, handle exception 1204 1205 str r2, [r9, #offThread_inJitCodeCache] @ set the new mode 1206 cmp r2, #0 @ return chaining cell still exists? 1207 bxne r2 @ yes - go ahead 1208 1209 @ continue executing the next instruction through the interpreter 1210 ldr r1, .LdvmJitToInterpTraceSelectNoChain @ defined in footer.S 1211 add rPC, r0, #6 @ reconstruct new rPC (advance 6 bytes) 1212#if defined(WITH_JIT_TUNING) 1213 mov r0, #kCallsiteInterpreted 1214#endif 1215 mov pc, r1 1216 1217/* 1218 * On entry: 1219 * r0 Faulting Dalvik PC 1220 */ 1221.LhandleException: 1222#if defined(WITH_SELF_VERIFICATION) 1223 ldr pc, .LdeadFood @ should not see this under self-verification mode 1224.LdeadFood: 1225 .word 0xdeadf00d 1226#endif 1227 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self 1228 mov r2, #0 1229 str r2, [r3, #offThread_inJitCodeCache] @ in interpreter land 1230 ldr r1, .LdvmMterpCommonExceptionThrown @ PIC way of getting &func 1231 ldr rIBASE, .LdvmAsmInstructionStart @ same as above 1232 mov rPC, r0 @ reload the faulting Dalvik address 1233 mov pc, r1 @ branch to dvmMterpCommonExceptionThrown 1234 1235 .align 2 1236.LdvmAsmInstructionStart: 1237 .word dvmAsmInstructionStart 1238.LdvmJitToInterpNoChainNoProfile: 1239 .word dvmJitToInterpNoChainNoProfile 1240.LdvmJitToInterpTraceSelectNoChain: 1241 .word dvmJitToInterpTraceSelectNoChain 1242.LdvmJitToInterpNoChain: 1243 .word dvmJitToInterpNoChain 1244.LdvmMterpStdBail: 1245 .word dvmMterpStdBail 1246.LdvmMterpCommonExceptionThrown: 1247 .word dvmMterpCommonExceptionThrown 1248.LdvmLockObject: 1249 .word dvmLockObject 1250#if defined(WITH_JIT_TUNING) 1251.LdvmICHitCount: 1252 .word gDvmICHitCount 1253#endif 1254#if defined(WITH_SELF_VERIFICATION) 1255.LdvmSelfVerificationMemOpDecode: 1256 .word dvmSelfVerificationMemOpDecode 1257#endif 1258.L__aeabi_cdcmple: 1259 .word __aeabi_cdcmple 1260.L__aeabi_cfcmple: 1261 .word __aeabi_cfcmple 1262 1263 .global dmvCompilerTemplateEnd 1264dmvCompilerTemplateEnd: 1265 1266#endif /* WITH_JIT */ 1267 1268