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