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