1 /* 2 * This file was generated automatically by gen-mterp.py for 'armv7-a'. 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 /* 25 * ARMv5 definitions and declarations. 26 */ 27 28 /* 29 ARM EABI general notes: 30 31 r0-r3 hold first 4 args to a method; they are not preserved across method calls 32 r4-r8 are available for general use 33 r9 is given special treatment in some situations, but not for us 34 r10 (sl) seems to be generally available 35 r11 (fp) is used by gcc (unless -fomit-frame-pointer is set) 36 r12 (ip) is scratch -- not preserved across method calls 37 r13 (sp) should be managed carefully in case a signal arrives 38 r14 (lr) must be preserved 39 r15 (pc) can be tinkered with directly 40 41 r0 holds returns of <= 4 bytes 42 r0-r1 hold returns of 8 bytes, low word in r0 43 44 Callee must save/restore r4+ (except r12) if it modifies them. If VFP 45 is present, registers s16-s31 (a/k/a d8-d15, a/k/a q4-q7) must be preserved, 46 s0-s15 (d0-d7, q0-a3) do not need to be. 47 48 Stack is "full descending". Only the arguments that don't fit in the first 4 49 registers are placed on the stack. "sp" points at the first stacked argument 50 (i.e. the 5th arg). 51 52 VFP: single-precision results in s0, double-precision results in d0. 53 54 In the EABI, "sp" must be 64-bit aligned on entry to a function, and any 55 64-bit quantities (long long, double) must be 64-bit aligned. 56 */ 57 58 /* 59 Mterp and ARM notes: 60 61 The following registers have fixed assignments: 62 63 reg nick purpose 64 r4 rPC interpreted program counter, used for fetching instructions 65 r5 rFP interpreted frame pointer, used for accessing locals and args 66 r6 rSELF self (Thread) pointer 67 r7 rINST first 16-bit code unit of current instruction 68 r8 rIBASE interpreted instruction base pointer, used for computed goto 69 70 Macros are provided for common operations. Each macro MUST emit only 71 one instruction to make instruction-counting easier. They MUST NOT alter 72 unspecified registers or condition codes. 73 */ 74 75 /* single-purpose registers, given names for clarity */ 76 #define rPC r4 77 #define rFP r5 78 #define rSELF r6 79 #define rINST r7 80 #define rIBASE r8 81 82 /* save/restore the PC and/or FP from the thread struct */ 83 #define LOAD_PC_FROM_SELF() ldr rPC, [rSELF, #offThread_pc] 84 #define SAVE_PC_TO_SELF() str rPC, [rSELF, #offThread_pc] 85 #define LOAD_FP_FROM_SELF() ldr rFP, [rSELF, #offThread_curFrame] 86 #define SAVE_FP_TO_SELF() str rFP, [rSELF, #offThread_curFrame] 87 #define LOAD_PC_FP_FROM_SELF() ldmia rSELF, {rPC, rFP} 88 #define SAVE_PC_FP_TO_SELF() stmia rSELF, {rPC, rFP} 89 90 /* 91 * "export" the PC to the stack frame, f/b/o future exception objects. Must 92 * be done *before* something throws. 93 * 94 * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e. 95 * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc) 96 * 97 * It's okay to do this more than once. 98 */ 99 #define EXPORT_PC() \ 100 str rPC, [rFP, #(-sizeofStackSaveArea + offStackSaveArea_currentPc)] 101 102 /* 103 * Given a frame pointer, find the stack save area. 104 * 105 * In C this is "((StackSaveArea*)(_fp) -1)". 106 */ 107 #define SAVEAREA_FROM_FP(_reg, _fpreg) \ 108 sub _reg, _fpreg, #sizeofStackSaveArea 109 110 /* 111 * Fetch the next instruction from rPC into rINST. Does not advance rPC. 112 */ 113 #define FETCH_INST() ldrh rINST, [rPC] 114 115 /* 116 * Fetch the next instruction from the specified offset. Advances rPC 117 * to point to the next instruction. "_count" is in 16-bit code units. 118 * 119 * Because of the limited size of immediate constants on ARM, this is only 120 * suitable for small forward movements (i.e. don't try to implement "goto" 121 * with this). 122 * 123 * This must come AFTER anything that can throw an exception, or the 124 * exception catch may miss. (This also implies that it must come after 125 * EXPORT_PC().) 126 */ 127 #define FETCH_ADVANCE_INST(_count) ldrh rINST, [rPC, #((_count)*2)]! 128 129 /* 130 * The operation performed here is similar to FETCH_ADVANCE_INST, except the 131 * src and dest registers are parameterized (not hard-wired to rPC and rINST). 132 */ 133 #define PREFETCH_ADVANCE_INST(_dreg, _sreg, _count) \ 134 ldrh _dreg, [_sreg, #((_count)*2)]! 135 136 /* 137 * Fetch the next instruction from an offset specified by _reg. Updates 138 * rPC to point to the next instruction. "_reg" must specify the distance 139 * in bytes, *not* 16-bit code units, and may be a signed value. 140 * 141 * We want to write "ldrh rINST, [rPC, _reg, lsl #1]!", but some of the 142 * bits that hold the shift distance are used for the half/byte/sign flags. 143 * In some cases we can pre-double _reg for free, so we require a byte offset 144 * here. 145 */ 146 #define FETCH_ADVANCE_INST_RB(_reg) ldrh rINST, [rPC, _reg]! 147 148 /* 149 * Fetch a half-word code unit from an offset past the current PC. The 150 * "_count" value is in 16-bit code units. Does not advance rPC. 151 * 152 * The "_S" variant works the same but treats the value as signed. 153 */ 154 #define FETCH(_reg, _count) ldrh _reg, [rPC, #((_count)*2)] 155 #define FETCH_S(_reg, _count) ldrsh _reg, [rPC, #((_count)*2)] 156 157 /* 158 * Fetch one byte from an offset past the current PC. Pass in the same 159 * "_count" as you would for FETCH, and an additional 0/1 indicating which 160 * byte of the halfword you want (lo/hi). 161 */ 162 #define FETCH_B(_reg, _count, _byte) ldrb _reg, [rPC, #((_count)*2+(_byte))] 163 164 /* 165 * Put the instruction's opcode field into the specified register. 166 */ 167 #define GET_INST_OPCODE(_reg) and _reg, rINST, #255 168 169 /* 170 * Put the prefetched instruction's opcode field into the specified register. 171 */ 172 #define GET_PREFETCHED_OPCODE(_oreg, _ireg) and _oreg, _ireg, #255 173 174 /* 175 * Begin executing the opcode in _reg. Because this only jumps within the 176 * interpreter, we don't have to worry about pre-ARMv5 THUMB interwork. 177 */ 178 #define GOTO_OPCODE(_reg) add pc, rIBASE, _reg, lsl #6 179 #define GOTO_OPCODE_BASE(_base,_reg) add pc, _base, _reg, lsl #6 180 #define GOTO_OPCODE_IFEQ(_reg) addeq pc, rIBASE, _reg, lsl #6 181 #define GOTO_OPCODE_IFNE(_reg) addne pc, rIBASE, _reg, lsl #6 182 183 /* 184 * Get/set the 32-bit value from a Dalvik register. 185 */ 186 #define GET_VREG(_reg, _vreg) ldr _reg, [rFP, _vreg, lsl #2] 187 #define SET_VREG(_reg, _vreg) str _reg, [rFP, _vreg, lsl #2] 188 189 /* 190 * Convert a virtual register index into an address. 191 */ 192 #define VREG_INDEX_TO_ADDR(_reg, _vreg) \ 193 add _reg, rFP, _vreg, lsl #2 194 195 /* 196 * This is a #include, not a %include, because we want the C pre-processor 197 * to expand the macros into assembler assignment statements. 198 */ 199 #include "../common/asm-constants.h" 200 201 #if defined(WITH_JIT) 202 #include "../common/jit-config.h" 203 #endif 204 205 /* File: armv7-a/platform.S */ 206 /* 207 * =========================================================================== 208 * CPU-version-specific defines 209 * =========================================================================== 210 */ 211 212 #if !defined(ANDROID_SMP) 213 # error "Must define ANDROID_SMP" 214 #endif 215 216 /* 217 * Macro for data memory barrier. 218 */ 219 .macro SMP_DMB 220 #if ANDROID_SMP != 0 221 dmb 222 #else 223 /* not SMP */ 224 #endif 225 .endm 226 227 /* 228 * Macro for data memory barrier (store/store variant). 229 */ 230 .macro SMP_DMB_ST 231 #if ANDROID_SMP != 0 232 dmb st 233 #else 234 /* not SMP */ 235 #endif 236 .endm 237 238 /* File: armv5te/entry.S */ 239 /* 240 * Copyright (C) 2008 The Android Open Source Project 241 * 242 * Licensed under the Apache License, Version 2.0 (the "License"); 243 * you may not use this file except in compliance with the License. 244 * You may obtain a copy of the License at 245 * 246 * http://www.apache.org/licenses/LICENSE-2.0 247 * 248 * Unless required by applicable law or agreed to in writing, software 249 * distributed under the License is distributed on an "AS IS" BASIS, 250 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 251 * See the License for the specific language governing permissions and 252 * limitations under the License. 253 */ 254 /* 255 * Interpreter entry point. 256 */ 257 258 /* 259 * We don't have formal stack frames, so gdb scans upward in the code 260 * to find the start of the function (a label with the %function type), 261 * and then looks at the next few instructions to figure out what 262 * got pushed onto the stack. From this it figures out how to restore 263 * the registers, including PC, for the previous stack frame. If gdb 264 * sees a non-function label, it stops scanning, so either we need to 265 * have nothing but assembler-local labels between the entry point and 266 * the break, or we need to fake it out. 267 * 268 * When this is defined, we add some stuff to make gdb less confused. 269 */ 270 #define ASSIST_DEBUGGER 1 271 272 .text 273 .align 2 274 .global dvmMterpStdRun 275 .type dvmMterpStdRun, %function 276 277 /* 278 * On entry: 279 * r0 Thread* self 280 * 281 * The return comes via a call to dvmMterpStdBail(). 282 */ 283 dvmMterpStdRun: 284 #define MTERP_ENTRY1 \ 285 .save {r4-r10,fp,lr}; \ 286 stmfd sp!, {r4-r10,fp,lr} @ save 9 regs 287 #define MTERP_ENTRY2 \ 288 .pad #4; \ 289 sub sp, sp, #4 @ align 64 290 291 .fnstart 292 MTERP_ENTRY1 293 MTERP_ENTRY2 294 295 /* save stack pointer, add magic word for debuggerd */ 296 str sp, [r0, #offThread_bailPtr] @ save SP for eventual return 297 298 /* set up "named" registers, figure out entry point */ 299 mov rSELF, r0 @ set rSELF 300 LOAD_PC_FP_FROM_SELF() @ load rPC and rFP from "thread" 301 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ set rIBASE 302 303 #if defined(WITH_JIT) 304 .LentryInstr: 305 /* Entry is always a possible trace start */ 306 ldr r0, [rSELF, #offThread_pJitProfTable] 307 FETCH_INST() 308 mov r1, #0 @ prepare the value for the new state 309 str r1, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 310 cmp r0,#0 @ is profiling disabled? 311 #if !defined(WITH_SELF_VERIFICATION) 312 bne common_updateProfile @ profiling is enabled 313 #else 314 ldr r2, [rSELF, #offThread_shadowSpace] @ to find out the jit exit state 315 beq 1f @ profiling is disabled 316 ldr r3, [r2, #offShadowSpace_jitExitState] @ jit exit state 317 cmp r3, #kSVSTraceSelect @ hot trace following? 318 moveq r2,#kJitTSelectRequestHot @ ask for trace selection 319 beq common_selectTrace @ go build the trace 320 cmp r3, #kSVSNoProfile @ don't profile the next instruction? 321 beq 1f @ intrepret the next instruction 322 b common_updateProfile @ collect profiles 323 #endif 324 1: 325 GET_INST_OPCODE(ip) 326 GOTO_OPCODE(ip) 327 #else 328 /* start executing the instruction at rPC */ 329 FETCH_INST() @ load rINST from rPC 330 GET_INST_OPCODE(ip) @ extract opcode from rINST 331 GOTO_OPCODE(ip) @ jump to next instruction 332 #endif 333 334 .Lbad_arg: 335 ldr r0, strBadEntryPoint 336 @ r1 holds value of entryPoint 337 bl printf 338 bl dvmAbort 339 .fnend 340 .size dvmMterpStdRun, .-dvmMterpStdRun 341 342 343 .global dvmMterpStdBail 344 .type dvmMterpStdBail, %function 345 346 /* 347 * Restore the stack pointer and PC from the save point established on entry. 348 * This is essentially the same as a longjmp, but should be cheaper. The 349 * last instruction causes us to return to whoever called dvmMterpStdRun. 350 * 351 * We pushed some registers on the stack in dvmMterpStdRun, then saved 352 * SP and LR. Here we restore SP, restore the registers, and then restore 353 * LR to PC. 354 * 355 * On entry: 356 * r0 Thread* self 357 */ 358 dvmMterpStdBail: 359 ldr sp, [r0, #offThread_bailPtr] @ sp<- saved SP 360 add sp, sp, #4 @ un-align 64 361 ldmfd sp!, {r4-r10,fp,pc} @ restore 9 regs and return 362 363 364 /* 365 * String references. 366 */ 367 strBadEntryPoint: 368 .word .LstrBadEntryPoint 369 370 371 .global dvmAsmInstructionStart 372 .type dvmAsmInstructionStart, %function 373 dvmAsmInstructionStart = .L_OP_NOP 374 .text 375 376 /* ------------------------------ */ 377 .balign 64 378 .L_OP_NOP: /* 0x00 */ 379 /* File: armv5te/OP_NOP.S */ 380 FETCH_ADVANCE_INST(1) @ advance to next instr, load rINST 381 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 382 GOTO_OPCODE(ip) @ execute it 383 384 #ifdef ASSIST_DEBUGGER 385 /* insert fake function header to help gdb find the stack frame */ 386 .type dalvik_inst, %function 387 dalvik_inst: 388 .fnstart 389 MTERP_ENTRY1 390 MTERP_ENTRY2 391 .fnend 392 #endif 393 394 /* ------------------------------ */ 395 .balign 64 396 .L_OP_MOVE: /* 0x01 */ 397 /* File: armv6t2/OP_MOVE.S */ 398 /* for move, move-object, long-to-int */ 399 /* op vA, vB */ 400 mov r1, rINST, lsr #12 @ r1<- B from 15:12 401 ubfx r0, rINST, #8, #4 @ r0<- A from 11:8 402 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 403 GET_VREG(r2, r1) @ r2<- fp[B] 404 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 405 SET_VREG(r2, r0) @ fp[A]<- r2 406 GOTO_OPCODE(ip) @ execute next instruction 407 408 /* ------------------------------ */ 409 .balign 64 410 .L_OP_MOVE_FROM16: /* 0x02 */ 411 /* File: armv5te/OP_MOVE_FROM16.S */ 412 /* for: move/from16, move-object/from16 */ 413 /* op vAA, vBBBB */ 414 FETCH(r1, 1) @ r1<- BBBB 415 mov r0, rINST, lsr #8 @ r0<- AA 416 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 417 GET_VREG(r2, r1) @ r2<- fp[BBBB] 418 GET_INST_OPCODE(ip) @ extract opcode from rINST 419 SET_VREG(r2, r0) @ fp[AA]<- r2 420 GOTO_OPCODE(ip) @ jump to next instruction 421 422 /* ------------------------------ */ 423 .balign 64 424 .L_OP_MOVE_16: /* 0x03 */ 425 /* File: armv5te/OP_MOVE_16.S */ 426 /* for: move/16, move-object/16 */ 427 /* op vAAAA, vBBBB */ 428 FETCH(r1, 2) @ r1<- BBBB 429 FETCH(r0, 1) @ r0<- AAAA 430 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 431 GET_VREG(r2, r1) @ r2<- fp[BBBB] 432 GET_INST_OPCODE(ip) @ extract opcode from rINST 433 SET_VREG(r2, r0) @ fp[AAAA]<- r2 434 GOTO_OPCODE(ip) @ jump to next instruction 435 436 /* ------------------------------ */ 437 .balign 64 438 .L_OP_MOVE_WIDE: /* 0x04 */ 439 /* File: armv6t2/OP_MOVE_WIDE.S */ 440 /* move-wide vA, vB */ 441 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 442 mov r3, rINST, lsr #12 @ r3<- B 443 ubfx r2, rINST, #8, #4 @ r2<- A 444 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 445 add r2, rFP, r2, lsl #2 @ r2<- &fp[A] 446 ldmia r3, {r0-r1} @ r0/r1<- fp[B] 447 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 448 GET_INST_OPCODE(ip) @ extract opcode from rINST 449 stmia r2, {r0-r1} @ fp[A]<- r0/r1 450 GOTO_OPCODE(ip) @ jump to next instruction 451 452 /* ------------------------------ */ 453 .balign 64 454 .L_OP_MOVE_WIDE_FROM16: /* 0x05 */ 455 /* File: armv5te/OP_MOVE_WIDE_FROM16.S */ 456 /* move-wide/from16 vAA, vBBBB */ 457 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 458 FETCH(r3, 1) @ r3<- BBBB 459 mov r2, rINST, lsr #8 @ r2<- AA 460 add r3, rFP, r3, lsl #2 @ r3<- &fp[BBBB] 461 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 462 ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB] 463 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 464 GET_INST_OPCODE(ip) @ extract opcode from rINST 465 stmia r2, {r0-r1} @ fp[AA]<- r0/r1 466 GOTO_OPCODE(ip) @ jump to next instruction 467 468 /* ------------------------------ */ 469 .balign 64 470 .L_OP_MOVE_WIDE_16: /* 0x06 */ 471 /* File: armv5te/OP_MOVE_WIDE_16.S */ 472 /* move-wide/16 vAAAA, vBBBB */ 473 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 474 FETCH(r3, 2) @ r3<- BBBB 475 FETCH(r2, 1) @ r2<- AAAA 476 add r3, rFP, r3, lsl #2 @ r3<- &fp[BBBB] 477 add r2, rFP, r2, lsl #2 @ r2<- &fp[AAAA] 478 ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB] 479 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 480 GET_INST_OPCODE(ip) @ extract opcode from rINST 481 stmia r2, {r0-r1} @ fp[AAAA]<- r0/r1 482 GOTO_OPCODE(ip) @ jump to next instruction 483 484 /* ------------------------------ */ 485 .balign 64 486 .L_OP_MOVE_OBJECT: /* 0x07 */ 487 /* File: armv5te/OP_MOVE_OBJECT.S */ 488 /* File: armv5te/OP_MOVE.S */ 489 /* for move, move-object, long-to-int */ 490 /* op vA, vB */ 491 mov r1, rINST, lsr #12 @ r1<- B from 15:12 492 mov r0, rINST, lsr #8 @ r0<- A from 11:8 493 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 494 GET_VREG(r2, r1) @ r2<- fp[B] 495 and r0, r0, #15 496 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 497 SET_VREG(r2, r0) @ fp[A]<- r2 498 GOTO_OPCODE(ip) @ execute next instruction 499 500 501 /* ------------------------------ */ 502 .balign 64 503 .L_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 504 /* File: armv5te/OP_MOVE_OBJECT_FROM16.S */ 505 /* File: armv5te/OP_MOVE_FROM16.S */ 506 /* for: move/from16, move-object/from16 */ 507 /* op vAA, vBBBB */ 508 FETCH(r1, 1) @ r1<- BBBB 509 mov r0, rINST, lsr #8 @ r0<- AA 510 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 511 GET_VREG(r2, r1) @ r2<- fp[BBBB] 512 GET_INST_OPCODE(ip) @ extract opcode from rINST 513 SET_VREG(r2, r0) @ fp[AA]<- r2 514 GOTO_OPCODE(ip) @ jump to next instruction 515 516 517 /* ------------------------------ */ 518 .balign 64 519 .L_OP_MOVE_OBJECT_16: /* 0x09 */ 520 /* File: armv5te/OP_MOVE_OBJECT_16.S */ 521 /* File: armv5te/OP_MOVE_16.S */ 522 /* for: move/16, move-object/16 */ 523 /* op vAAAA, vBBBB */ 524 FETCH(r1, 2) @ r1<- BBBB 525 FETCH(r0, 1) @ r0<- AAAA 526 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 527 GET_VREG(r2, r1) @ r2<- fp[BBBB] 528 GET_INST_OPCODE(ip) @ extract opcode from rINST 529 SET_VREG(r2, r0) @ fp[AAAA]<- r2 530 GOTO_OPCODE(ip) @ jump to next instruction 531 532 533 /* ------------------------------ */ 534 .balign 64 535 .L_OP_MOVE_RESULT: /* 0x0a */ 536 /* File: armv5te/OP_MOVE_RESULT.S */ 537 /* for: move-result, move-result-object */ 538 /* op vAA */ 539 mov r2, rINST, lsr #8 @ r2<- AA 540 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 541 ldr r0, [rSELF, #offThread_retval] @ r0<- self->retval.i 542 GET_INST_OPCODE(ip) @ extract opcode from rINST 543 SET_VREG(r0, r2) @ fp[AA]<- r0 544 GOTO_OPCODE(ip) @ jump to next instruction 545 546 /* ------------------------------ */ 547 .balign 64 548 .L_OP_MOVE_RESULT_WIDE: /* 0x0b */ 549 /* File: armv5te/OP_MOVE_RESULT_WIDE.S */ 550 /* move-result-wide vAA */ 551 mov r2, rINST, lsr #8 @ r2<- AA 552 add r3, rSELF, #offThread_retval @ r3<- &self->retval 553 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 554 ldmia r3, {r0-r1} @ r0/r1<- retval.j 555 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 556 GET_INST_OPCODE(ip) @ extract opcode from rINST 557 stmia r2, {r0-r1} @ fp[AA]<- r0/r1 558 GOTO_OPCODE(ip) @ jump to next instruction 559 560 /* ------------------------------ */ 561 .balign 64 562 .L_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 563 /* File: armv5te/OP_MOVE_RESULT_OBJECT.S */ 564 /* File: armv5te/OP_MOVE_RESULT.S */ 565 /* for: move-result, move-result-object */ 566 /* op vAA */ 567 mov r2, rINST, lsr #8 @ r2<- AA 568 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 569 ldr r0, [rSELF, #offThread_retval] @ r0<- self->retval.i 570 GET_INST_OPCODE(ip) @ extract opcode from rINST 571 SET_VREG(r0, r2) @ fp[AA]<- r0 572 GOTO_OPCODE(ip) @ jump to next instruction 573 574 575 /* ------------------------------ */ 576 .balign 64 577 .L_OP_MOVE_EXCEPTION: /* 0x0d */ 578 /* File: armv5te/OP_MOVE_EXCEPTION.S */ 579 /* move-exception vAA */ 580 mov r2, rINST, lsr #8 @ r2<- AA 581 ldr r3, [rSELF, #offThread_exception] @ r3<- dvmGetException bypass 582 mov r1, #0 @ r1<- 0 583 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 584 SET_VREG(r3, r2) @ fp[AA]<- exception obj 585 GET_INST_OPCODE(ip) @ extract opcode from rINST 586 str r1, [rSELF, #offThread_exception] @ dvmClearException bypass 587 GOTO_OPCODE(ip) @ jump to next instruction 588 589 /* ------------------------------ */ 590 .balign 64 591 .L_OP_RETURN_VOID: /* 0x0e */ 592 /* File: armv5te/OP_RETURN_VOID.S */ 593 b common_returnFromMethod 594 595 /* ------------------------------ */ 596 .balign 64 597 .L_OP_RETURN: /* 0x0f */ 598 /* File: armv5te/OP_RETURN.S */ 599 /* 600 * Return a 32-bit value. Copies the return value into the "thread" 601 * structure, then jumps to the return handler. 602 * 603 * for: return, return-object 604 */ 605 /* op vAA */ 606 mov r2, rINST, lsr #8 @ r2<- AA 607 GET_VREG(r0, r2) @ r0<- vAA 608 str r0, [rSELF, #offThread_retval] @ retval.i <- vAA 609 b common_returnFromMethod 610 611 /* ------------------------------ */ 612 .balign 64 613 .L_OP_RETURN_WIDE: /* 0x10 */ 614 /* File: armv5te/OP_RETURN_WIDE.S */ 615 /* 616 * Return a 64-bit value. Copies the return value into the "thread" 617 * structure, then jumps to the return handler. 618 */ 619 /* return-wide vAA */ 620 mov r2, rINST, lsr #8 @ r2<- AA 621 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 622 add r3, rSELF, #offThread_retval @ r3<- &self->retval 623 ldmia r2, {r0-r1} @ r0/r1 <- vAA/vAA+1 624 stmia r3, {r0-r1} @ retval<- r0/r1 625 b common_returnFromMethod 626 627 /* ------------------------------ */ 628 .balign 64 629 .L_OP_RETURN_OBJECT: /* 0x11 */ 630 /* File: armv5te/OP_RETURN_OBJECT.S */ 631 /* File: armv5te/OP_RETURN.S */ 632 /* 633 * Return a 32-bit value. Copies the return value into the "thread" 634 * structure, then jumps to the return handler. 635 * 636 * for: return, return-object 637 */ 638 /* op vAA */ 639 mov r2, rINST, lsr #8 @ r2<- AA 640 GET_VREG(r0, r2) @ r0<- vAA 641 str r0, [rSELF, #offThread_retval] @ retval.i <- vAA 642 b common_returnFromMethod 643 644 645 /* ------------------------------ */ 646 .balign 64 647 .L_OP_CONST_4: /* 0x12 */ 648 /* File: armv6t2/OP_CONST_4.S */ 649 /* const/4 vA, #+B */ 650 mov r1, rINST, lsl #16 @ r1<- Bxxx0000 651 ubfx r0, rINST, #8, #4 @ r0<- A 652 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 653 mov r1, r1, asr #28 @ r1<- sssssssB (sign-extended) 654 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 655 SET_VREG(r1, r0) @ fp[A]<- r1 656 GOTO_OPCODE(ip) @ execute next instruction 657 658 /* ------------------------------ */ 659 .balign 64 660 .L_OP_CONST_16: /* 0x13 */ 661 /* File: armv5te/OP_CONST_16.S */ 662 /* const/16 vAA, #+BBBB */ 663 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 664 mov r3, rINST, lsr #8 @ r3<- AA 665 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 666 SET_VREG(r0, r3) @ vAA<- r0 667 GET_INST_OPCODE(ip) @ extract opcode from rINST 668 GOTO_OPCODE(ip) @ jump to next instruction 669 670 /* ------------------------------ */ 671 .balign 64 672 .L_OP_CONST: /* 0x14 */ 673 /* File: armv5te/OP_CONST.S */ 674 /* const vAA, #+BBBBbbbb */ 675 mov r3, rINST, lsr #8 @ r3<- AA 676 FETCH(r0, 1) @ r0<- bbbb (low) 677 FETCH(r1, 2) @ r1<- BBBB (high) 678 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 679 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 680 GET_INST_OPCODE(ip) @ extract opcode from rINST 681 SET_VREG(r0, r3) @ vAA<- r0 682 GOTO_OPCODE(ip) @ jump to next instruction 683 684 /* ------------------------------ */ 685 .balign 64 686 .L_OP_CONST_HIGH16: /* 0x15 */ 687 /* File: armv5te/OP_CONST_HIGH16.S */ 688 /* const/high16 vAA, #+BBBB0000 */ 689 FETCH(r0, 1) @ r0<- 0000BBBB (zero-extended) 690 mov r3, rINST, lsr #8 @ r3<- AA 691 mov r0, r0, lsl #16 @ r0<- BBBB0000 692 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 693 SET_VREG(r0, r3) @ vAA<- r0 694 GET_INST_OPCODE(ip) @ extract opcode from rINST 695 GOTO_OPCODE(ip) @ jump to next instruction 696 697 /* ------------------------------ */ 698 .balign 64 699 .L_OP_CONST_WIDE_16: /* 0x16 */ 700 /* File: armv5te/OP_CONST_WIDE_16.S */ 701 /* const-wide/16 vAA, #+BBBB */ 702 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 703 mov r3, rINST, lsr #8 @ r3<- AA 704 mov r1, r0, asr #31 @ r1<- ssssssss 705 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 706 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 707 GET_INST_OPCODE(ip) @ extract opcode from rINST 708 stmia r3, {r0-r1} @ vAA<- r0/r1 709 GOTO_OPCODE(ip) @ jump to next instruction 710 711 /* ------------------------------ */ 712 .balign 64 713 .L_OP_CONST_WIDE_32: /* 0x17 */ 714 /* File: armv5te/OP_CONST_WIDE_32.S */ 715 /* const-wide/32 vAA, #+BBBBbbbb */ 716 FETCH(r0, 1) @ r0<- 0000bbbb (low) 717 mov r3, rINST, lsr #8 @ r3<- AA 718 FETCH_S(r2, 2) @ r2<- ssssBBBB (high) 719 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 720 orr r0, r0, r2, lsl #16 @ r0<- BBBBbbbb 721 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 722 mov r1, r0, asr #31 @ r1<- ssssssss 723 GET_INST_OPCODE(ip) @ extract opcode from rINST 724 stmia r3, {r0-r1} @ vAA<- r0/r1 725 GOTO_OPCODE(ip) @ jump to next instruction 726 727 /* ------------------------------ */ 728 .balign 64 729 .L_OP_CONST_WIDE: /* 0x18 */ 730 /* File: armv5te/OP_CONST_WIDE.S */ 731 /* const-wide vAA, #+HHHHhhhhBBBBbbbb */ 732 FETCH(r0, 1) @ r0<- bbbb (low) 733 FETCH(r1, 2) @ r1<- BBBB (low middle) 734 FETCH(r2, 3) @ r2<- hhhh (high middle) 735 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb (low word) 736 FETCH(r3, 4) @ r3<- HHHH (high) 737 mov r9, rINST, lsr #8 @ r9<- AA 738 orr r1, r2, r3, lsl #16 @ r1<- HHHHhhhh (high word) 739 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 740 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 741 GET_INST_OPCODE(ip) @ extract opcode from rINST 742 stmia r9, {r0-r1} @ vAA<- r0/r1 743 GOTO_OPCODE(ip) @ jump to next instruction 744 745 /* ------------------------------ */ 746 .balign 64 747 .L_OP_CONST_WIDE_HIGH16: /* 0x19 */ 748 /* File: armv5te/OP_CONST_WIDE_HIGH16.S */ 749 /* const-wide/high16 vAA, #+BBBB000000000000 */ 750 FETCH(r1, 1) @ r1<- 0000BBBB (zero-extended) 751 mov r3, rINST, lsr #8 @ r3<- AA 752 mov r0, #0 @ r0<- 00000000 753 mov r1, r1, lsl #16 @ r1<- BBBB0000 754 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 755 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 756 GET_INST_OPCODE(ip) @ extract opcode from rINST 757 stmia r3, {r0-r1} @ vAA<- r0/r1 758 GOTO_OPCODE(ip) @ jump to next instruction 759 760 /* ------------------------------ */ 761 .balign 64 762 .L_OP_CONST_STRING: /* 0x1a */ 763 /* File: armv5te/OP_CONST_STRING.S */ 764 /* const/string vAA, String@BBBB */ 765 FETCH(r1, 1) @ r1<- BBBB 766 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 767 mov r9, rINST, lsr #8 @ r9<- AA 768 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 769 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 770 cmp r0, #0 @ not yet resolved? 771 beq .LOP_CONST_STRING_resolve 772 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 773 GET_INST_OPCODE(ip) @ extract opcode from rINST 774 SET_VREG(r0, r9) @ vAA<- r0 775 GOTO_OPCODE(ip) @ jump to next instruction 776 777 /* ------------------------------ */ 778 .balign 64 779 .L_OP_CONST_STRING_JUMBO: /* 0x1b */ 780 /* File: armv5te/OP_CONST_STRING_JUMBO.S */ 781 /* const/string vAA, String@BBBBBBBB */ 782 FETCH(r0, 1) @ r0<- bbbb (low) 783 FETCH(r1, 2) @ r1<- BBBB (high) 784 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 785 mov r9, rINST, lsr #8 @ r9<- AA 786 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 787 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 788 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 789 cmp r0, #0 790 beq .LOP_CONST_STRING_JUMBO_resolve 791 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 792 GET_INST_OPCODE(ip) @ extract opcode from rINST 793 SET_VREG(r0, r9) @ vAA<- r0 794 GOTO_OPCODE(ip) @ jump to next instruction 795 796 /* ------------------------------ */ 797 .balign 64 798 .L_OP_CONST_CLASS: /* 0x1c */ 799 /* File: armv5te/OP_CONST_CLASS.S */ 800 /* const/class vAA, Class@BBBB */ 801 FETCH(r1, 1) @ r1<- BBBB 802 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 803 mov r9, rINST, lsr #8 @ r9<- AA 804 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- dvmDex->pResClasses 805 ldr r0, [r2, r1, lsl #2] @ r0<- pResClasses[BBBB] 806 cmp r0, #0 @ not yet resolved? 807 beq .LOP_CONST_CLASS_resolve 808 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 809 GET_INST_OPCODE(ip) @ extract opcode from rINST 810 SET_VREG(r0, r9) @ vAA<- r0 811 GOTO_OPCODE(ip) @ jump to next instruction 812 813 /* ------------------------------ */ 814 .balign 64 815 .L_OP_MONITOR_ENTER: /* 0x1d */ 816 /* File: armv5te/OP_MONITOR_ENTER.S */ 817 /* 818 * Synchronize on an object. 819 */ 820 /* monitor-enter vAA */ 821 mov r2, rINST, lsr #8 @ r2<- AA 822 GET_VREG(r1, r2) @ r1<- vAA (object) 823 mov r0, rSELF @ r0<- self 824 cmp r1, #0 @ null object? 825 EXPORT_PC() @ need for precise GC 826 beq common_errNullObject @ null object, throw an exception 827 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 828 bl dvmLockObject @ call(self, obj) 829 GET_INST_OPCODE(ip) @ extract opcode from rINST 830 GOTO_OPCODE(ip) @ jump to next instruction 831 832 /* ------------------------------ */ 833 .balign 64 834 .L_OP_MONITOR_EXIT: /* 0x1e */ 835 /* File: armv5te/OP_MONITOR_EXIT.S */ 836 /* 837 * Unlock an object. 838 * 839 * Exceptions that occur when unlocking a monitor need to appear as 840 * if they happened at the following instruction. See the Dalvik 841 * instruction spec. 842 */ 843 /* monitor-exit vAA */ 844 mov r2, rINST, lsr #8 @ r2<- AA 845 EXPORT_PC() @ before fetch: export the PC 846 GET_VREG(r1, r2) @ r1<- vAA (object) 847 cmp r1, #0 @ null object? 848 beq 1f @ yes 849 mov r0, rSELF @ r0<- self 850 bl dvmUnlockObject @ r0<- success for unlock(self, obj) 851 cmp r0, #0 @ failed? 852 FETCH_ADVANCE_INST(1) @ before throw: advance rPC, load rINST 853 beq common_exceptionThrown @ yes, exception is pending 854 GET_INST_OPCODE(ip) @ extract opcode from rINST 855 GOTO_OPCODE(ip) @ jump to next instruction 856 1: 857 FETCH_ADVANCE_INST(1) @ advance before throw 858 b common_errNullObject 859 860 /* ------------------------------ */ 861 .balign 64 862 .L_OP_CHECK_CAST: /* 0x1f */ 863 /* File: armv5te/OP_CHECK_CAST.S */ 864 /* 865 * Check to see if a cast from one class to another is allowed. 866 */ 867 /* check-cast vAA, class@BBBB */ 868 mov r3, rINST, lsr #8 @ r3<- AA 869 FETCH(r2, 1) @ r2<- BBBB 870 GET_VREG(r9, r3) @ r9<- object 871 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- pDvmDex 872 cmp r9, #0 @ is object null? 873 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 874 beq .LOP_CHECK_CAST_okay @ null obj, cast always succeeds 875 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 876 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 877 cmp r1, #0 @ have we resolved this before? 878 beq .LOP_CHECK_CAST_resolve @ not resolved, do it now 879 .LOP_CHECK_CAST_resolved: 880 cmp r0, r1 @ same class (trivial success)? 881 bne .LOP_CHECK_CAST_fullcheck @ no, do full check 882 .LOP_CHECK_CAST_okay: 883 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 884 GET_INST_OPCODE(ip) @ extract opcode from rINST 885 GOTO_OPCODE(ip) @ jump to next instruction 886 887 /* ------------------------------ */ 888 .balign 64 889 .L_OP_INSTANCE_OF: /* 0x20 */ 890 /* File: armv5te/OP_INSTANCE_OF.S */ 891 /* 892 * Check to see if an object reference is an instance of a class. 893 * 894 * Most common situation is a non-null object, being compared against 895 * an already-resolved class. 896 */ 897 /* instance-of vA, vB, class@CCCC */ 898 mov r3, rINST, lsr #12 @ r3<- B 899 mov r9, rINST, lsr #8 @ r9<- A+ 900 GET_VREG(r0, r3) @ r0<- vB (object) 901 and r9, r9, #15 @ r9<- A 902 cmp r0, #0 @ is object null? 903 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- pDvmDex 904 beq .LOP_INSTANCE_OF_store @ null obj, not an instance, store r0 905 FETCH(r3, 1) @ r3<- CCCC 906 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 907 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 908 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 909 cmp r1, #0 @ have we resolved this before? 910 beq .LOP_INSTANCE_OF_resolve @ not resolved, do it now 911 .LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class 912 cmp r0, r1 @ same class (trivial success)? 913 beq .LOP_INSTANCE_OF_trivial @ yes, trivial finish 914 b .LOP_INSTANCE_OF_fullcheck @ no, do full check 915 916 /* ------------------------------ */ 917 .balign 64 918 .L_OP_ARRAY_LENGTH: /* 0x21 */ 919 /* File: armv6t2/OP_ARRAY_LENGTH.S */ 920 /* 921 * Return the length of an array. 922 */ 923 mov r1, rINST, lsr #12 @ r1<- B 924 ubfx r2, rINST, #8, #4 @ r2<- A 925 GET_VREG(r0, r1) @ r0<- vB (object ref) 926 cmp r0, #0 @ is object null? 927 beq common_errNullObject @ yup, fail 928 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 929 ldr r3, [r0, #offArrayObject_length] @ r3<- array length 930 GET_INST_OPCODE(ip) @ extract opcode from rINST 931 SET_VREG(r3, r2) @ vB<- length 932 GOTO_OPCODE(ip) @ jump to next instruction 933 934 /* ------------------------------ */ 935 .balign 64 936 .L_OP_NEW_INSTANCE: /* 0x22 */ 937 /* File: armv5te/OP_NEW_INSTANCE.S */ 938 /* 939 * Create a new instance of a class. 940 */ 941 /* new-instance vAA, class@BBBB */ 942 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 943 FETCH(r1, 1) @ r1<- BBBB 944 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 945 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 946 #if defined(WITH_JIT) 947 add r10, r3, r1, lsl #2 @ r10<- &resolved_class 948 #endif 949 EXPORT_PC() @ req'd for init, resolve, alloc 950 cmp r0, #0 @ already resolved? 951 beq .LOP_NEW_INSTANCE_resolve @ no, resolve it now 952 .LOP_NEW_INSTANCE_resolved: @ r0=class 953 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 954 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 955 bne .LOP_NEW_INSTANCE_needinit @ no, init class now 956 .LOP_NEW_INSTANCE_initialized: @ r0=class 957 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 958 bl dvmAllocObject @ r0<- new object 959 b .LOP_NEW_INSTANCE_finish @ continue 960 961 /* ------------------------------ */ 962 .balign 64 963 .L_OP_NEW_ARRAY: /* 0x23 */ 964 /* File: armv5te/OP_NEW_ARRAY.S */ 965 /* 966 * Allocate an array of objects, specified with the array class 967 * and a count. 968 * 969 * The verifier guarantees that this is an array class, so we don't 970 * check for it here. 971 */ 972 /* new-array vA, vB, class@CCCC */ 973 mov r0, rINST, lsr #12 @ r0<- B 974 FETCH(r2, 1) @ r2<- CCCC 975 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 976 GET_VREG(r1, r0) @ r1<- vB (array length) 977 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 978 cmp r1, #0 @ check length 979 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 980 bmi common_errNegativeArraySize @ negative length, bail - len in r1 981 cmp r0, #0 @ already resolved? 982 EXPORT_PC() @ req'd for resolve, alloc 983 bne .LOP_NEW_ARRAY_finish @ resolved, continue 984 b .LOP_NEW_ARRAY_resolve @ do resolve now 985 986 /* ------------------------------ */ 987 .balign 64 988 .L_OP_FILLED_NEW_ARRAY: /* 0x24 */ 989 /* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 990 /* 991 * Create a new array with elements filled from registers. 992 * 993 * for: filled-new-array, filled-new-array/range 994 */ 995 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 996 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 997 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 998 FETCH(r1, 1) @ r1<- BBBB 999 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1000 EXPORT_PC() @ need for resolve and alloc 1001 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1002 mov r10, rINST, lsr #8 @ r10<- AA or BA 1003 cmp r0, #0 @ already resolved? 1004 bne .LOP_FILLED_NEW_ARRAY_continue @ yes, continue on 1005 8: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 1006 mov r2, #0 @ r2<- false 1007 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1008 bl dvmResolveClass @ r0<- call(clazz, ref) 1009 cmp r0, #0 @ got null? 1010 beq common_exceptionThrown @ yes, handle exception 1011 b .LOP_FILLED_NEW_ARRAY_continue 1012 1013 /* ------------------------------ */ 1014 .balign 64 1015 .L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 1016 /* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */ 1017 /* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1018 /* 1019 * Create a new array with elements filled from registers. 1020 * 1021 * for: filled-new-array, filled-new-array/range 1022 */ 1023 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1024 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1025 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 1026 FETCH(r1, 1) @ r1<- BBBB 1027 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1028 EXPORT_PC() @ need for resolve and alloc 1029 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1030 mov r10, rINST, lsr #8 @ r10<- AA or BA 1031 cmp r0, #0 @ already resolved? 1032 bne .LOP_FILLED_NEW_ARRAY_RANGE_continue @ yes, continue on 1033 8: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 1034 mov r2, #0 @ r2<- false 1035 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1036 bl dvmResolveClass @ r0<- call(clazz, ref) 1037 cmp r0, #0 @ got null? 1038 beq common_exceptionThrown @ yes, handle exception 1039 b .LOP_FILLED_NEW_ARRAY_RANGE_continue 1040 1041 1042 /* ------------------------------ */ 1043 .balign 64 1044 .L_OP_FILL_ARRAY_DATA: /* 0x26 */ 1045 /* File: armv5te/OP_FILL_ARRAY_DATA.S */ 1046 /* fill-array-data vAA, +BBBBBBBB */ 1047 FETCH(r0, 1) @ r0<- bbbb (lo) 1048 FETCH(r1, 2) @ r1<- BBBB (hi) 1049 mov r3, rINST, lsr #8 @ r3<- AA 1050 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 1051 GET_VREG(r0, r3) @ r0<- vAA (array object) 1052 add r1, rPC, r1, lsl #1 @ r1<- PC + BBBBbbbb*2 (array data off.) 1053 EXPORT_PC(); 1054 bl dvmInterpHandleFillArrayData@ fill the array with predefined data 1055 cmp r0, #0 @ 0 means an exception is thrown 1056 beq common_exceptionThrown @ has exception 1057 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 1058 GET_INST_OPCODE(ip) @ extract opcode from rINST 1059 GOTO_OPCODE(ip) @ jump to next instruction 1060 1061 /* ------------------------------ */ 1062 .balign 64 1063 .L_OP_THROW: /* 0x27 */ 1064 /* File: armv5te/OP_THROW.S */ 1065 /* 1066 * Throw an exception object in the current thread. 1067 */ 1068 /* throw vAA */ 1069 mov r2, rINST, lsr #8 @ r2<- AA 1070 GET_VREG(r1, r2) @ r1<- vAA (exception object) 1071 EXPORT_PC() @ exception handler can throw 1072 cmp r1, #0 @ null object? 1073 beq common_errNullObject @ yes, throw an NPE instead 1074 @ bypass dvmSetException, just store it 1075 str r1, [rSELF, #offThread_exception] @ thread->exception<- obj 1076 b common_exceptionThrown 1077 1078 /* ------------------------------ */ 1079 .balign 64 1080 .L_OP_GOTO: /* 0x28 */ 1081 /* File: armv5te/OP_GOTO.S */ 1082 /* 1083 * Unconditional branch, 8-bit offset. 1084 * 1085 * The branch distance is a signed code-unit offset, which we need to 1086 * double to get a byte offset. 1087 */ 1088 /* goto +AA */ 1089 /* tuning: use sbfx for 6t2+ targets */ 1090 mov r0, rINST, lsl #16 @ r0<- AAxx0000 1091 movs r1, r0, asr #24 @ r1<- ssssssAA (sign-extended) 1092 add r2, r1, r1 @ r2<- byte offset, set flags 1093 @ If backwards branch refresh rIBASE 1094 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1095 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1096 #if defined(WITH_JIT) 1097 ldr r0, [rSELF, #offThread_pJitProfTable] 1098 bmi common_testUpdateProfile @ (r0) check for trace hotness 1099 #endif 1100 GET_INST_OPCODE(ip) @ extract opcode from rINST 1101 GOTO_OPCODE(ip) @ jump to next instruction 1102 1103 /* ------------------------------ */ 1104 .balign 64 1105 .L_OP_GOTO_16: /* 0x29 */ 1106 /* File: armv5te/OP_GOTO_16.S */ 1107 /* 1108 * Unconditional branch, 16-bit offset. 1109 * 1110 * The branch distance is a signed code-unit offset, which we need to 1111 * double to get a byte offset. 1112 */ 1113 /* goto/16 +AAAA */ 1114 FETCH_S(r0, 1) @ r0<- ssssAAAA (sign-extended) 1115 adds r1, r0, r0 @ r1<- byte offset, flags set 1116 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1117 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1118 #if defined(WITH_JIT) 1119 ldr r0, [rSELF, #offThread_pJitProfTable] 1120 bmi common_testUpdateProfile @ (r0) hot trace head? 1121 #endif 1122 GET_INST_OPCODE(ip) @ extract opcode from rINST 1123 GOTO_OPCODE(ip) @ jump to next instruction 1124 1125 /* ------------------------------ */ 1126 .balign 64 1127 .L_OP_GOTO_32: /* 0x2a */ 1128 /* File: armv5te/OP_GOTO_32.S */ 1129 /* 1130 * Unconditional branch, 32-bit offset. 1131 * 1132 * The branch distance is a signed code-unit offset, which we need to 1133 * double to get a byte offset. 1134 * 1135 * Unlike most opcodes, this one is allowed to branch to itself, so 1136 * our "backward branch" test must be "<=0" instead of "<0". Because 1137 * we need the V bit set, we'll use an adds to convert from Dalvik 1138 * offset to byte offset. 1139 */ 1140 /* goto/32 +AAAAAAAA */ 1141 FETCH(r0, 1) @ r0<- aaaa (lo) 1142 FETCH(r1, 2) @ r1<- AAAA (hi) 1143 orr r0, r0, r1, lsl #16 @ r0<- AAAAaaaa 1144 adds r1, r0, r0 @ r1<- byte offset 1145 #if defined(WITH_JIT) 1146 ldr r0, [rSELF, #offThread_pJitProfTable] 1147 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1148 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1149 ble common_testUpdateProfile @ (r0) hot trace head? 1150 #else 1151 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1152 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1153 #endif 1154 GET_INST_OPCODE(ip) @ extract opcode from rINST 1155 GOTO_OPCODE(ip) @ jump to next instruction 1156 1157 /* ------------------------------ */ 1158 .balign 64 1159 .L_OP_PACKED_SWITCH: /* 0x2b */ 1160 /* File: armv5te/OP_PACKED_SWITCH.S */ 1161 /* 1162 * Handle a packed-switch or sparse-switch instruction. In both cases 1163 * we decode it and hand it off to a helper function. 1164 * 1165 * We don't really expect backward branches in a switch statement, but 1166 * they're perfectly legal, so we check for them here. 1167 * 1168 * When the JIT is present, all targets are considered treated as 1169 * a potential trace heads regardless of branch direction. 1170 * 1171 * for: packed-switch, sparse-switch 1172 */ 1173 /* op vAA, +BBBB */ 1174 FETCH(r0, 1) @ r0<- bbbb (lo) 1175 FETCH(r1, 2) @ r1<- BBBB (hi) 1176 mov r3, rINST, lsr #8 @ r3<- AA 1177 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1178 GET_VREG(r1, r3) @ r1<- vAA 1179 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1180 bl dvmInterpHandlePackedSwitch @ r0<- code-unit branch offset 1181 adds r1, r0, r0 @ r1<- byte offset; clear V 1182 #if defined(WITH_JIT) 1183 ldr r0, [rSELF, #offThread_pJitProfTable] 1184 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1185 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1186 cmp r0, #0 1187 bne common_updateProfile 1188 #else 1189 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1190 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1191 #endif 1192 GET_INST_OPCODE(ip) @ extract opcode from rINST 1193 GOTO_OPCODE(ip) @ jump to next instruction 1194 1195 /* ------------------------------ */ 1196 .balign 64 1197 .L_OP_SPARSE_SWITCH: /* 0x2c */ 1198 /* File: armv5te/OP_SPARSE_SWITCH.S */ 1199 /* File: armv5te/OP_PACKED_SWITCH.S */ 1200 /* 1201 * Handle a packed-switch or sparse-switch instruction. In both cases 1202 * we decode it and hand it off to a helper function. 1203 * 1204 * We don't really expect backward branches in a switch statement, but 1205 * they're perfectly legal, so we check for them here. 1206 * 1207 * When the JIT is present, all targets are considered treated as 1208 * a potential trace heads regardless of branch direction. 1209 * 1210 * for: packed-switch, sparse-switch 1211 */ 1212 /* op vAA, +BBBB */ 1213 FETCH(r0, 1) @ r0<- bbbb (lo) 1214 FETCH(r1, 2) @ r1<- BBBB (hi) 1215 mov r3, rINST, lsr #8 @ r3<- AA 1216 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1217 GET_VREG(r1, r3) @ r1<- vAA 1218 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1219 bl dvmInterpHandleSparseSwitch @ r0<- code-unit branch offset 1220 adds r1, r0, r0 @ r1<- byte offset; clear V 1221 #if defined(WITH_JIT) 1222 ldr r0, [rSELF, #offThread_pJitProfTable] 1223 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1224 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1225 cmp r0, #0 1226 bne common_updateProfile 1227 #else 1228 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1229 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1230 #endif 1231 GET_INST_OPCODE(ip) @ extract opcode from rINST 1232 GOTO_OPCODE(ip) @ jump to next instruction 1233 1234 1235 /* ------------------------------ */ 1236 .balign 64 1237 .L_OP_CMPL_FLOAT: /* 0x2d */ 1238 /* File: arm-vfp/OP_CMPL_FLOAT.S */ 1239 /* 1240 * Compare two floating-point values. Puts 0, 1, or -1 into the 1241 * destination register based on the results of the comparison. 1242 * 1243 * int compare(x, y) { 1244 * if (x == y) { 1245 * return 0; 1246 * } else if (x > y) { 1247 * return 1; 1248 * } else if (x < y) { 1249 * return -1; 1250 * } else { 1251 * return -1; 1252 * } 1253 * } 1254 */ 1255 /* op vAA, vBB, vCC */ 1256 FETCH(r0, 1) @ r0<- CCBB 1257 mov r9, rINST, lsr #8 @ r9<- AA 1258 and r2, r0, #255 @ r2<- BB 1259 mov r3, r0, lsr #8 @ r3<- CC 1260 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1261 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1262 flds s0, [r2] @ s0<- vBB 1263 flds s1, [r3] @ s1<- vCC 1264 fcmpes s0, s1 @ compare (vBB, vCC) 1265 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1266 mvn r0, #0 @ r0<- -1 (default) 1267 GET_INST_OPCODE(ip) @ extract opcode from rINST 1268 fmstat @ export status flags 1269 movgt r0, #1 @ (greater than) r1<- 1 1270 moveq r0, #0 @ (equal) r1<- 0 1271 b .LOP_CMPL_FLOAT_finish @ argh 1272 1273 1274 /* ------------------------------ */ 1275 .balign 64 1276 .L_OP_CMPG_FLOAT: /* 0x2e */ 1277 /* File: arm-vfp/OP_CMPG_FLOAT.S */ 1278 /* 1279 * Compare two floating-point values. Puts 0, 1, or -1 into the 1280 * destination register based on the results of the comparison. 1281 * 1282 * int compare(x, y) { 1283 * if (x == y) { 1284 * return 0; 1285 * } else if (x < y) { 1286 * return -1; 1287 * } else if (x > y) { 1288 * return 1; 1289 * } else { 1290 * return 1; 1291 * } 1292 * } 1293 */ 1294 /* op vAA, vBB, vCC */ 1295 FETCH(r0, 1) @ r0<- CCBB 1296 mov r9, rINST, lsr #8 @ r9<- AA 1297 and r2, r0, #255 @ r2<- BB 1298 mov r3, r0, lsr #8 @ r3<- CC 1299 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1300 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1301 flds s0, [r2] @ s0<- vBB 1302 flds s1, [r3] @ s1<- vCC 1303 fcmpes s0, s1 @ compare (vBB, vCC) 1304 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1305 mov r0, #1 @ r0<- 1 (default) 1306 GET_INST_OPCODE(ip) @ extract opcode from rINST 1307 fmstat @ export status flags 1308 mvnmi r0, #0 @ (less than) r1<- -1 1309 moveq r0, #0 @ (equal) r1<- 0 1310 b .LOP_CMPG_FLOAT_finish @ argh 1311 1312 1313 /* ------------------------------ */ 1314 .balign 64 1315 .L_OP_CMPL_DOUBLE: /* 0x2f */ 1316 /* File: arm-vfp/OP_CMPL_DOUBLE.S */ 1317 /* 1318 * Compare two floating-point values. Puts 0, 1, or -1 into the 1319 * destination register based on the results of the comparison. 1320 * 1321 * int compare(x, y) { 1322 * if (x == y) { 1323 * return 0; 1324 * } else if (x > y) { 1325 * return 1; 1326 * } else if (x < y) { 1327 * return -1; 1328 * } else { 1329 * return -1; 1330 * } 1331 * } 1332 */ 1333 /* op vAA, vBB, vCC */ 1334 FETCH(r0, 1) @ r0<- CCBB 1335 mov r9, rINST, lsr #8 @ r9<- AA 1336 and r2, r0, #255 @ r2<- BB 1337 mov r3, r0, lsr #8 @ r3<- CC 1338 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1339 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1340 fldd d0, [r2] @ d0<- vBB 1341 fldd d1, [r3] @ d1<- vCC 1342 fcmped d0, d1 @ compare (vBB, vCC) 1343 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1344 mvn r0, #0 @ r0<- -1 (default) 1345 GET_INST_OPCODE(ip) @ extract opcode from rINST 1346 fmstat @ export status flags 1347 movgt r0, #1 @ (greater than) r1<- 1 1348 moveq r0, #0 @ (equal) r1<- 0 1349 b .LOP_CMPL_DOUBLE_finish @ argh 1350 1351 1352 /* ------------------------------ */ 1353 .balign 64 1354 .L_OP_CMPG_DOUBLE: /* 0x30 */ 1355 /* File: arm-vfp/OP_CMPG_DOUBLE.S */ 1356 /* 1357 * Compare two floating-point values. Puts 0, 1, or -1 into the 1358 * destination register based on the results of the comparison. 1359 * 1360 * int compare(x, y) { 1361 * if (x == y) { 1362 * return 0; 1363 * } else if (x < y) { 1364 * return -1; 1365 * } else if (x > y) { 1366 * return 1; 1367 * } else { 1368 * return 1; 1369 * } 1370 * } 1371 */ 1372 /* op vAA, vBB, vCC */ 1373 FETCH(r0, 1) @ r0<- CCBB 1374 mov r9, rINST, lsr #8 @ r9<- AA 1375 and r2, r0, #255 @ r2<- BB 1376 mov r3, r0, lsr #8 @ r3<- CC 1377 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1378 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1379 fldd d0, [r2] @ d0<- vBB 1380 fldd d1, [r3] @ d1<- vCC 1381 fcmped d0, d1 @ compare (vBB, vCC) 1382 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1383 mov r0, #1 @ r0<- 1 (default) 1384 GET_INST_OPCODE(ip) @ extract opcode from rINST 1385 fmstat @ export status flags 1386 mvnmi r0, #0 @ (less than) r1<- -1 1387 moveq r0, #0 @ (equal) r1<- 0 1388 b .LOP_CMPG_DOUBLE_finish @ argh 1389 1390 1391 /* ------------------------------ */ 1392 .balign 64 1393 .L_OP_CMP_LONG: /* 0x31 */ 1394 /* File: armv5te/OP_CMP_LONG.S */ 1395 /* 1396 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 1397 * register based on the results of the comparison. 1398 * 1399 * We load the full values with LDM, but in practice many values could 1400 * be resolved by only looking at the high word. This could be made 1401 * faster or slower by splitting the LDM into a pair of LDRs. 1402 * 1403 * If we just wanted to set condition flags, we could do this: 1404 * subs ip, r0, r2 1405 * sbcs ip, r1, r3 1406 * subeqs ip, r0, r2 1407 * Leaving { <0, 0, >0 } in ip. However, we have to set it to a specific 1408 * integer value, which we can do with 2 conditional mov/mvn instructions 1409 * (set 1, set -1; if they're equal we already have 0 in ip), giving 1410 * us a constant 5-cycle path plus a branch at the end to the 1411 * instruction epilogue code. The multi-compare approach below needs 1412 * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch 1413 * in the worst case (the 64-bit values are equal). 1414 */ 1415 /* cmp-long vAA, vBB, vCC */ 1416 FETCH(r0, 1) @ r0<- CCBB 1417 mov r9, rINST, lsr #8 @ r9<- AA 1418 and r2, r0, #255 @ r2<- BB 1419 mov r3, r0, lsr #8 @ r3<- CC 1420 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 1421 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 1422 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 1423 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 1424 cmp r1, r3 @ compare (vBB+1, vCC+1) 1425 blt .LOP_CMP_LONG_less @ signed compare on high part 1426 bgt .LOP_CMP_LONG_greater 1427 subs r1, r0, r2 @ r1<- r0 - r2 1428 bhi .LOP_CMP_LONG_greater @ unsigned compare on low part 1429 bne .LOP_CMP_LONG_less 1430 b .LOP_CMP_LONG_finish @ equal; r1 already holds 0 1431 1432 /* ------------------------------ */ 1433 .balign 64 1434 .L_OP_IF_EQ: /* 0x32 */ 1435 /* File: armv6t2/OP_IF_EQ.S */ 1436 /* File: armv6t2/bincmp.S */ 1437 /* 1438 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1439 * fragment that specifies the *reverse* comparison to perform, e.g. 1440 * for "if-le" you would use "gt". 1441 * 1442 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1443 */ 1444 /* if-cmp vA, vB, +CCCC */ 1445 mov r1, rINST, lsr #12 @ r1<- B 1446 ubfx r0, rINST, #8, #4 @ r0<- A 1447 GET_VREG(r3, r1) @ r3<- vB 1448 GET_VREG(r2, r0) @ r2<- vA 1449 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1450 cmp r2, r3 @ compare (vA, vB) 1451 movne r1, #2 @ r1<- BYTE branch dist for not-taken 1452 adds r2, r1, r1 @ convert to bytes, check sign 1453 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1454 #if defined(WITH_JIT) 1455 ldr r0, [rSELF, #offThread_pJitProfTable] 1456 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1457 cmp r0, #0 1458 bne common_updateProfile 1459 #else 1460 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1461 #endif 1462 GET_INST_OPCODE(ip) @ extract opcode from rINST 1463 GOTO_OPCODE(ip) @ jump to next instruction 1464 1465 1466 /* ------------------------------ */ 1467 .balign 64 1468 .L_OP_IF_NE: /* 0x33 */ 1469 /* File: armv6t2/OP_IF_NE.S */ 1470 /* File: armv6t2/bincmp.S */ 1471 /* 1472 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1473 * fragment that specifies the *reverse* comparison to perform, e.g. 1474 * for "if-le" you would use "gt". 1475 * 1476 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1477 */ 1478 /* if-cmp vA, vB, +CCCC */ 1479 mov r1, rINST, lsr #12 @ r1<- B 1480 ubfx r0, rINST, #8, #4 @ r0<- A 1481 GET_VREG(r3, r1) @ r3<- vB 1482 GET_VREG(r2, r0) @ r2<- vA 1483 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1484 cmp r2, r3 @ compare (vA, vB) 1485 moveq r1, #2 @ r1<- BYTE branch dist for not-taken 1486 adds r2, r1, r1 @ convert to bytes, check sign 1487 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1488 #if defined(WITH_JIT) 1489 ldr r0, [rSELF, #offThread_pJitProfTable] 1490 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1491 cmp r0, #0 1492 bne common_updateProfile 1493 #else 1494 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1495 #endif 1496 GET_INST_OPCODE(ip) @ extract opcode from rINST 1497 GOTO_OPCODE(ip) @ jump to next instruction 1498 1499 1500 /* ------------------------------ */ 1501 .balign 64 1502 .L_OP_IF_LT: /* 0x34 */ 1503 /* File: armv6t2/OP_IF_LT.S */ 1504 /* File: armv6t2/bincmp.S */ 1505 /* 1506 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1507 * fragment that specifies the *reverse* comparison to perform, e.g. 1508 * for "if-le" you would use "gt". 1509 * 1510 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1511 */ 1512 /* if-cmp vA, vB, +CCCC */ 1513 mov r1, rINST, lsr #12 @ r1<- B 1514 ubfx r0, rINST, #8, #4 @ r0<- A 1515 GET_VREG(r3, r1) @ r3<- vB 1516 GET_VREG(r2, r0) @ r2<- vA 1517 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1518 cmp r2, r3 @ compare (vA, vB) 1519 movge r1, #2 @ r1<- BYTE branch dist for not-taken 1520 adds r2, r1, r1 @ convert to bytes, check sign 1521 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1522 #if defined(WITH_JIT) 1523 ldr r0, [rSELF, #offThread_pJitProfTable] 1524 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1525 cmp r0, #0 1526 bne common_updateProfile 1527 #else 1528 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1529 #endif 1530 GET_INST_OPCODE(ip) @ extract opcode from rINST 1531 GOTO_OPCODE(ip) @ jump to next instruction 1532 1533 1534 /* ------------------------------ */ 1535 .balign 64 1536 .L_OP_IF_GE: /* 0x35 */ 1537 /* File: armv6t2/OP_IF_GE.S */ 1538 /* File: armv6t2/bincmp.S */ 1539 /* 1540 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1541 * fragment that specifies the *reverse* comparison to perform, e.g. 1542 * for "if-le" you would use "gt". 1543 * 1544 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1545 */ 1546 /* if-cmp vA, vB, +CCCC */ 1547 mov r1, rINST, lsr #12 @ r1<- B 1548 ubfx r0, rINST, #8, #4 @ r0<- A 1549 GET_VREG(r3, r1) @ r3<- vB 1550 GET_VREG(r2, r0) @ r2<- vA 1551 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1552 cmp r2, r3 @ compare (vA, vB) 1553 movlt r1, #2 @ r1<- BYTE branch dist for not-taken 1554 adds r2, r1, r1 @ convert to bytes, check sign 1555 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1556 #if defined(WITH_JIT) 1557 ldr r0, [rSELF, #offThread_pJitProfTable] 1558 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1559 cmp r0, #0 1560 bne common_updateProfile 1561 #else 1562 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1563 #endif 1564 GET_INST_OPCODE(ip) @ extract opcode from rINST 1565 GOTO_OPCODE(ip) @ jump to next instruction 1566 1567 1568 /* ------------------------------ */ 1569 .balign 64 1570 .L_OP_IF_GT: /* 0x36 */ 1571 /* File: armv6t2/OP_IF_GT.S */ 1572 /* File: armv6t2/bincmp.S */ 1573 /* 1574 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1575 * fragment that specifies the *reverse* comparison to perform, e.g. 1576 * for "if-le" you would use "gt". 1577 * 1578 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1579 */ 1580 /* if-cmp vA, vB, +CCCC */ 1581 mov r1, rINST, lsr #12 @ r1<- B 1582 ubfx r0, rINST, #8, #4 @ r0<- A 1583 GET_VREG(r3, r1) @ r3<- vB 1584 GET_VREG(r2, r0) @ r2<- vA 1585 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1586 cmp r2, r3 @ compare (vA, vB) 1587 movle r1, #2 @ r1<- BYTE branch dist for not-taken 1588 adds r2, r1, r1 @ convert to bytes, check sign 1589 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1590 #if defined(WITH_JIT) 1591 ldr r0, [rSELF, #offThread_pJitProfTable] 1592 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1593 cmp r0, #0 1594 bne common_updateProfile 1595 #else 1596 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1597 #endif 1598 GET_INST_OPCODE(ip) @ extract opcode from rINST 1599 GOTO_OPCODE(ip) @ jump to next instruction 1600 1601 1602 /* ------------------------------ */ 1603 .balign 64 1604 .L_OP_IF_LE: /* 0x37 */ 1605 /* File: armv6t2/OP_IF_LE.S */ 1606 /* File: armv6t2/bincmp.S */ 1607 /* 1608 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1609 * fragment that specifies the *reverse* comparison to perform, e.g. 1610 * for "if-le" you would use "gt". 1611 * 1612 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1613 */ 1614 /* if-cmp vA, vB, +CCCC */ 1615 mov r1, rINST, lsr #12 @ r1<- B 1616 ubfx r0, rINST, #8, #4 @ r0<- A 1617 GET_VREG(r3, r1) @ r3<- vB 1618 GET_VREG(r2, r0) @ r2<- vA 1619 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1620 cmp r2, r3 @ compare (vA, vB) 1621 movgt r1, #2 @ r1<- BYTE branch dist for not-taken 1622 adds r2, r1, r1 @ convert to bytes, check sign 1623 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1624 #if defined(WITH_JIT) 1625 ldr r0, [rSELF, #offThread_pJitProfTable] 1626 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1627 cmp r0, #0 1628 bne common_updateProfile 1629 #else 1630 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1631 #endif 1632 GET_INST_OPCODE(ip) @ extract opcode from rINST 1633 GOTO_OPCODE(ip) @ jump to next instruction 1634 1635 1636 /* ------------------------------ */ 1637 .balign 64 1638 .L_OP_IF_EQZ: /* 0x38 */ 1639 /* File: armv5te/OP_IF_EQZ.S */ 1640 /* File: armv5te/zcmp.S */ 1641 /* 1642 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1643 * fragment that specifies the *reverse* comparison to perform, e.g. 1644 * for "if-le" you would use "gt". 1645 * 1646 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1647 */ 1648 /* if-cmp vAA, +BBBB */ 1649 mov r0, rINST, lsr #8 @ r0<- AA 1650 GET_VREG(r2, r0) @ r2<- vAA 1651 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1652 cmp r2, #0 @ compare (vA, 0) 1653 movne r1, #2 @ r1<- inst branch dist for not-taken 1654 adds r1, r1, r1 @ convert to bytes & set flags 1655 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1656 #if defined(WITH_JIT) 1657 ldr r0, [rSELF, #offThread_pJitProfTable] 1658 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1659 cmp r0,#0 1660 bne common_updateProfile @ test for JIT off at target 1661 #else 1662 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1663 #endif 1664 GET_INST_OPCODE(ip) @ extract opcode from rINST 1665 GOTO_OPCODE(ip) @ jump to next instruction 1666 1667 1668 /* ------------------------------ */ 1669 .balign 64 1670 .L_OP_IF_NEZ: /* 0x39 */ 1671 /* File: armv5te/OP_IF_NEZ.S */ 1672 /* File: armv5te/zcmp.S */ 1673 /* 1674 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1675 * fragment that specifies the *reverse* comparison to perform, e.g. 1676 * for "if-le" you would use "gt". 1677 * 1678 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1679 */ 1680 /* if-cmp vAA, +BBBB */ 1681 mov r0, rINST, lsr #8 @ r0<- AA 1682 GET_VREG(r2, r0) @ r2<- vAA 1683 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1684 cmp r2, #0 @ compare (vA, 0) 1685 moveq r1, #2 @ r1<- inst branch dist for not-taken 1686 adds r1, r1, r1 @ convert to bytes & set flags 1687 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1688 #if defined(WITH_JIT) 1689 ldr r0, [rSELF, #offThread_pJitProfTable] 1690 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1691 cmp r0,#0 1692 bne common_updateProfile @ test for JIT off at target 1693 #else 1694 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1695 #endif 1696 GET_INST_OPCODE(ip) @ extract opcode from rINST 1697 GOTO_OPCODE(ip) @ jump to next instruction 1698 1699 1700 /* ------------------------------ */ 1701 .balign 64 1702 .L_OP_IF_LTZ: /* 0x3a */ 1703 /* File: armv5te/OP_IF_LTZ.S */ 1704 /* File: armv5te/zcmp.S */ 1705 /* 1706 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1707 * fragment that specifies the *reverse* comparison to perform, e.g. 1708 * for "if-le" you would use "gt". 1709 * 1710 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1711 */ 1712 /* if-cmp vAA, +BBBB */ 1713 mov r0, rINST, lsr #8 @ r0<- AA 1714 GET_VREG(r2, r0) @ r2<- vAA 1715 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1716 cmp r2, #0 @ compare (vA, 0) 1717 movge r1, #2 @ r1<- inst branch dist for not-taken 1718 adds r1, r1, r1 @ convert to bytes & set flags 1719 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1720 #if defined(WITH_JIT) 1721 ldr r0, [rSELF, #offThread_pJitProfTable] 1722 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1723 cmp r0,#0 1724 bne common_updateProfile @ test for JIT off at target 1725 #else 1726 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1727 #endif 1728 GET_INST_OPCODE(ip) @ extract opcode from rINST 1729 GOTO_OPCODE(ip) @ jump to next instruction 1730 1731 1732 /* ------------------------------ */ 1733 .balign 64 1734 .L_OP_IF_GEZ: /* 0x3b */ 1735 /* File: armv5te/OP_IF_GEZ.S */ 1736 /* File: armv5te/zcmp.S */ 1737 /* 1738 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1739 * fragment that specifies the *reverse* comparison to perform, e.g. 1740 * for "if-le" you would use "gt". 1741 * 1742 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1743 */ 1744 /* if-cmp vAA, +BBBB */ 1745 mov r0, rINST, lsr #8 @ r0<- AA 1746 GET_VREG(r2, r0) @ r2<- vAA 1747 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1748 cmp r2, #0 @ compare (vA, 0) 1749 movlt r1, #2 @ r1<- inst branch dist for not-taken 1750 adds r1, r1, r1 @ convert to bytes & set flags 1751 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1752 #if defined(WITH_JIT) 1753 ldr r0, [rSELF, #offThread_pJitProfTable] 1754 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1755 cmp r0,#0 1756 bne common_updateProfile @ test for JIT off at target 1757 #else 1758 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1759 #endif 1760 GET_INST_OPCODE(ip) @ extract opcode from rINST 1761 GOTO_OPCODE(ip) @ jump to next instruction 1762 1763 1764 /* ------------------------------ */ 1765 .balign 64 1766 .L_OP_IF_GTZ: /* 0x3c */ 1767 /* File: armv5te/OP_IF_GTZ.S */ 1768 /* File: armv5te/zcmp.S */ 1769 /* 1770 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1771 * fragment that specifies the *reverse* comparison to perform, e.g. 1772 * for "if-le" you would use "gt". 1773 * 1774 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1775 */ 1776 /* if-cmp vAA, +BBBB */ 1777 mov r0, rINST, lsr #8 @ r0<- AA 1778 GET_VREG(r2, r0) @ r2<- vAA 1779 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1780 cmp r2, #0 @ compare (vA, 0) 1781 movle r1, #2 @ r1<- inst branch dist for not-taken 1782 adds r1, r1, r1 @ convert to bytes & set flags 1783 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1784 #if defined(WITH_JIT) 1785 ldr r0, [rSELF, #offThread_pJitProfTable] 1786 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1787 cmp r0,#0 1788 bne common_updateProfile @ test for JIT off at target 1789 #else 1790 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1791 #endif 1792 GET_INST_OPCODE(ip) @ extract opcode from rINST 1793 GOTO_OPCODE(ip) @ jump to next instruction 1794 1795 1796 /* ------------------------------ */ 1797 .balign 64 1798 .L_OP_IF_LEZ: /* 0x3d */ 1799 /* File: armv5te/OP_IF_LEZ.S */ 1800 /* File: armv5te/zcmp.S */ 1801 /* 1802 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1803 * fragment that specifies the *reverse* comparison to perform, e.g. 1804 * for "if-le" you would use "gt". 1805 * 1806 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1807 */ 1808 /* if-cmp vAA, +BBBB */ 1809 mov r0, rINST, lsr #8 @ r0<- AA 1810 GET_VREG(r2, r0) @ r2<- vAA 1811 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1812 cmp r2, #0 @ compare (vA, 0) 1813 movgt r1, #2 @ r1<- inst branch dist for not-taken 1814 adds r1, r1, r1 @ convert to bytes & set flags 1815 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1816 #if defined(WITH_JIT) 1817 ldr r0, [rSELF, #offThread_pJitProfTable] 1818 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1819 cmp r0,#0 1820 bne common_updateProfile @ test for JIT off at target 1821 #else 1822 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1823 #endif 1824 GET_INST_OPCODE(ip) @ extract opcode from rINST 1825 GOTO_OPCODE(ip) @ jump to next instruction 1826 1827 1828 /* ------------------------------ */ 1829 .balign 64 1830 .L_OP_UNUSED_3E: /* 0x3e */ 1831 /* File: armv5te/OP_UNUSED_3E.S */ 1832 /* File: armv5te/unused.S */ 1833 bl common_abort 1834 1835 1836 /* ------------------------------ */ 1837 .balign 64 1838 .L_OP_UNUSED_3F: /* 0x3f */ 1839 /* File: armv5te/OP_UNUSED_3F.S */ 1840 /* File: armv5te/unused.S */ 1841 bl common_abort 1842 1843 1844 /* ------------------------------ */ 1845 .balign 64 1846 .L_OP_UNUSED_40: /* 0x40 */ 1847 /* File: armv5te/OP_UNUSED_40.S */ 1848 /* File: armv5te/unused.S */ 1849 bl common_abort 1850 1851 1852 /* ------------------------------ */ 1853 .balign 64 1854 .L_OP_UNUSED_41: /* 0x41 */ 1855 /* File: armv5te/OP_UNUSED_41.S */ 1856 /* File: armv5te/unused.S */ 1857 bl common_abort 1858 1859 1860 /* ------------------------------ */ 1861 .balign 64 1862 .L_OP_UNUSED_42: /* 0x42 */ 1863 /* File: armv5te/OP_UNUSED_42.S */ 1864 /* File: armv5te/unused.S */ 1865 bl common_abort 1866 1867 1868 /* ------------------------------ */ 1869 .balign 64 1870 .L_OP_UNUSED_43: /* 0x43 */ 1871 /* File: armv5te/OP_UNUSED_43.S */ 1872 /* File: armv5te/unused.S */ 1873 bl common_abort 1874 1875 1876 /* ------------------------------ */ 1877 .balign 64 1878 .L_OP_AGET: /* 0x44 */ 1879 /* File: armv5te/OP_AGET.S */ 1880 /* 1881 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1882 * 1883 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1884 * instructions. We use a pair of FETCH_Bs instead. 1885 * 1886 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1887 */ 1888 /* op vAA, vBB, vCC */ 1889 FETCH_B(r2, 1, 0) @ r2<- BB 1890 mov r9, rINST, lsr #8 @ r9<- AA 1891 FETCH_B(r3, 1, 1) @ r3<- CC 1892 GET_VREG(r0, r2) @ r0<- vBB (array object) 1893 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1894 cmp r0, #0 @ null array object? 1895 beq common_errNullObject @ yes, bail 1896 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1897 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1898 cmp r1, r3 @ compare unsigned index, length 1899 bcs common_errArrayIndex @ index >= length, bail 1900 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1901 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1902 GET_INST_OPCODE(ip) @ extract opcode from rINST 1903 SET_VREG(r2, r9) @ vAA<- r2 1904 GOTO_OPCODE(ip) @ jump to next instruction 1905 1906 /* ------------------------------ */ 1907 .balign 64 1908 .L_OP_AGET_WIDE: /* 0x45 */ 1909 /* File: armv5te/OP_AGET_WIDE.S */ 1910 /* 1911 * Array get, 64 bits. vAA <- vBB[vCC]. 1912 * 1913 * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD. 1914 */ 1915 /* aget-wide vAA, vBB, vCC */ 1916 FETCH(r0, 1) @ r0<- CCBB 1917 mov r9, rINST, lsr #8 @ r9<- AA 1918 and r2, r0, #255 @ r2<- BB 1919 mov r3, r0, lsr #8 @ r3<- CC 1920 GET_VREG(r0, r2) @ r0<- vBB (array object) 1921 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1922 cmp r0, #0 @ null array object? 1923 beq common_errNullObject @ yes, bail 1924 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1925 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 1926 cmp r1, r3 @ compare unsigned index, length 1927 bcc .LOP_AGET_WIDE_finish @ okay, continue below 1928 b common_errArrayIndex @ index >= length, bail 1929 @ May want to swap the order of these two branches depending on how the 1930 @ branch prediction (if any) handles conditional forward branches vs. 1931 @ unconditional forward branches. 1932 1933 /* ------------------------------ */ 1934 .balign 64 1935 .L_OP_AGET_OBJECT: /* 0x46 */ 1936 /* File: armv5te/OP_AGET_OBJECT.S */ 1937 /* File: armv5te/OP_AGET.S */ 1938 /* 1939 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1940 * 1941 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1942 * instructions. We use a pair of FETCH_Bs instead. 1943 * 1944 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1945 */ 1946 /* op vAA, vBB, vCC */ 1947 FETCH_B(r2, 1, 0) @ r2<- BB 1948 mov r9, rINST, lsr #8 @ r9<- AA 1949 FETCH_B(r3, 1, 1) @ r3<- CC 1950 GET_VREG(r0, r2) @ r0<- vBB (array object) 1951 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1952 cmp r0, #0 @ null array object? 1953 beq common_errNullObject @ yes, bail 1954 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1955 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1956 cmp r1, r3 @ compare unsigned index, length 1957 bcs common_errArrayIndex @ index >= length, bail 1958 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1959 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1960 GET_INST_OPCODE(ip) @ extract opcode from rINST 1961 SET_VREG(r2, r9) @ vAA<- r2 1962 GOTO_OPCODE(ip) @ jump to next instruction 1963 1964 1965 /* ------------------------------ */ 1966 .balign 64 1967 .L_OP_AGET_BOOLEAN: /* 0x47 */ 1968 /* File: armv5te/OP_AGET_BOOLEAN.S */ 1969 /* File: armv5te/OP_AGET.S */ 1970 /* 1971 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1972 * 1973 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1974 * instructions. We use a pair of FETCH_Bs instead. 1975 * 1976 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1977 */ 1978 /* op vAA, vBB, vCC */ 1979 FETCH_B(r2, 1, 0) @ r2<- BB 1980 mov r9, rINST, lsr #8 @ r9<- AA 1981 FETCH_B(r3, 1, 1) @ r3<- CC 1982 GET_VREG(r0, r2) @ r0<- vBB (array object) 1983 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1984 cmp r0, #0 @ null array object? 1985 beq common_errNullObject @ yes, bail 1986 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1987 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 1988 cmp r1, r3 @ compare unsigned index, length 1989 bcs common_errArrayIndex @ index >= length, bail 1990 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1991 ldrb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1992 GET_INST_OPCODE(ip) @ extract opcode from rINST 1993 SET_VREG(r2, r9) @ vAA<- r2 1994 GOTO_OPCODE(ip) @ jump to next instruction 1995 1996 1997 /* ------------------------------ */ 1998 .balign 64 1999 .L_OP_AGET_BYTE: /* 0x48 */ 2000 /* File: armv5te/OP_AGET_BYTE.S */ 2001 /* File: armv5te/OP_AGET.S */ 2002 /* 2003 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2004 * 2005 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2006 * instructions. We use a pair of FETCH_Bs instead. 2007 * 2008 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2009 */ 2010 /* op vAA, vBB, vCC */ 2011 FETCH_B(r2, 1, 0) @ r2<- BB 2012 mov r9, rINST, lsr #8 @ r9<- AA 2013 FETCH_B(r3, 1, 1) @ r3<- CC 2014 GET_VREG(r0, r2) @ r0<- vBB (array object) 2015 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2016 cmp r0, #0 @ null array object? 2017 beq common_errNullObject @ yes, bail 2018 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2019 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2020 cmp r1, r3 @ compare unsigned index, length 2021 bcs common_errArrayIndex @ index >= length, bail 2022 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2023 ldrsb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2024 GET_INST_OPCODE(ip) @ extract opcode from rINST 2025 SET_VREG(r2, r9) @ vAA<- r2 2026 GOTO_OPCODE(ip) @ jump to next instruction 2027 2028 2029 /* ------------------------------ */ 2030 .balign 64 2031 .L_OP_AGET_CHAR: /* 0x49 */ 2032 /* File: armv5te/OP_AGET_CHAR.S */ 2033 /* File: armv5te/OP_AGET.S */ 2034 /* 2035 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2036 * 2037 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2038 * instructions. We use a pair of FETCH_Bs instead. 2039 * 2040 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2041 */ 2042 /* op vAA, vBB, vCC */ 2043 FETCH_B(r2, 1, 0) @ r2<- BB 2044 mov r9, rINST, lsr #8 @ r9<- AA 2045 FETCH_B(r3, 1, 1) @ r3<- CC 2046 GET_VREG(r0, r2) @ r0<- vBB (array object) 2047 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2048 cmp r0, #0 @ null array object? 2049 beq common_errNullObject @ yes, bail 2050 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2051 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2052 cmp r1, r3 @ compare unsigned index, length 2053 bcs common_errArrayIndex @ index >= length, bail 2054 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2055 ldrh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2056 GET_INST_OPCODE(ip) @ extract opcode from rINST 2057 SET_VREG(r2, r9) @ vAA<- r2 2058 GOTO_OPCODE(ip) @ jump to next instruction 2059 2060 2061 /* ------------------------------ */ 2062 .balign 64 2063 .L_OP_AGET_SHORT: /* 0x4a */ 2064 /* File: armv5te/OP_AGET_SHORT.S */ 2065 /* File: armv5te/OP_AGET.S */ 2066 /* 2067 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2068 * 2069 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2070 * instructions. We use a pair of FETCH_Bs instead. 2071 * 2072 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2073 */ 2074 /* op vAA, vBB, vCC */ 2075 FETCH_B(r2, 1, 0) @ r2<- BB 2076 mov r9, rINST, lsr #8 @ r9<- AA 2077 FETCH_B(r3, 1, 1) @ r3<- CC 2078 GET_VREG(r0, r2) @ r0<- vBB (array object) 2079 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2080 cmp r0, #0 @ null array object? 2081 beq common_errNullObject @ yes, bail 2082 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2083 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2084 cmp r1, r3 @ compare unsigned index, length 2085 bcs common_errArrayIndex @ index >= length, bail 2086 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2087 ldrsh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2088 GET_INST_OPCODE(ip) @ extract opcode from rINST 2089 SET_VREG(r2, r9) @ vAA<- r2 2090 GOTO_OPCODE(ip) @ jump to next instruction 2091 2092 2093 /* ------------------------------ */ 2094 .balign 64 2095 .L_OP_APUT: /* 0x4b */ 2096 /* File: armv5te/OP_APUT.S */ 2097 /* 2098 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2099 * 2100 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2101 * instructions. We use a pair of FETCH_Bs instead. 2102 * 2103 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2104 */ 2105 /* op vAA, vBB, vCC */ 2106 FETCH_B(r2, 1, 0) @ r2<- BB 2107 mov r9, rINST, lsr #8 @ r9<- AA 2108 FETCH_B(r3, 1, 1) @ r3<- CC 2109 GET_VREG(r0, r2) @ r0<- vBB (array object) 2110 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2111 cmp r0, #0 @ null array object? 2112 beq common_errNullObject @ yes, bail 2113 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2114 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2115 cmp r1, r3 @ compare unsigned index, length 2116 bcs common_errArrayIndex @ index >= length, bail 2117 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2118 GET_VREG(r2, r9) @ r2<- vAA 2119 GET_INST_OPCODE(ip) @ extract opcode from rINST 2120 str r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2121 GOTO_OPCODE(ip) @ jump to next instruction 2122 2123 /* ------------------------------ */ 2124 .balign 64 2125 .L_OP_APUT_WIDE: /* 0x4c */ 2126 /* File: armv5te/OP_APUT_WIDE.S */ 2127 /* 2128 * Array put, 64 bits. vBB[vCC] <- vAA. 2129 * 2130 * Arrays of long/double are 64-bit aligned, so it's okay to use STRD. 2131 */ 2132 /* aput-wide vAA, vBB, vCC */ 2133 FETCH(r0, 1) @ r0<- CCBB 2134 mov r9, rINST, lsr #8 @ r9<- AA 2135 and r2, r0, #255 @ r2<- BB 2136 mov r3, r0, lsr #8 @ r3<- CC 2137 GET_VREG(r0, r2) @ r0<- vBB (array object) 2138 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2139 cmp r0, #0 @ null array object? 2140 beq common_errNullObject @ yes, bail 2141 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2142 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2143 cmp r1, r3 @ compare unsigned index, length 2144 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2145 bcc .LOP_APUT_WIDE_finish @ okay, continue below 2146 b common_errArrayIndex @ index >= length, bail 2147 @ May want to swap the order of these two branches depending on how the 2148 @ branch prediction (if any) handles conditional forward branches vs. 2149 @ unconditional forward branches. 2150 2151 /* ------------------------------ */ 2152 .balign 64 2153 .L_OP_APUT_OBJECT: /* 0x4d */ 2154 /* File: armv5te/OP_APUT_OBJECT.S */ 2155 /* 2156 * Store an object into an array. vBB[vCC] <- vAA. 2157 */ 2158 /* op vAA, vBB, vCC */ 2159 FETCH(r0, 1) @ r0<- CCBB 2160 mov r9, rINST, lsr #8 @ r9<- AA 2161 and r2, r0, #255 @ r2<- BB 2162 mov r3, r0, lsr #8 @ r3<- CC 2163 GET_VREG(rINST, r2) @ rINST<- vBB (array object) 2164 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2165 cmp rINST, #0 @ null array object? 2166 GET_VREG(r9, r9) @ r9<- vAA 2167 beq common_errNullObject @ yes, bail 2168 ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length 2169 add r10, rINST, r1, lsl #2 @ r10<- arrayObj + index*width 2170 cmp r1, r3 @ compare unsigned index, length 2171 bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on 2172 b common_errArrayIndex @ index >= length, bail 2173 2174 2175 /* ------------------------------ */ 2176 .balign 64 2177 .L_OP_APUT_BOOLEAN: /* 0x4e */ 2178 /* File: armv5te/OP_APUT_BOOLEAN.S */ 2179 /* File: armv5te/OP_APUT.S */ 2180 /* 2181 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2182 * 2183 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2184 * instructions. We use a pair of FETCH_Bs instead. 2185 * 2186 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2187 */ 2188 /* op vAA, vBB, vCC */ 2189 FETCH_B(r2, 1, 0) @ r2<- BB 2190 mov r9, rINST, lsr #8 @ r9<- AA 2191 FETCH_B(r3, 1, 1) @ r3<- CC 2192 GET_VREG(r0, r2) @ r0<- vBB (array object) 2193 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2194 cmp r0, #0 @ null array object? 2195 beq common_errNullObject @ yes, bail 2196 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2197 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2198 cmp r1, r3 @ compare unsigned index, length 2199 bcs common_errArrayIndex @ index >= length, bail 2200 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2201 GET_VREG(r2, r9) @ r2<- vAA 2202 GET_INST_OPCODE(ip) @ extract opcode from rINST 2203 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2204 GOTO_OPCODE(ip) @ jump to next instruction 2205 2206 2207 /* ------------------------------ */ 2208 .balign 64 2209 .L_OP_APUT_BYTE: /* 0x4f */ 2210 /* File: armv5te/OP_APUT_BYTE.S */ 2211 /* File: armv5te/OP_APUT.S */ 2212 /* 2213 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2214 * 2215 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2216 * instructions. We use a pair of FETCH_Bs instead. 2217 * 2218 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2219 */ 2220 /* op vAA, vBB, vCC */ 2221 FETCH_B(r2, 1, 0) @ r2<- BB 2222 mov r9, rINST, lsr #8 @ r9<- AA 2223 FETCH_B(r3, 1, 1) @ r3<- CC 2224 GET_VREG(r0, r2) @ r0<- vBB (array object) 2225 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2226 cmp r0, #0 @ null array object? 2227 beq common_errNullObject @ yes, bail 2228 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2229 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2230 cmp r1, r3 @ compare unsigned index, length 2231 bcs common_errArrayIndex @ index >= length, bail 2232 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2233 GET_VREG(r2, r9) @ r2<- vAA 2234 GET_INST_OPCODE(ip) @ extract opcode from rINST 2235 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2236 GOTO_OPCODE(ip) @ jump to next instruction 2237 2238 2239 /* ------------------------------ */ 2240 .balign 64 2241 .L_OP_APUT_CHAR: /* 0x50 */ 2242 /* File: armv5te/OP_APUT_CHAR.S */ 2243 /* File: armv5te/OP_APUT.S */ 2244 /* 2245 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2246 * 2247 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2248 * instructions. We use a pair of FETCH_Bs instead. 2249 * 2250 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2251 */ 2252 /* op vAA, vBB, vCC */ 2253 FETCH_B(r2, 1, 0) @ r2<- BB 2254 mov r9, rINST, lsr #8 @ r9<- AA 2255 FETCH_B(r3, 1, 1) @ r3<- CC 2256 GET_VREG(r0, r2) @ r0<- vBB (array object) 2257 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2258 cmp r0, #0 @ null array object? 2259 beq common_errNullObject @ yes, bail 2260 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2261 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2262 cmp r1, r3 @ compare unsigned index, length 2263 bcs common_errArrayIndex @ index >= length, bail 2264 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2265 GET_VREG(r2, r9) @ r2<- vAA 2266 GET_INST_OPCODE(ip) @ extract opcode from rINST 2267 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2268 GOTO_OPCODE(ip) @ jump to next instruction 2269 2270 2271 /* ------------------------------ */ 2272 .balign 64 2273 .L_OP_APUT_SHORT: /* 0x51 */ 2274 /* File: armv5te/OP_APUT_SHORT.S */ 2275 /* File: armv5te/OP_APUT.S */ 2276 /* 2277 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2278 * 2279 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2280 * instructions. We use a pair of FETCH_Bs instead. 2281 * 2282 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2283 */ 2284 /* op vAA, vBB, vCC */ 2285 FETCH_B(r2, 1, 0) @ r2<- BB 2286 mov r9, rINST, lsr #8 @ r9<- AA 2287 FETCH_B(r3, 1, 1) @ r3<- CC 2288 GET_VREG(r0, r2) @ r0<- vBB (array object) 2289 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2290 cmp r0, #0 @ null array object? 2291 beq common_errNullObject @ yes, bail 2292 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2293 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2294 cmp r1, r3 @ compare unsigned index, length 2295 bcs common_errArrayIndex @ index >= length, bail 2296 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2297 GET_VREG(r2, r9) @ r2<- vAA 2298 GET_INST_OPCODE(ip) @ extract opcode from rINST 2299 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2300 GOTO_OPCODE(ip) @ jump to next instruction 2301 2302 2303 /* ------------------------------ */ 2304 .balign 64 2305 .L_OP_IGET: /* 0x52 */ 2306 /* File: armv6t2/OP_IGET.S */ 2307 /* 2308 * General 32-bit instance field get. 2309 * 2310 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2311 */ 2312 /* op vA, vB, field@CCCC */ 2313 mov r0, rINST, lsr #12 @ r0<- B 2314 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2315 FETCH(r1, 1) @ r1<- field ref CCCC 2316 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2317 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2318 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2319 cmp r0, #0 @ is resolved entry null? 2320 bne .LOP_IGET_finish @ no, already resolved 2321 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2322 EXPORT_PC() @ resolve() could throw 2323 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2324 bl dvmResolveInstField @ r0<- resolved InstField ptr 2325 cmp r0, #0 2326 bne .LOP_IGET_finish 2327 b common_exceptionThrown 2328 2329 /* ------------------------------ */ 2330 .balign 64 2331 .L_OP_IGET_WIDE: /* 0x53 */ 2332 /* File: armv6t2/OP_IGET_WIDE.S */ 2333 /* 2334 * Wide 32-bit instance field get. 2335 */ 2336 /* iget-wide vA, vB, field@CCCC */ 2337 mov r0, rINST, lsr #12 @ r0<- B 2338 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2339 FETCH(r1, 1) @ r1<- field ref CCCC 2340 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2341 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2342 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2343 cmp r0, #0 @ is resolved entry null? 2344 bne .LOP_IGET_WIDE_finish @ no, already resolved 2345 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2346 EXPORT_PC() @ resolve() could throw 2347 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2348 bl dvmResolveInstField @ r0<- resolved InstField ptr 2349 cmp r0, #0 2350 bne .LOP_IGET_WIDE_finish 2351 b common_exceptionThrown 2352 2353 /* ------------------------------ */ 2354 .balign 64 2355 .L_OP_IGET_OBJECT: /* 0x54 */ 2356 /* File: armv5te/OP_IGET_OBJECT.S */ 2357 /* File: armv5te/OP_IGET.S */ 2358 /* 2359 * General 32-bit instance field get. 2360 * 2361 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2362 */ 2363 /* op vA, vB, field@CCCC */ 2364 mov r0, rINST, lsr #12 @ r0<- B 2365 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2366 FETCH(r1, 1) @ r1<- field ref CCCC 2367 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2368 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2369 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2370 cmp r0, #0 @ is resolved entry null? 2371 bne .LOP_IGET_OBJECT_finish @ no, already resolved 2372 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2373 EXPORT_PC() @ resolve() could throw 2374 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2375 bl dvmResolveInstField @ r0<- resolved InstField ptr 2376 cmp r0, #0 2377 bne .LOP_IGET_OBJECT_finish 2378 b common_exceptionThrown 2379 2380 2381 /* ------------------------------ */ 2382 .balign 64 2383 .L_OP_IGET_BOOLEAN: /* 0x55 */ 2384 /* File: armv5te/OP_IGET_BOOLEAN.S */ 2385 @include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" } 2386 /* File: armv5te/OP_IGET.S */ 2387 /* 2388 * General 32-bit instance field get. 2389 * 2390 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2391 */ 2392 /* op vA, vB, field@CCCC */ 2393 mov r0, rINST, lsr #12 @ r0<- B 2394 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2395 FETCH(r1, 1) @ r1<- field ref CCCC 2396 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2397 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2398 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2399 cmp r0, #0 @ is resolved entry null? 2400 bne .LOP_IGET_BOOLEAN_finish @ no, already resolved 2401 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2402 EXPORT_PC() @ resolve() could throw 2403 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2404 bl dvmResolveInstField @ r0<- resolved InstField ptr 2405 cmp r0, #0 2406 bne .LOP_IGET_BOOLEAN_finish 2407 b common_exceptionThrown 2408 2409 2410 /* ------------------------------ */ 2411 .balign 64 2412 .L_OP_IGET_BYTE: /* 0x56 */ 2413 /* File: armv5te/OP_IGET_BYTE.S */ 2414 @include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" } 2415 /* File: armv5te/OP_IGET.S */ 2416 /* 2417 * General 32-bit instance field get. 2418 * 2419 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2420 */ 2421 /* op vA, vB, field@CCCC */ 2422 mov r0, rINST, lsr #12 @ r0<- B 2423 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2424 FETCH(r1, 1) @ r1<- field ref CCCC 2425 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2426 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2427 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2428 cmp r0, #0 @ is resolved entry null? 2429 bne .LOP_IGET_BYTE_finish @ no, already resolved 2430 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2431 EXPORT_PC() @ resolve() could throw 2432 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2433 bl dvmResolveInstField @ r0<- resolved InstField ptr 2434 cmp r0, #0 2435 bne .LOP_IGET_BYTE_finish 2436 b common_exceptionThrown 2437 2438 2439 /* ------------------------------ */ 2440 .balign 64 2441 .L_OP_IGET_CHAR: /* 0x57 */ 2442 /* File: armv5te/OP_IGET_CHAR.S */ 2443 @include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" } 2444 /* File: armv5te/OP_IGET.S */ 2445 /* 2446 * General 32-bit instance field get. 2447 * 2448 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2449 */ 2450 /* op vA, vB, field@CCCC */ 2451 mov r0, rINST, lsr #12 @ r0<- B 2452 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2453 FETCH(r1, 1) @ r1<- field ref CCCC 2454 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2455 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2456 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2457 cmp r0, #0 @ is resolved entry null? 2458 bne .LOP_IGET_CHAR_finish @ no, already resolved 2459 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2460 EXPORT_PC() @ resolve() could throw 2461 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2462 bl dvmResolveInstField @ r0<- resolved InstField ptr 2463 cmp r0, #0 2464 bne .LOP_IGET_CHAR_finish 2465 b common_exceptionThrown 2466 2467 2468 /* ------------------------------ */ 2469 .balign 64 2470 .L_OP_IGET_SHORT: /* 0x58 */ 2471 /* File: armv5te/OP_IGET_SHORT.S */ 2472 @include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" } 2473 /* File: armv5te/OP_IGET.S */ 2474 /* 2475 * General 32-bit instance field get. 2476 * 2477 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2478 */ 2479 /* op vA, vB, field@CCCC */ 2480 mov r0, rINST, lsr #12 @ r0<- B 2481 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2482 FETCH(r1, 1) @ r1<- field ref CCCC 2483 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2484 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2485 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2486 cmp r0, #0 @ is resolved entry null? 2487 bne .LOP_IGET_SHORT_finish @ no, already resolved 2488 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2489 EXPORT_PC() @ resolve() could throw 2490 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2491 bl dvmResolveInstField @ r0<- resolved InstField ptr 2492 cmp r0, #0 2493 bne .LOP_IGET_SHORT_finish 2494 b common_exceptionThrown 2495 2496 2497 /* ------------------------------ */ 2498 .balign 64 2499 .L_OP_IPUT: /* 0x59 */ 2500 /* File: armv6t2/OP_IPUT.S */ 2501 /* 2502 * General 32-bit instance field put. 2503 * 2504 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2505 */ 2506 /* op vA, vB, field@CCCC */ 2507 mov r0, rINST, lsr #12 @ r0<- B 2508 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2509 FETCH(r1, 1) @ r1<- field ref CCCC 2510 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2511 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2512 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2513 cmp r0, #0 @ is resolved entry null? 2514 bne .LOP_IPUT_finish @ no, already resolved 2515 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2516 EXPORT_PC() @ resolve() could throw 2517 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2518 bl dvmResolveInstField @ r0<- resolved InstField ptr 2519 cmp r0, #0 @ success? 2520 bne .LOP_IPUT_finish @ yes, finish up 2521 b common_exceptionThrown 2522 2523 /* ------------------------------ */ 2524 .balign 64 2525 .L_OP_IPUT_WIDE: /* 0x5a */ 2526 /* File: armv6t2/OP_IPUT_WIDE.S */ 2527 /* iput-wide vA, vB, field@CCCC */ 2528 mov r0, rINST, lsr #12 @ r0<- B 2529 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2530 FETCH(r1, 1) @ r1<- field ref CCCC 2531 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2532 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2533 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2534 cmp r0, #0 @ is resolved entry null? 2535 bne .LOP_IPUT_WIDE_finish @ no, already resolved 2536 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2537 EXPORT_PC() @ resolve() could throw 2538 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2539 bl dvmResolveInstField @ r0<- resolved InstField ptr 2540 cmp r0, #0 @ success? 2541 bne .LOP_IPUT_WIDE_finish @ yes, finish up 2542 b common_exceptionThrown 2543 2544 /* ------------------------------ */ 2545 .balign 64 2546 .L_OP_IPUT_OBJECT: /* 0x5b */ 2547 /* File: armv5te/OP_IPUT_OBJECT.S */ 2548 /* 2549 * 32-bit instance field put. 2550 * 2551 * for: iput-object, iput-object-volatile 2552 */ 2553 /* op vA, vB, field@CCCC */ 2554 mov r0, rINST, lsr #12 @ r0<- B 2555 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2556 FETCH(r1, 1) @ r1<- field ref CCCC 2557 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2558 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2559 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2560 cmp r0, #0 @ is resolved entry null? 2561 bne .LOP_IPUT_OBJECT_finish @ no, already resolved 2562 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2563 EXPORT_PC() @ resolve() could throw 2564 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2565 bl dvmResolveInstField @ r0<- resolved InstField ptr 2566 cmp r0, #0 @ success? 2567 bne .LOP_IPUT_OBJECT_finish @ yes, finish up 2568 b common_exceptionThrown 2569 2570 /* ------------------------------ */ 2571 .balign 64 2572 .L_OP_IPUT_BOOLEAN: /* 0x5c */ 2573 /* File: armv5te/OP_IPUT_BOOLEAN.S */ 2574 @include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" } 2575 /* File: armv5te/OP_IPUT.S */ 2576 /* 2577 * General 32-bit instance field put. 2578 * 2579 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2580 */ 2581 /* op vA, vB, field@CCCC */ 2582 mov r0, rINST, lsr #12 @ r0<- B 2583 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2584 FETCH(r1, 1) @ r1<- field ref CCCC 2585 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2586 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2587 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2588 cmp r0, #0 @ is resolved entry null? 2589 bne .LOP_IPUT_BOOLEAN_finish @ no, already resolved 2590 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2591 EXPORT_PC() @ resolve() could throw 2592 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2593 bl dvmResolveInstField @ r0<- resolved InstField ptr 2594 cmp r0, #0 @ success? 2595 bne .LOP_IPUT_BOOLEAN_finish @ yes, finish up 2596 b common_exceptionThrown 2597 2598 2599 /* ------------------------------ */ 2600 .balign 64 2601 .L_OP_IPUT_BYTE: /* 0x5d */ 2602 /* File: armv5te/OP_IPUT_BYTE.S */ 2603 @include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" } 2604 /* File: armv5te/OP_IPUT.S */ 2605 /* 2606 * General 32-bit instance field put. 2607 * 2608 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2609 */ 2610 /* op vA, vB, field@CCCC */ 2611 mov r0, rINST, lsr #12 @ r0<- B 2612 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2613 FETCH(r1, 1) @ r1<- field ref CCCC 2614 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2615 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2616 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2617 cmp r0, #0 @ is resolved entry null? 2618 bne .LOP_IPUT_BYTE_finish @ no, already resolved 2619 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2620 EXPORT_PC() @ resolve() could throw 2621 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2622 bl dvmResolveInstField @ r0<- resolved InstField ptr 2623 cmp r0, #0 @ success? 2624 bne .LOP_IPUT_BYTE_finish @ yes, finish up 2625 b common_exceptionThrown 2626 2627 2628 /* ------------------------------ */ 2629 .balign 64 2630 .L_OP_IPUT_CHAR: /* 0x5e */ 2631 /* File: armv5te/OP_IPUT_CHAR.S */ 2632 @include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" } 2633 /* File: armv5te/OP_IPUT.S */ 2634 /* 2635 * General 32-bit instance field put. 2636 * 2637 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2638 */ 2639 /* op vA, vB, field@CCCC */ 2640 mov r0, rINST, lsr #12 @ r0<- B 2641 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2642 FETCH(r1, 1) @ r1<- field ref CCCC 2643 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2644 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2645 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2646 cmp r0, #0 @ is resolved entry null? 2647 bne .LOP_IPUT_CHAR_finish @ no, already resolved 2648 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2649 EXPORT_PC() @ resolve() could throw 2650 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2651 bl dvmResolveInstField @ r0<- resolved InstField ptr 2652 cmp r0, #0 @ success? 2653 bne .LOP_IPUT_CHAR_finish @ yes, finish up 2654 b common_exceptionThrown 2655 2656 2657 /* ------------------------------ */ 2658 .balign 64 2659 .L_OP_IPUT_SHORT: /* 0x5f */ 2660 /* File: armv5te/OP_IPUT_SHORT.S */ 2661 @include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" } 2662 /* File: armv5te/OP_IPUT.S */ 2663 /* 2664 * General 32-bit instance field put. 2665 * 2666 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2667 */ 2668 /* op vA, vB, field@CCCC */ 2669 mov r0, rINST, lsr #12 @ r0<- B 2670 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2671 FETCH(r1, 1) @ r1<- field ref CCCC 2672 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2673 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2674 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2675 cmp r0, #0 @ is resolved entry null? 2676 bne .LOP_IPUT_SHORT_finish @ no, already resolved 2677 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2678 EXPORT_PC() @ resolve() could throw 2679 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2680 bl dvmResolveInstField @ r0<- resolved InstField ptr 2681 cmp r0, #0 @ success? 2682 bne .LOP_IPUT_SHORT_finish @ yes, finish up 2683 b common_exceptionThrown 2684 2685 2686 /* ------------------------------ */ 2687 .balign 64 2688 .L_OP_SGET: /* 0x60 */ 2689 /* File: armv5te/OP_SGET.S */ 2690 /* 2691 * General 32-bit SGET handler. 2692 * 2693 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2694 */ 2695 /* op vAA, field@BBBB */ 2696 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2697 FETCH(r1, 1) @ r1<- field ref BBBB 2698 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2699 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2700 cmp r0, #0 @ is resolved entry null? 2701 beq .LOP_SGET_resolve @ yes, do resolve 2702 .LOP_SGET_finish: @ field ptr in r0 2703 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2704 @ no-op @ acquiring load 2705 mov r2, rINST, lsr #8 @ r2<- AA 2706 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2707 SET_VREG(r1, r2) @ fp[AA]<- r1 2708 GET_INST_OPCODE(ip) @ extract opcode from rINST 2709 GOTO_OPCODE(ip) @ jump to next instruction 2710 2711 /* ------------------------------ */ 2712 .balign 64 2713 .L_OP_SGET_WIDE: /* 0x61 */ 2714 /* File: armv5te/OP_SGET_WIDE.S */ 2715 /* 2716 * 64-bit SGET handler. 2717 */ 2718 /* sget-wide vAA, field@BBBB */ 2719 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2720 FETCH(r1, 1) @ r1<- field ref BBBB 2721 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2722 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2723 cmp r0, #0 @ is resolved entry null? 2724 beq .LOP_SGET_WIDE_resolve @ yes, do resolve 2725 .LOP_SGET_WIDE_finish: 2726 mov r9, rINST, lsr #8 @ r9<- AA 2727 .if 0 2728 add r0, r0, #offStaticField_value @ r0<- pointer to data 2729 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 2730 .else 2731 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 2732 .endif 2733 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2734 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2735 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 2736 GET_INST_OPCODE(ip) @ extract opcode from rINST 2737 GOTO_OPCODE(ip) @ jump to next instruction 2738 2739 /* ------------------------------ */ 2740 .balign 64 2741 .L_OP_SGET_OBJECT: /* 0x62 */ 2742 /* File: armv5te/OP_SGET_OBJECT.S */ 2743 /* File: armv5te/OP_SGET.S */ 2744 /* 2745 * General 32-bit SGET handler. 2746 * 2747 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2748 */ 2749 /* op vAA, field@BBBB */ 2750 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2751 FETCH(r1, 1) @ r1<- field ref BBBB 2752 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2753 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2754 cmp r0, #0 @ is resolved entry null? 2755 beq .LOP_SGET_OBJECT_resolve @ yes, do resolve 2756 .LOP_SGET_OBJECT_finish: @ field ptr in r0 2757 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2758 @ no-op @ acquiring load 2759 mov r2, rINST, lsr #8 @ r2<- AA 2760 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2761 SET_VREG(r1, r2) @ fp[AA]<- r1 2762 GET_INST_OPCODE(ip) @ extract opcode from rINST 2763 GOTO_OPCODE(ip) @ jump to next instruction 2764 2765 2766 /* ------------------------------ */ 2767 .balign 64 2768 .L_OP_SGET_BOOLEAN: /* 0x63 */ 2769 /* File: armv5te/OP_SGET_BOOLEAN.S */ 2770 /* File: armv5te/OP_SGET.S */ 2771 /* 2772 * General 32-bit SGET handler. 2773 * 2774 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2775 */ 2776 /* op vAA, field@BBBB */ 2777 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2778 FETCH(r1, 1) @ r1<- field ref BBBB 2779 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2780 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2781 cmp r0, #0 @ is resolved entry null? 2782 beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve 2783 .LOP_SGET_BOOLEAN_finish: @ field ptr in r0 2784 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2785 @ no-op @ acquiring load 2786 mov r2, rINST, lsr #8 @ r2<- AA 2787 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2788 SET_VREG(r1, r2) @ fp[AA]<- r1 2789 GET_INST_OPCODE(ip) @ extract opcode from rINST 2790 GOTO_OPCODE(ip) @ jump to next instruction 2791 2792 2793 /* ------------------------------ */ 2794 .balign 64 2795 .L_OP_SGET_BYTE: /* 0x64 */ 2796 /* File: armv5te/OP_SGET_BYTE.S */ 2797 /* File: armv5te/OP_SGET.S */ 2798 /* 2799 * General 32-bit SGET handler. 2800 * 2801 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2802 */ 2803 /* op vAA, field@BBBB */ 2804 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2805 FETCH(r1, 1) @ r1<- field ref BBBB 2806 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2807 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2808 cmp r0, #0 @ is resolved entry null? 2809 beq .LOP_SGET_BYTE_resolve @ yes, do resolve 2810 .LOP_SGET_BYTE_finish: @ field ptr in r0 2811 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2812 @ no-op @ acquiring load 2813 mov r2, rINST, lsr #8 @ r2<- AA 2814 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2815 SET_VREG(r1, r2) @ fp[AA]<- r1 2816 GET_INST_OPCODE(ip) @ extract opcode from rINST 2817 GOTO_OPCODE(ip) @ jump to next instruction 2818 2819 2820 /* ------------------------------ */ 2821 .balign 64 2822 .L_OP_SGET_CHAR: /* 0x65 */ 2823 /* File: armv5te/OP_SGET_CHAR.S */ 2824 /* File: armv5te/OP_SGET.S */ 2825 /* 2826 * General 32-bit SGET handler. 2827 * 2828 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2829 */ 2830 /* op vAA, field@BBBB */ 2831 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2832 FETCH(r1, 1) @ r1<- field ref BBBB 2833 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2834 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2835 cmp r0, #0 @ is resolved entry null? 2836 beq .LOP_SGET_CHAR_resolve @ yes, do resolve 2837 .LOP_SGET_CHAR_finish: @ field ptr in r0 2838 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2839 @ no-op @ acquiring load 2840 mov r2, rINST, lsr #8 @ r2<- AA 2841 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2842 SET_VREG(r1, r2) @ fp[AA]<- r1 2843 GET_INST_OPCODE(ip) @ extract opcode from rINST 2844 GOTO_OPCODE(ip) @ jump to next instruction 2845 2846 2847 /* ------------------------------ */ 2848 .balign 64 2849 .L_OP_SGET_SHORT: /* 0x66 */ 2850 /* File: armv5te/OP_SGET_SHORT.S */ 2851 /* File: armv5te/OP_SGET.S */ 2852 /* 2853 * General 32-bit SGET handler. 2854 * 2855 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2856 */ 2857 /* op vAA, field@BBBB */ 2858 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2859 FETCH(r1, 1) @ r1<- field ref BBBB 2860 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2861 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2862 cmp r0, #0 @ is resolved entry null? 2863 beq .LOP_SGET_SHORT_resolve @ yes, do resolve 2864 .LOP_SGET_SHORT_finish: @ field ptr in r0 2865 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2866 @ no-op @ acquiring load 2867 mov r2, rINST, lsr #8 @ r2<- AA 2868 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2869 SET_VREG(r1, r2) @ fp[AA]<- r1 2870 GET_INST_OPCODE(ip) @ extract opcode from rINST 2871 GOTO_OPCODE(ip) @ jump to next instruction 2872 2873 2874 /* ------------------------------ */ 2875 .balign 64 2876 .L_OP_SPUT: /* 0x67 */ 2877 /* File: armv5te/OP_SPUT.S */ 2878 /* 2879 * General 32-bit SPUT handler. 2880 * 2881 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2882 */ 2883 /* op vAA, field@BBBB */ 2884 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2885 FETCH(r1, 1) @ r1<- field ref BBBB 2886 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2887 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2888 cmp r0, #0 @ is resolved entry null? 2889 beq .LOP_SPUT_resolve @ yes, do resolve 2890 .LOP_SPUT_finish: @ field ptr in r0 2891 mov r2, rINST, lsr #8 @ r2<- AA 2892 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2893 GET_VREG(r1, r2) @ r1<- fp[AA] 2894 GET_INST_OPCODE(ip) @ extract opcode from rINST 2895 @ no-op @ releasing store 2896 str r1, [r0, #offStaticField_value] @ field<- vAA 2897 @ no-op 2898 GOTO_OPCODE(ip) @ jump to next instruction 2899 2900 /* ------------------------------ */ 2901 .balign 64 2902 .L_OP_SPUT_WIDE: /* 0x68 */ 2903 /* File: armv5te/OP_SPUT_WIDE.S */ 2904 /* 2905 * 64-bit SPUT handler. 2906 */ 2907 /* sput-wide vAA, field@BBBB */ 2908 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- DvmDex 2909 FETCH(r1, 1) @ r1<- field ref BBBB 2910 ldr r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2911 mov r9, rINST, lsr #8 @ r9<- AA 2912 ldr r2, [r10, r1, lsl #2] @ r2<- resolved StaticField ptr 2913 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2914 cmp r2, #0 @ is resolved entry null? 2915 beq .LOP_SPUT_WIDE_resolve @ yes, do resolve 2916 .LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9 2917 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2918 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 2919 GET_INST_OPCODE(r10) @ extract opcode from rINST 2920 .if 0 2921 add r2, r2, #offStaticField_value @ r2<- pointer to data 2922 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 2923 .else 2924 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 2925 .endif 2926 GOTO_OPCODE(r10) @ jump to next instruction 2927 2928 /* ------------------------------ */ 2929 .balign 64 2930 .L_OP_SPUT_OBJECT: /* 0x69 */ 2931 /* File: armv5te/OP_SPUT_OBJECT.S */ 2932 /* 2933 * 32-bit SPUT handler for objects 2934 * 2935 * for: sput-object, sput-object-volatile 2936 */ 2937 /* op vAA, field@BBBB */ 2938 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2939 FETCH(r1, 1) @ r1<- field ref BBBB 2940 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2941 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2942 cmp r0, #0 @ is resolved entry null? 2943 beq .LOP_SPUT_OBJECT_resolve @ yes, do resolve 2944 .LOP_SPUT_OBJECT_finish: @ field ptr in r0 2945 mov r2, rINST, lsr #8 @ r2<- AA 2946 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2947 GET_VREG(r1, r2) @ r1<- fp[AA] 2948 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 2949 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 2950 GET_INST_OPCODE(ip) @ extract opcode from rINST 2951 @ no-op @ releasing store 2952 b .LOP_SPUT_OBJECT_end 2953 2954 /* ------------------------------ */ 2955 .balign 64 2956 .L_OP_SPUT_BOOLEAN: /* 0x6a */ 2957 /* File: armv5te/OP_SPUT_BOOLEAN.S */ 2958 /* File: armv5te/OP_SPUT.S */ 2959 /* 2960 * General 32-bit SPUT handler. 2961 * 2962 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2963 */ 2964 /* op vAA, field@BBBB */ 2965 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2966 FETCH(r1, 1) @ r1<- field ref BBBB 2967 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2968 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2969 cmp r0, #0 @ is resolved entry null? 2970 beq .LOP_SPUT_BOOLEAN_resolve @ yes, do resolve 2971 .LOP_SPUT_BOOLEAN_finish: @ field ptr in r0 2972 mov r2, rINST, lsr #8 @ r2<- AA 2973 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2974 GET_VREG(r1, r2) @ r1<- fp[AA] 2975 GET_INST_OPCODE(ip) @ extract opcode from rINST 2976 @ no-op @ releasing store 2977 str r1, [r0, #offStaticField_value] @ field<- vAA 2978 @ no-op 2979 GOTO_OPCODE(ip) @ jump to next instruction 2980 2981 2982 /* ------------------------------ */ 2983 .balign 64 2984 .L_OP_SPUT_BYTE: /* 0x6b */ 2985 /* File: armv5te/OP_SPUT_BYTE.S */ 2986 /* File: armv5te/OP_SPUT.S */ 2987 /* 2988 * General 32-bit SPUT handler. 2989 * 2990 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2991 */ 2992 /* op vAA, field@BBBB */ 2993 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2994 FETCH(r1, 1) @ r1<- field ref BBBB 2995 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2996 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2997 cmp r0, #0 @ is resolved entry null? 2998 beq .LOP_SPUT_BYTE_resolve @ yes, do resolve 2999 .LOP_SPUT_BYTE_finish: @ field ptr in r0 3000 mov r2, rINST, lsr #8 @ r2<- AA 3001 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3002 GET_VREG(r1, r2) @ r1<- fp[AA] 3003 GET_INST_OPCODE(ip) @ extract opcode from rINST 3004 @ no-op @ releasing store 3005 str r1, [r0, #offStaticField_value] @ field<- vAA 3006 @ no-op 3007 GOTO_OPCODE(ip) @ jump to next instruction 3008 3009 3010 /* ------------------------------ */ 3011 .balign 64 3012 .L_OP_SPUT_CHAR: /* 0x6c */ 3013 /* File: armv5te/OP_SPUT_CHAR.S */ 3014 /* File: armv5te/OP_SPUT.S */ 3015 /* 3016 * General 32-bit SPUT handler. 3017 * 3018 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3019 */ 3020 /* op vAA, field@BBBB */ 3021 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3022 FETCH(r1, 1) @ r1<- field ref BBBB 3023 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 3024 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 3025 cmp r0, #0 @ is resolved entry null? 3026 beq .LOP_SPUT_CHAR_resolve @ yes, do resolve 3027 .LOP_SPUT_CHAR_finish: @ field ptr in r0 3028 mov r2, rINST, lsr #8 @ r2<- AA 3029 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3030 GET_VREG(r1, r2) @ r1<- fp[AA] 3031 GET_INST_OPCODE(ip) @ extract opcode from rINST 3032 @ no-op @ releasing store 3033 str r1, [r0, #offStaticField_value] @ field<- vAA 3034 @ no-op 3035 GOTO_OPCODE(ip) @ jump to next instruction 3036 3037 3038 /* ------------------------------ */ 3039 .balign 64 3040 .L_OP_SPUT_SHORT: /* 0x6d */ 3041 /* File: armv5te/OP_SPUT_SHORT.S */ 3042 /* File: armv5te/OP_SPUT.S */ 3043 /* 3044 * General 32-bit SPUT handler. 3045 * 3046 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3047 */ 3048 /* op vAA, field@BBBB */ 3049 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3050 FETCH(r1, 1) @ r1<- field ref BBBB 3051 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 3052 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 3053 cmp r0, #0 @ is resolved entry null? 3054 beq .LOP_SPUT_SHORT_resolve @ yes, do resolve 3055 .LOP_SPUT_SHORT_finish: @ field ptr in r0 3056 mov r2, rINST, lsr #8 @ r2<- AA 3057 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3058 GET_VREG(r1, r2) @ r1<- fp[AA] 3059 GET_INST_OPCODE(ip) @ extract opcode from rINST 3060 @ no-op @ releasing store 3061 str r1, [r0, #offStaticField_value] @ field<- vAA 3062 @ no-op 3063 GOTO_OPCODE(ip) @ jump to next instruction 3064 3065 3066 /* ------------------------------ */ 3067 .balign 64 3068 .L_OP_INVOKE_VIRTUAL: /* 0x6e */ 3069 /* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3070 /* 3071 * Handle a virtual method call. 3072 * 3073 * for: invoke-virtual, invoke-virtual/range 3074 */ 3075 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3076 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3077 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3078 FETCH(r1, 1) @ r1<- BBBB 3079 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3080 FETCH(r10, 2) @ r10<- GFED or CCCC 3081 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3082 .if (!0) 3083 and r10, r10, #15 @ r10<- D (or stays CCCC) 3084 .endif 3085 cmp r0, #0 @ already resolved? 3086 EXPORT_PC() @ must export for invoke 3087 bne .LOP_INVOKE_VIRTUAL_continue @ yes, continue on 3088 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3089 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3090 mov r2, #METHOD_VIRTUAL @ resolver method type 3091 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3092 cmp r0, #0 @ got null? 3093 bne .LOP_INVOKE_VIRTUAL_continue @ no, continue 3094 b common_exceptionThrown @ yes, handle exception 3095 3096 /* ------------------------------ */ 3097 .balign 64 3098 .L_OP_INVOKE_SUPER: /* 0x6f */ 3099 /* File: armv5te/OP_INVOKE_SUPER.S */ 3100 /* 3101 * Handle a "super" method call. 3102 * 3103 * for: invoke-super, invoke-super/range 3104 */ 3105 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3106 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3107 FETCH(r10, 2) @ r10<- GFED or CCCC 3108 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3109 .if (!0) 3110 and r10, r10, #15 @ r10<- D (or stays CCCC) 3111 .endif 3112 FETCH(r1, 1) @ r1<- BBBB 3113 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3114 GET_VREG(r9, r10) @ r9<- "this" ptr 3115 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3116 cmp r9, #0 @ null "this"? 3117 ldr r10, [rSELF, #offThread_method] @ r10<- current method 3118 beq common_errNullObject @ null "this", throw exception 3119 cmp r0, #0 @ already resolved? 3120 ldr r10, [r10, #offMethod_clazz] @ r10<- method->clazz 3121 EXPORT_PC() @ must export for invoke 3122 bne .LOP_INVOKE_SUPER_continue @ resolved, continue on 3123 b .LOP_INVOKE_SUPER_resolve @ do resolve now 3124 3125 /* ------------------------------ */ 3126 .balign 64 3127 .L_OP_INVOKE_DIRECT: /* 0x70 */ 3128 /* File: armv5te/OP_INVOKE_DIRECT.S */ 3129 /* 3130 * Handle a direct method call. 3131 * 3132 * (We could defer the "is 'this' pointer null" test to the common 3133 * method invocation code, and use a flag to indicate that static 3134 * calls don't count. If we do this as part of copying the arguments 3135 * out we could avoiding loading the first arg twice.) 3136 * 3137 * for: invoke-direct, invoke-direct/range 3138 */ 3139 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3140 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3141 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3142 FETCH(r1, 1) @ r1<- BBBB 3143 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3144 FETCH(r10, 2) @ r10<- GFED or CCCC 3145 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3146 .if (!0) 3147 and r10, r10, #15 @ r10<- D (or stays CCCC) 3148 .endif 3149 cmp r0, #0 @ already resolved? 3150 EXPORT_PC() @ must export for invoke 3151 GET_VREG(r9, r10) @ r9<- "this" ptr 3152 beq .LOP_INVOKE_DIRECT_resolve @ not resolved, do it now 3153 .LOP_INVOKE_DIRECT_finish: 3154 cmp r9, #0 @ null "this" ref? 3155 bne common_invokeMethodNoRange @ r0=method, r9="this" 3156 b common_errNullObject @ yes, throw exception 3157 3158 /* ------------------------------ */ 3159 .balign 64 3160 .L_OP_INVOKE_STATIC: /* 0x71 */ 3161 /* File: armv5te/OP_INVOKE_STATIC.S */ 3162 /* 3163 * Handle a static method call. 3164 * 3165 * for: invoke-static, invoke-static/range 3166 */ 3167 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3168 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3169 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3170 FETCH(r1, 1) @ r1<- BBBB 3171 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3172 mov r9, #0 @ null "this" in delay slot 3173 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3174 #if defined(WITH_JIT) 3175 add r10, r3, r1, lsl #2 @ r10<- &resolved_methodToCall 3176 #endif 3177 cmp r0, #0 @ already resolved? 3178 EXPORT_PC() @ must export for invoke 3179 bne common_invokeMethodNoRange @ yes, continue on 3180 b .LOP_INVOKE_STATIC_resolve 3181 3182 /* ------------------------------ */ 3183 .balign 64 3184 .L_OP_INVOKE_INTERFACE: /* 0x72 */ 3185 /* File: armv5te/OP_INVOKE_INTERFACE.S */ 3186 /* 3187 * Handle an interface method call. 3188 * 3189 * for: invoke-interface, invoke-interface/range 3190 */ 3191 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3192 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3193 FETCH(r2, 2) @ r2<- FEDC or CCCC 3194 FETCH(r1, 1) @ r1<- BBBB 3195 .if (!0) 3196 and r2, r2, #15 @ r2<- C (or stays CCCC) 3197 .endif 3198 EXPORT_PC() @ must export for invoke 3199 GET_VREG(r9, r2) @ r9<- first arg ("this") 3200 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- methodClassDex 3201 cmp r9, #0 @ null obj? 3202 ldr r2, [rSELF, #offThread_method] @ r2<- method 3203 beq common_errNullObject @ yes, fail 3204 ldr r0, [r9, #offObject_clazz] @ r0<- thisPtr->clazz 3205 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3206 cmp r0, #0 @ failed? 3207 beq common_exceptionThrown @ yes, handle exception 3208 b common_invokeMethodNoRange @ (r0=method, r9="this") 3209 3210 /* ------------------------------ */ 3211 .balign 64 3212 .L_OP_UNUSED_73: /* 0x73 */ 3213 /* File: armv5te/OP_UNUSED_73.S */ 3214 /* File: armv5te/unused.S */ 3215 bl common_abort 3216 3217 3218 /* ------------------------------ */ 3219 .balign 64 3220 .L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 3221 /* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */ 3222 /* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3223 /* 3224 * Handle a virtual method call. 3225 * 3226 * for: invoke-virtual, invoke-virtual/range 3227 */ 3228 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3229 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3230 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3231 FETCH(r1, 1) @ r1<- BBBB 3232 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3233 FETCH(r10, 2) @ r10<- GFED or CCCC 3234 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3235 .if (!1) 3236 and r10, r10, #15 @ r10<- D (or stays CCCC) 3237 .endif 3238 cmp r0, #0 @ already resolved? 3239 EXPORT_PC() @ must export for invoke 3240 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ yes, continue on 3241 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3242 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3243 mov r2, #METHOD_VIRTUAL @ resolver method type 3244 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3245 cmp r0, #0 @ got null? 3246 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ no, continue 3247 b common_exceptionThrown @ yes, handle exception 3248 3249 3250 /* ------------------------------ */ 3251 .balign 64 3252 .L_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 3253 /* File: armv5te/OP_INVOKE_SUPER_RANGE.S */ 3254 /* File: armv5te/OP_INVOKE_SUPER.S */ 3255 /* 3256 * Handle a "super" method call. 3257 * 3258 * for: invoke-super, invoke-super/range 3259 */ 3260 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3261 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3262 FETCH(r10, 2) @ r10<- GFED or CCCC 3263 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3264 .if (!1) 3265 and r10, r10, #15 @ r10<- D (or stays CCCC) 3266 .endif 3267 FETCH(r1, 1) @ r1<- BBBB 3268 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3269 GET_VREG(r9, r10) @ r9<- "this" ptr 3270 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3271 cmp r9, #0 @ null "this"? 3272 ldr r10, [rSELF, #offThread_method] @ r10<- current method 3273 beq common_errNullObject @ null "this", throw exception 3274 cmp r0, #0 @ already resolved? 3275 ldr r10, [r10, #offMethod_clazz] @ r10<- method->clazz 3276 EXPORT_PC() @ must export for invoke 3277 bne .LOP_INVOKE_SUPER_RANGE_continue @ resolved, continue on 3278 b .LOP_INVOKE_SUPER_RANGE_resolve @ do resolve now 3279 3280 3281 /* ------------------------------ */ 3282 .balign 64 3283 .L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 3284 /* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */ 3285 /* File: armv5te/OP_INVOKE_DIRECT.S */ 3286 /* 3287 * Handle a direct method call. 3288 * 3289 * (We could defer the "is 'this' pointer null" test to the common 3290 * method invocation code, and use a flag to indicate that static 3291 * calls don't count. If we do this as part of copying the arguments 3292 * out we could avoiding loading the first arg twice.) 3293 * 3294 * for: invoke-direct, invoke-direct/range 3295 */ 3296 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3297 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3298 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3299 FETCH(r1, 1) @ r1<- BBBB 3300 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3301 FETCH(r10, 2) @ r10<- GFED or CCCC 3302 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3303 .if (!1) 3304 and r10, r10, #15 @ r10<- D (or stays CCCC) 3305 .endif 3306 cmp r0, #0 @ already resolved? 3307 EXPORT_PC() @ must export for invoke 3308 GET_VREG(r9, r10) @ r9<- "this" ptr 3309 beq .LOP_INVOKE_DIRECT_RANGE_resolve @ not resolved, do it now 3310 .LOP_INVOKE_DIRECT_RANGE_finish: 3311 cmp r9, #0 @ null "this" ref? 3312 bne common_invokeMethodRange @ r0=method, r9="this" 3313 b common_errNullObject @ yes, throw exception 3314 3315 3316 /* ------------------------------ */ 3317 .balign 64 3318 .L_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 3319 /* File: armv5te/OP_INVOKE_STATIC_RANGE.S */ 3320 /* File: armv5te/OP_INVOKE_STATIC.S */ 3321 /* 3322 * Handle a static method call. 3323 * 3324 * for: invoke-static, invoke-static/range 3325 */ 3326 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3327 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3328 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3329 FETCH(r1, 1) @ r1<- BBBB 3330 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3331 mov r9, #0 @ null "this" in delay slot 3332 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3333 #if defined(WITH_JIT) 3334 add r10, r3, r1, lsl #2 @ r10<- &resolved_methodToCall 3335 #endif 3336 cmp r0, #0 @ already resolved? 3337 EXPORT_PC() @ must export for invoke 3338 bne common_invokeMethodRange @ yes, continue on 3339 b .LOP_INVOKE_STATIC_RANGE_resolve 3340 3341 3342 /* ------------------------------ */ 3343 .balign 64 3344 .L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 3345 /* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */ 3346 /* File: armv5te/OP_INVOKE_INTERFACE.S */ 3347 /* 3348 * Handle an interface method call. 3349 * 3350 * for: invoke-interface, invoke-interface/range 3351 */ 3352 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3353 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3354 FETCH(r2, 2) @ r2<- FEDC or CCCC 3355 FETCH(r1, 1) @ r1<- BBBB 3356 .if (!1) 3357 and r2, r2, #15 @ r2<- C (or stays CCCC) 3358 .endif 3359 EXPORT_PC() @ must export for invoke 3360 GET_VREG(r9, r2) @ r9<- first arg ("this") 3361 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- methodClassDex 3362 cmp r9, #0 @ null obj? 3363 ldr r2, [rSELF, #offThread_method] @ r2<- method 3364 beq common_errNullObject @ yes, fail 3365 ldr r0, [r9, #offObject_clazz] @ r0<- thisPtr->clazz 3366 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3367 cmp r0, #0 @ failed? 3368 beq common_exceptionThrown @ yes, handle exception 3369 b common_invokeMethodRange @ (r0=method, r9="this") 3370 3371 3372 /* ------------------------------ */ 3373 .balign 64 3374 .L_OP_UNUSED_79: /* 0x79 */ 3375 /* File: armv5te/OP_UNUSED_79.S */ 3376 /* File: armv5te/unused.S */ 3377 bl common_abort 3378 3379 3380 /* ------------------------------ */ 3381 .balign 64 3382 .L_OP_UNUSED_7A: /* 0x7a */ 3383 /* File: armv5te/OP_UNUSED_7A.S */ 3384 /* File: armv5te/unused.S */ 3385 bl common_abort 3386 3387 3388 /* ------------------------------ */ 3389 .balign 64 3390 .L_OP_NEG_INT: /* 0x7b */ 3391 /* File: armv6t2/OP_NEG_INT.S */ 3392 /* File: armv6t2/unop.S */ 3393 /* 3394 * Generic 32-bit unary operation. Provide an "instr" line that 3395 * specifies an instruction that performs "result = op r0". 3396 * This could be an ARM instruction or a function call. 3397 * 3398 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3399 * int-to-byte, int-to-char, int-to-short 3400 */ 3401 /* unop vA, vB */ 3402 mov r3, rINST, lsr #12 @ r3<- B 3403 ubfx r9, rINST, #8, #4 @ r9<- A 3404 GET_VREG(r0, r3) @ r0<- vB 3405 @ optional op; may set condition codes 3406 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3407 rsb r0, r0, #0 @ r0<- op, r0-r3 changed 3408 GET_INST_OPCODE(ip) @ extract opcode from rINST 3409 SET_VREG(r0, r9) @ vAA<- r0 3410 GOTO_OPCODE(ip) @ jump to next instruction 3411 /* 8-9 instructions */ 3412 3413 3414 /* ------------------------------ */ 3415 .balign 64 3416 .L_OP_NOT_INT: /* 0x7c */ 3417 /* File: armv6t2/OP_NOT_INT.S */ 3418 /* File: armv6t2/unop.S */ 3419 /* 3420 * Generic 32-bit unary operation. Provide an "instr" line that 3421 * specifies an instruction that performs "result = op r0". 3422 * This could be an ARM instruction or a function call. 3423 * 3424 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3425 * int-to-byte, int-to-char, int-to-short 3426 */ 3427 /* unop vA, vB */ 3428 mov r3, rINST, lsr #12 @ r3<- B 3429 ubfx r9, rINST, #8, #4 @ r9<- A 3430 GET_VREG(r0, r3) @ r0<- vB 3431 @ optional op; may set condition codes 3432 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3433 mvn r0, r0 @ r0<- op, r0-r3 changed 3434 GET_INST_OPCODE(ip) @ extract opcode from rINST 3435 SET_VREG(r0, r9) @ vAA<- r0 3436 GOTO_OPCODE(ip) @ jump to next instruction 3437 /* 8-9 instructions */ 3438 3439 3440 /* ------------------------------ */ 3441 .balign 64 3442 .L_OP_NEG_LONG: /* 0x7d */ 3443 /* File: armv6t2/OP_NEG_LONG.S */ 3444 /* File: armv6t2/unopWide.S */ 3445 /* 3446 * Generic 64-bit unary operation. Provide an "instr" line that 3447 * specifies an instruction that performs "result = op r0/r1". 3448 * This could be an ARM instruction or a function call. 3449 * 3450 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3451 */ 3452 /* unop vA, vB */ 3453 mov r3, rINST, lsr #12 @ r3<- B 3454 ubfx r9, rINST, #8, #4 @ r9<- A 3455 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3456 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3457 ldmia r3, {r0-r1} @ r0/r1<- vAA 3458 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3459 rsbs r0, r0, #0 @ optional op; may set condition codes 3460 rsc r1, r1, #0 @ r0/r1<- op, r2-r3 changed 3461 GET_INST_OPCODE(ip) @ extract opcode from rINST 3462 stmia r9, {r0-r1} @ vAA<- r0/r1 3463 GOTO_OPCODE(ip) @ jump to next instruction 3464 /* 10-11 instructions */ 3465 3466 3467 /* ------------------------------ */ 3468 .balign 64 3469 .L_OP_NOT_LONG: /* 0x7e */ 3470 /* File: armv6t2/OP_NOT_LONG.S */ 3471 /* File: armv6t2/unopWide.S */ 3472 /* 3473 * Generic 64-bit unary operation. Provide an "instr" line that 3474 * specifies an instruction that performs "result = op r0/r1". 3475 * This could be an ARM instruction or a function call. 3476 * 3477 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3478 */ 3479 /* unop vA, vB */ 3480 mov r3, rINST, lsr #12 @ r3<- B 3481 ubfx r9, rINST, #8, #4 @ r9<- A 3482 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3483 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3484 ldmia r3, {r0-r1} @ r0/r1<- vAA 3485 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3486 mvn r0, r0 @ optional op; may set condition codes 3487 mvn r1, r1 @ r0/r1<- op, r2-r3 changed 3488 GET_INST_OPCODE(ip) @ extract opcode from rINST 3489 stmia r9, {r0-r1} @ vAA<- r0/r1 3490 GOTO_OPCODE(ip) @ jump to next instruction 3491 /* 10-11 instructions */ 3492 3493 3494 /* ------------------------------ */ 3495 .balign 64 3496 .L_OP_NEG_FLOAT: /* 0x7f */ 3497 /* File: armv6t2/OP_NEG_FLOAT.S */ 3498 /* File: armv6t2/unop.S */ 3499 /* 3500 * Generic 32-bit unary operation. Provide an "instr" line that 3501 * specifies an instruction that performs "result = op r0". 3502 * This could be an ARM instruction or a function call. 3503 * 3504 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3505 * int-to-byte, int-to-char, int-to-short 3506 */ 3507 /* unop vA, vB */ 3508 mov r3, rINST, lsr #12 @ r3<- B 3509 ubfx r9, rINST, #8, #4 @ r9<- A 3510 GET_VREG(r0, r3) @ r0<- vB 3511 @ optional op; may set condition codes 3512 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3513 add r0, r0, #0x80000000 @ r0<- op, r0-r3 changed 3514 GET_INST_OPCODE(ip) @ extract opcode from rINST 3515 SET_VREG(r0, r9) @ vAA<- r0 3516 GOTO_OPCODE(ip) @ jump to next instruction 3517 /* 8-9 instructions */ 3518 3519 3520 /* ------------------------------ */ 3521 .balign 64 3522 .L_OP_NEG_DOUBLE: /* 0x80 */ 3523 /* File: armv6t2/OP_NEG_DOUBLE.S */ 3524 /* File: armv6t2/unopWide.S */ 3525 /* 3526 * Generic 64-bit unary operation. Provide an "instr" line that 3527 * specifies an instruction that performs "result = op r0/r1". 3528 * This could be an ARM instruction or a function call. 3529 * 3530 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3531 */ 3532 /* unop vA, vB */ 3533 mov r3, rINST, lsr #12 @ r3<- B 3534 ubfx r9, rINST, #8, #4 @ r9<- A 3535 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3536 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3537 ldmia r3, {r0-r1} @ r0/r1<- vAA 3538 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3539 @ optional op; may set condition codes 3540 add r1, r1, #0x80000000 @ r0/r1<- op, r2-r3 changed 3541 GET_INST_OPCODE(ip) @ extract opcode from rINST 3542 stmia r9, {r0-r1} @ vAA<- r0/r1 3543 GOTO_OPCODE(ip) @ jump to next instruction 3544 /* 10-11 instructions */ 3545 3546 3547 /* ------------------------------ */ 3548 .balign 64 3549 .L_OP_INT_TO_LONG: /* 0x81 */ 3550 /* File: armv6t2/OP_INT_TO_LONG.S */ 3551 /* File: armv6t2/unopWider.S */ 3552 /* 3553 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3554 * that specifies an instruction that performs "result = op r0", where 3555 * "result" is a 64-bit quantity in r0/r1. 3556 * 3557 * For: int-to-long, int-to-double, float-to-long, float-to-double 3558 */ 3559 /* unop vA, vB */ 3560 mov r3, rINST, lsr #12 @ r3<- B 3561 ubfx r9, rINST, #8, #4 @ r9<- A 3562 GET_VREG(r0, r3) @ r0<- vB 3563 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3564 @ optional op; may set condition codes 3565 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3566 mov r1, r0, asr #31 @ r0<- op, r0-r3 changed 3567 GET_INST_OPCODE(ip) @ extract opcode from rINST 3568 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3569 GOTO_OPCODE(ip) @ jump to next instruction 3570 /* 9-10 instructions */ 3571 3572 3573 /* ------------------------------ */ 3574 .balign 64 3575 .L_OP_INT_TO_FLOAT: /* 0x82 */ 3576 /* File: arm-vfp/OP_INT_TO_FLOAT.S */ 3577 /* File: arm-vfp/funop.S */ 3578 /* 3579 * Generic 32-bit unary floating-point operation. Provide an "instr" 3580 * line that specifies an instruction that performs "s1 = op s0". 3581 * 3582 * for: int-to-float, float-to-int 3583 */ 3584 /* unop vA, vB */ 3585 mov r3, rINST, lsr #12 @ r3<- B 3586 mov r9, rINST, lsr #8 @ r9<- A+ 3587 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3588 flds s0, [r3] @ s0<- vB 3589 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3590 and r9, r9, #15 @ r9<- A 3591 fsitos s1, s0 @ s1<- op 3592 GET_INST_OPCODE(ip) @ extract opcode from rINST 3593 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3594 fsts s1, [r9] @ vA<- s1 3595 GOTO_OPCODE(ip) @ jump to next instruction 3596 3597 3598 /* ------------------------------ */ 3599 .balign 64 3600 .L_OP_INT_TO_DOUBLE: /* 0x83 */ 3601 /* File: arm-vfp/OP_INT_TO_DOUBLE.S */ 3602 /* File: arm-vfp/funopWider.S */ 3603 /* 3604 * Generic 32bit-to-64bit floating point unary operation. Provide an 3605 * "instr" line that specifies an instruction that performs "d0 = op s0". 3606 * 3607 * For: int-to-double, float-to-double 3608 */ 3609 /* unop vA, vB */ 3610 mov r3, rINST, lsr #12 @ r3<- B 3611 mov r9, rINST, lsr #8 @ r9<- A+ 3612 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3613 flds s0, [r3] @ s0<- vB 3614 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3615 and r9, r9, #15 @ r9<- A 3616 fsitod d0, s0 @ d0<- op 3617 GET_INST_OPCODE(ip) @ extract opcode from rINST 3618 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3619 fstd d0, [r9] @ vA<- d0 3620 GOTO_OPCODE(ip) @ jump to next instruction 3621 3622 3623 /* ------------------------------ */ 3624 .balign 64 3625 .L_OP_LONG_TO_INT: /* 0x84 */ 3626 /* File: armv5te/OP_LONG_TO_INT.S */ 3627 /* we ignore the high word, making this equivalent to a 32-bit reg move */ 3628 /* File: armv5te/OP_MOVE.S */ 3629 /* for move, move-object, long-to-int */ 3630 /* op vA, vB */ 3631 mov r1, rINST, lsr #12 @ r1<- B from 15:12 3632 mov r0, rINST, lsr #8 @ r0<- A from 11:8 3633 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3634 GET_VREG(r2, r1) @ r2<- fp[B] 3635 and r0, r0, #15 3636 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 3637 SET_VREG(r2, r0) @ fp[A]<- r2 3638 GOTO_OPCODE(ip) @ execute next instruction 3639 3640 3641 /* ------------------------------ */ 3642 .balign 64 3643 .L_OP_LONG_TO_FLOAT: /* 0x85 */ 3644 /* File: armv6t2/OP_LONG_TO_FLOAT.S */ 3645 /* File: armv6t2/unopNarrower.S */ 3646 /* 3647 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 3648 * that specifies an instruction that performs "result = op r0/r1", where 3649 * "result" is a 32-bit quantity in r0. 3650 * 3651 * For: long-to-float, double-to-int, double-to-float 3652 * 3653 * (This would work for long-to-int, but that instruction is actually 3654 * an exact match for OP_MOVE.) 3655 */ 3656 /* unop vA, vB */ 3657 mov r3, rINST, lsr #12 @ r3<- B 3658 ubfx r9, rINST, #8, #4 @ r9<- A 3659 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3660 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 3661 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3662 @ optional op; may set condition codes 3663 bl __aeabi_l2f @ r0<- op, r0-r3 changed 3664 GET_INST_OPCODE(ip) @ extract opcode from rINST 3665 SET_VREG(r0, r9) @ vA<- r0 3666 GOTO_OPCODE(ip) @ jump to next instruction 3667 /* 9-10 instructions */ 3668 3669 3670 /* ------------------------------ */ 3671 .balign 64 3672 .L_OP_LONG_TO_DOUBLE: /* 0x86 */ 3673 /* File: armv6t2/OP_LONG_TO_DOUBLE.S */ 3674 /* File: armv6t2/unopWide.S */ 3675 /* 3676 * Generic 64-bit unary operation. Provide an "instr" line that 3677 * specifies an instruction that performs "result = op r0/r1". 3678 * This could be an ARM instruction or a function call. 3679 * 3680 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3681 */ 3682 /* unop vA, vB */ 3683 mov r3, rINST, lsr #12 @ r3<- B 3684 ubfx r9, rINST, #8, #4 @ r9<- A 3685 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3686 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3687 ldmia r3, {r0-r1} @ r0/r1<- vAA 3688 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3689 @ optional op; may set condition codes 3690 bl __aeabi_l2d @ r0/r1<- op, r2-r3 changed 3691 GET_INST_OPCODE(ip) @ extract opcode from rINST 3692 stmia r9, {r0-r1} @ vAA<- r0/r1 3693 GOTO_OPCODE(ip) @ jump to next instruction 3694 /* 10-11 instructions */ 3695 3696 3697 /* ------------------------------ */ 3698 .balign 64 3699 .L_OP_FLOAT_TO_INT: /* 0x87 */ 3700 /* File: arm-vfp/OP_FLOAT_TO_INT.S */ 3701 /* File: arm-vfp/funop.S */ 3702 /* 3703 * Generic 32-bit unary floating-point operation. Provide an "instr" 3704 * line that specifies an instruction that performs "s1 = op s0". 3705 * 3706 * for: int-to-float, float-to-int 3707 */ 3708 /* unop vA, vB */ 3709 mov r3, rINST, lsr #12 @ r3<- B 3710 mov r9, rINST, lsr #8 @ r9<- A+ 3711 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3712 flds s0, [r3] @ s0<- vB 3713 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3714 and r9, r9, #15 @ r9<- A 3715 ftosizs s1, s0 @ s1<- op 3716 GET_INST_OPCODE(ip) @ extract opcode from rINST 3717 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3718 fsts s1, [r9] @ vA<- s1 3719 GOTO_OPCODE(ip) @ jump to next instruction 3720 3721 3722 /* ------------------------------ */ 3723 .balign 64 3724 .L_OP_FLOAT_TO_LONG: /* 0x88 */ 3725 /* File: armv6t2/OP_FLOAT_TO_LONG.S */ 3726 @include "armv6t2/unopWider.S" {"instr":"bl __aeabi_f2lz"} 3727 /* File: armv6t2/unopWider.S */ 3728 /* 3729 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3730 * that specifies an instruction that performs "result = op r0", where 3731 * "result" is a 64-bit quantity in r0/r1. 3732 * 3733 * For: int-to-long, int-to-double, float-to-long, float-to-double 3734 */ 3735 /* unop vA, vB */ 3736 mov r3, rINST, lsr #12 @ r3<- B 3737 ubfx r9, rINST, #8, #4 @ r9<- A 3738 GET_VREG(r0, r3) @ r0<- vB 3739 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3740 @ optional op; may set condition codes 3741 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3742 bl f2l_doconv @ r0<- op, r0-r3 changed 3743 GET_INST_OPCODE(ip) @ extract opcode from rINST 3744 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3745 GOTO_OPCODE(ip) @ jump to next instruction 3746 /* 9-10 instructions */ 3747 3748 3749 3750 /* ------------------------------ */ 3751 .balign 64 3752 .L_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 3753 /* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */ 3754 /* File: arm-vfp/funopWider.S */ 3755 /* 3756 * Generic 32bit-to-64bit floating point unary operation. Provide an 3757 * "instr" line that specifies an instruction that performs "d0 = op s0". 3758 * 3759 * For: int-to-double, float-to-double 3760 */ 3761 /* unop vA, vB */ 3762 mov r3, rINST, lsr #12 @ r3<- B 3763 mov r9, rINST, lsr #8 @ r9<- A+ 3764 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3765 flds s0, [r3] @ s0<- vB 3766 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3767 and r9, r9, #15 @ r9<- A 3768 fcvtds d0, s0 @ d0<- op 3769 GET_INST_OPCODE(ip) @ extract opcode from rINST 3770 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3771 fstd d0, [r9] @ vA<- d0 3772 GOTO_OPCODE(ip) @ jump to next instruction 3773 3774 3775 /* ------------------------------ */ 3776 .balign 64 3777 .L_OP_DOUBLE_TO_INT: /* 0x8a */ 3778 /* File: arm-vfp/OP_DOUBLE_TO_INT.S */ 3779 /* File: arm-vfp/funopNarrower.S */ 3780 /* 3781 * Generic 64bit-to-32bit unary floating point operation. Provide an 3782 * "instr" line that specifies an instruction that performs "s0 = op d0". 3783 * 3784 * For: double-to-int, double-to-float 3785 */ 3786 /* unop vA, vB */ 3787 mov r3, rINST, lsr #12 @ r3<- B 3788 mov r9, rINST, lsr #8 @ r9<- A+ 3789 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3790 fldd d0, [r3] @ d0<- vB 3791 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3792 and r9, r9, #15 @ r9<- A 3793 ftosizd s0, d0 @ s0<- op 3794 GET_INST_OPCODE(ip) @ extract opcode from rINST 3795 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3796 fsts s0, [r9] @ vA<- s0 3797 GOTO_OPCODE(ip) @ jump to next instruction 3798 3799 3800 /* ------------------------------ */ 3801 .balign 64 3802 .L_OP_DOUBLE_TO_LONG: /* 0x8b */ 3803 /* File: armv6t2/OP_DOUBLE_TO_LONG.S */ 3804 @include "armv6t2/unopWide.S" {"instr":"bl __aeabi_d2lz"} 3805 /* File: armv6t2/unopWide.S */ 3806 /* 3807 * Generic 64-bit unary operation. Provide an "instr" line that 3808 * specifies an instruction that performs "result = op r0/r1". 3809 * This could be an ARM instruction or a function call. 3810 * 3811 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3812 */ 3813 /* unop vA, vB */ 3814 mov r3, rINST, lsr #12 @ r3<- B 3815 ubfx r9, rINST, #8, #4 @ r9<- A 3816 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3817 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3818 ldmia r3, {r0-r1} @ r0/r1<- vAA 3819 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3820 @ optional op; may set condition codes 3821 bl d2l_doconv @ r0/r1<- op, r2-r3 changed 3822 GET_INST_OPCODE(ip) @ extract opcode from rINST 3823 stmia r9, {r0-r1} @ vAA<- r0/r1 3824 GOTO_OPCODE(ip) @ jump to next instruction 3825 /* 10-11 instructions */ 3826 3827 3828 3829 /* ------------------------------ */ 3830 .balign 64 3831 .L_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 3832 /* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */ 3833 /* File: arm-vfp/funopNarrower.S */ 3834 /* 3835 * Generic 64bit-to-32bit unary floating point operation. Provide an 3836 * "instr" line that specifies an instruction that performs "s0 = op d0". 3837 * 3838 * For: double-to-int, double-to-float 3839 */ 3840 /* unop vA, vB */ 3841 mov r3, rINST, lsr #12 @ r3<- B 3842 mov r9, rINST, lsr #8 @ r9<- A+ 3843 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3844 fldd d0, [r3] @ d0<- vB 3845 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3846 and r9, r9, #15 @ r9<- A 3847 fcvtsd s0, d0 @ s0<- op 3848 GET_INST_OPCODE(ip) @ extract opcode from rINST 3849 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3850 fsts s0, [r9] @ vA<- s0 3851 GOTO_OPCODE(ip) @ jump to next instruction 3852 3853 3854 /* ------------------------------ */ 3855 .balign 64 3856 .L_OP_INT_TO_BYTE: /* 0x8d */ 3857 /* File: armv6t2/OP_INT_TO_BYTE.S */ 3858 /* File: armv6t2/unop.S */ 3859 /* 3860 * Generic 32-bit unary operation. Provide an "instr" line that 3861 * specifies an instruction that performs "result = op r0". 3862 * This could be an ARM instruction or a function call. 3863 * 3864 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3865 * int-to-byte, int-to-char, int-to-short 3866 */ 3867 /* unop vA, vB */ 3868 mov r3, rINST, lsr #12 @ r3<- B 3869 ubfx r9, rINST, #8, #4 @ r9<- A 3870 GET_VREG(r0, r3) @ r0<- vB 3871 @ optional op; may set condition codes 3872 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3873 sxtb r0, r0 @ r0<- op, r0-r3 changed 3874 GET_INST_OPCODE(ip) @ extract opcode from rINST 3875 SET_VREG(r0, r9) @ vAA<- r0 3876 GOTO_OPCODE(ip) @ jump to next instruction 3877 /* 8-9 instructions */ 3878 3879 3880 /* ------------------------------ */ 3881 .balign 64 3882 .L_OP_INT_TO_CHAR: /* 0x8e */ 3883 /* File: armv6t2/OP_INT_TO_CHAR.S */ 3884 /* File: armv6t2/unop.S */ 3885 /* 3886 * Generic 32-bit unary operation. Provide an "instr" line that 3887 * specifies an instruction that performs "result = op r0". 3888 * This could be an ARM instruction or a function call. 3889 * 3890 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3891 * int-to-byte, int-to-char, int-to-short 3892 */ 3893 /* unop vA, vB */ 3894 mov r3, rINST, lsr #12 @ r3<- B 3895 ubfx r9, rINST, #8, #4 @ r9<- A 3896 GET_VREG(r0, r3) @ r0<- vB 3897 @ optional op; may set condition codes 3898 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3899 uxth r0, r0 @ r0<- op, r0-r3 changed 3900 GET_INST_OPCODE(ip) @ extract opcode from rINST 3901 SET_VREG(r0, r9) @ vAA<- r0 3902 GOTO_OPCODE(ip) @ jump to next instruction 3903 /* 8-9 instructions */ 3904 3905 3906 /* ------------------------------ */ 3907 .balign 64 3908 .L_OP_INT_TO_SHORT: /* 0x8f */ 3909 /* File: armv6t2/OP_INT_TO_SHORT.S */ 3910 /* File: armv6t2/unop.S */ 3911 /* 3912 * Generic 32-bit unary operation. Provide an "instr" line that 3913 * specifies an instruction that performs "result = op r0". 3914 * This could be an ARM instruction or a function call. 3915 * 3916 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3917 * int-to-byte, int-to-char, int-to-short 3918 */ 3919 /* unop vA, vB */ 3920 mov r3, rINST, lsr #12 @ r3<- B 3921 ubfx r9, rINST, #8, #4 @ r9<- A 3922 GET_VREG(r0, r3) @ r0<- vB 3923 @ optional op; may set condition codes 3924 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3925 sxth r0, r0 @ r0<- op, r0-r3 changed 3926 GET_INST_OPCODE(ip) @ extract opcode from rINST 3927 SET_VREG(r0, r9) @ vAA<- r0 3928 GOTO_OPCODE(ip) @ jump to next instruction 3929 /* 8-9 instructions */ 3930 3931 3932 /* ------------------------------ */ 3933 .balign 64 3934 .L_OP_ADD_INT: /* 0x90 */ 3935 /* File: armv5te/OP_ADD_INT.S */ 3936 /* File: armv5te/binop.S */ 3937 /* 3938 * Generic 32-bit binary operation. Provide an "instr" line that 3939 * specifies an instruction that performs "result = r0 op r1". 3940 * This could be an ARM instruction or a function call. (If the result 3941 * comes back in a register other than r0, you can override "result".) 3942 * 3943 * If "chkzero" is set to 1, we perform a divide-by-zero check on 3944 * vCC (r1). Useful for integer division and modulus. Note that we 3945 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 3946 * handles it correctly. 3947 * 3948 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 3949 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 3950 * mul-float, div-float, rem-float 3951 */ 3952 /* binop vAA, vBB, vCC */ 3953 FETCH(r0, 1) @ r0<- CCBB 3954 mov r9, rINST, lsr #8 @ r9<- AA 3955 mov r3, r0, lsr #8 @ r3<- CC 3956 and r2, r0, #255 @ r2<- BB 3957 GET_VREG(r1, r3) @ r1<- vCC 3958 GET_VREG(r0, r2) @ r0<- vBB 3959 .if 0 3960 cmp r1, #0 @ is second operand zero? 3961 beq common_errDivideByZero 3962 .endif 3963 3964 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3965 @ optional op; may set condition codes 3966 add r0, r0, r1 @ r0<- op, r0-r3 changed 3967 GET_INST_OPCODE(ip) @ extract opcode from rINST 3968 SET_VREG(r0, r9) @ vAA<- r0 3969 GOTO_OPCODE(ip) @ jump to next instruction 3970 /* 11-14 instructions */ 3971 3972 3973 /* ------------------------------ */ 3974 .balign 64 3975 .L_OP_SUB_INT: /* 0x91 */ 3976 /* File: armv5te/OP_SUB_INT.S */ 3977 /* File: armv5te/binop.S */ 3978 /* 3979 * Generic 32-bit binary operation. Provide an "instr" line that 3980 * specifies an instruction that performs "result = r0 op r1". 3981 * This could be an ARM instruction or a function call. (If the result 3982 * comes back in a register other than r0, you can override "result".) 3983 * 3984 * If "chkzero" is set to 1, we perform a divide-by-zero check on 3985 * vCC (r1). Useful for integer division and modulus. Note that we 3986 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 3987 * handles it correctly. 3988 * 3989 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 3990 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 3991 * mul-float, div-float, rem-float 3992 */ 3993 /* binop vAA, vBB, vCC */ 3994 FETCH(r0, 1) @ r0<- CCBB 3995 mov r9, rINST, lsr #8 @ r9<- AA 3996 mov r3, r0, lsr #8 @ r3<- CC 3997 and r2, r0, #255 @ r2<- BB 3998 GET_VREG(r1, r3) @ r1<- vCC 3999 GET_VREG(r0, r2) @ r0<- vBB 4000 .if 0 4001 cmp r1, #0 @ is second operand zero? 4002 beq common_errDivideByZero 4003 .endif 4004 4005 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4006 @ optional op; may set condition codes 4007 sub r0, r0, r1 @ r0<- op, r0-r3 changed 4008 GET_INST_OPCODE(ip) @ extract opcode from rINST 4009 SET_VREG(r0, r9) @ vAA<- r0 4010 GOTO_OPCODE(ip) @ jump to next instruction 4011 /* 11-14 instructions */ 4012 4013 4014 /* ------------------------------ */ 4015 .balign 64 4016 .L_OP_MUL_INT: /* 0x92 */ 4017 /* File: armv5te/OP_MUL_INT.S */ 4018 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 4019 /* File: armv5te/binop.S */ 4020 /* 4021 * Generic 32-bit binary operation. Provide an "instr" line that 4022 * specifies an instruction that performs "result = r0 op r1". 4023 * This could be an ARM instruction or a function call. (If the result 4024 * comes back in a register other than r0, you can override "result".) 4025 * 4026 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4027 * vCC (r1). Useful for integer division and modulus. Note that we 4028 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4029 * handles it correctly. 4030 * 4031 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4032 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4033 * mul-float, div-float, rem-float 4034 */ 4035 /* binop vAA, vBB, vCC */ 4036 FETCH(r0, 1) @ r0<- CCBB 4037 mov r9, rINST, lsr #8 @ r9<- AA 4038 mov r3, r0, lsr #8 @ r3<- CC 4039 and r2, r0, #255 @ r2<- BB 4040 GET_VREG(r1, r3) @ r1<- vCC 4041 GET_VREG(r0, r2) @ r0<- vBB 4042 .if 0 4043 cmp r1, #0 @ is second operand zero? 4044 beq common_errDivideByZero 4045 .endif 4046 4047 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4048 @ optional op; may set condition codes 4049 mul r0, r1, r0 @ r0<- op, r0-r3 changed 4050 GET_INST_OPCODE(ip) @ extract opcode from rINST 4051 SET_VREG(r0, r9) @ vAA<- r0 4052 GOTO_OPCODE(ip) @ jump to next instruction 4053 /* 11-14 instructions */ 4054 4055 4056 /* ------------------------------ */ 4057 .balign 64 4058 .L_OP_DIV_INT: /* 0x93 */ 4059 /* File: armv5te/OP_DIV_INT.S */ 4060 /* File: armv5te/binop.S */ 4061 /* 4062 * Generic 32-bit binary operation. Provide an "instr" line that 4063 * specifies an instruction that performs "result = r0 op r1". 4064 * This could be an ARM instruction or a function call. (If the result 4065 * comes back in a register other than r0, you can override "result".) 4066 * 4067 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4068 * vCC (r1). Useful for integer division and modulus. Note that we 4069 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4070 * handles it correctly. 4071 * 4072 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4073 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4074 * mul-float, div-float, rem-float 4075 */ 4076 /* binop vAA, vBB, vCC */ 4077 FETCH(r0, 1) @ r0<- CCBB 4078 mov r9, rINST, lsr #8 @ r9<- AA 4079 mov r3, r0, lsr #8 @ r3<- CC 4080 and r2, r0, #255 @ r2<- BB 4081 GET_VREG(r1, r3) @ r1<- vCC 4082 GET_VREG(r0, r2) @ r0<- vBB 4083 .if 1 4084 cmp r1, #0 @ is second operand zero? 4085 beq common_errDivideByZero 4086 .endif 4087 4088 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4089 @ optional op; may set condition codes 4090 bl __aeabi_idiv @ r0<- op, r0-r3 changed 4091 GET_INST_OPCODE(ip) @ extract opcode from rINST 4092 SET_VREG(r0, r9) @ vAA<- r0 4093 GOTO_OPCODE(ip) @ jump to next instruction 4094 /* 11-14 instructions */ 4095 4096 4097 /* ------------------------------ */ 4098 .balign 64 4099 .L_OP_REM_INT: /* 0x94 */ 4100 /* File: armv5te/OP_REM_INT.S */ 4101 /* idivmod returns quotient in r0 and remainder in r1 */ 4102 /* File: armv5te/binop.S */ 4103 /* 4104 * Generic 32-bit binary operation. Provide an "instr" line that 4105 * specifies an instruction that performs "result = r0 op r1". 4106 * This could be an ARM instruction or a function call. (If the result 4107 * comes back in a register other than r0, you can override "result".) 4108 * 4109 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4110 * vCC (r1). Useful for integer division and modulus. Note that we 4111 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4112 * handles it correctly. 4113 * 4114 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4115 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4116 * mul-float, div-float, rem-float 4117 */ 4118 /* binop vAA, vBB, vCC */ 4119 FETCH(r0, 1) @ r0<- CCBB 4120 mov r9, rINST, lsr #8 @ r9<- AA 4121 mov r3, r0, lsr #8 @ r3<- CC 4122 and r2, r0, #255 @ r2<- BB 4123 GET_VREG(r1, r3) @ r1<- vCC 4124 GET_VREG(r0, r2) @ r0<- vBB 4125 .if 1 4126 cmp r1, #0 @ is second operand zero? 4127 beq common_errDivideByZero 4128 .endif 4129 4130 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4131 @ optional op; may set condition codes 4132 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 4133 GET_INST_OPCODE(ip) @ extract opcode from rINST 4134 SET_VREG(r1, r9) @ vAA<- r1 4135 GOTO_OPCODE(ip) @ jump to next instruction 4136 /* 11-14 instructions */ 4137 4138 4139 /* ------------------------------ */ 4140 .balign 64 4141 .L_OP_AND_INT: /* 0x95 */ 4142 /* File: armv5te/OP_AND_INT.S */ 4143 /* File: armv5te/binop.S */ 4144 /* 4145 * Generic 32-bit binary operation. Provide an "instr" line that 4146 * specifies an instruction that performs "result = r0 op r1". 4147 * This could be an ARM instruction or a function call. (If the result 4148 * comes back in a register other than r0, you can override "result".) 4149 * 4150 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4151 * vCC (r1). Useful for integer division and modulus. Note that we 4152 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4153 * handles it correctly. 4154 * 4155 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4156 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4157 * mul-float, div-float, rem-float 4158 */ 4159 /* binop vAA, vBB, vCC */ 4160 FETCH(r0, 1) @ r0<- CCBB 4161 mov r9, rINST, lsr #8 @ r9<- AA 4162 mov r3, r0, lsr #8 @ r3<- CC 4163 and r2, r0, #255 @ r2<- BB 4164 GET_VREG(r1, r3) @ r1<- vCC 4165 GET_VREG(r0, r2) @ r0<- vBB 4166 .if 0 4167 cmp r1, #0 @ is second operand zero? 4168 beq common_errDivideByZero 4169 .endif 4170 4171 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4172 @ optional op; may set condition codes 4173 and r0, r0, r1 @ r0<- op, r0-r3 changed 4174 GET_INST_OPCODE(ip) @ extract opcode from rINST 4175 SET_VREG(r0, r9) @ vAA<- r0 4176 GOTO_OPCODE(ip) @ jump to next instruction 4177 /* 11-14 instructions */ 4178 4179 4180 /* ------------------------------ */ 4181 .balign 64 4182 .L_OP_OR_INT: /* 0x96 */ 4183 /* File: armv5te/OP_OR_INT.S */ 4184 /* File: armv5te/binop.S */ 4185 /* 4186 * Generic 32-bit binary operation. Provide an "instr" line that 4187 * specifies an instruction that performs "result = r0 op r1". 4188 * This could be an ARM instruction or a function call. (If the result 4189 * comes back in a register other than r0, you can override "result".) 4190 * 4191 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4192 * vCC (r1). Useful for integer division and modulus. Note that we 4193 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4194 * handles it correctly. 4195 * 4196 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4197 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4198 * mul-float, div-float, rem-float 4199 */ 4200 /* binop vAA, vBB, vCC */ 4201 FETCH(r0, 1) @ r0<- CCBB 4202 mov r9, rINST, lsr #8 @ r9<- AA 4203 mov r3, r0, lsr #8 @ r3<- CC 4204 and r2, r0, #255 @ r2<- BB 4205 GET_VREG(r1, r3) @ r1<- vCC 4206 GET_VREG(r0, r2) @ r0<- vBB 4207 .if 0 4208 cmp r1, #0 @ is second operand zero? 4209 beq common_errDivideByZero 4210 .endif 4211 4212 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4213 @ optional op; may set condition codes 4214 orr r0, r0, r1 @ r0<- op, r0-r3 changed 4215 GET_INST_OPCODE(ip) @ extract opcode from rINST 4216 SET_VREG(r0, r9) @ vAA<- r0 4217 GOTO_OPCODE(ip) @ jump to next instruction 4218 /* 11-14 instructions */ 4219 4220 4221 /* ------------------------------ */ 4222 .balign 64 4223 .L_OP_XOR_INT: /* 0x97 */ 4224 /* File: armv5te/OP_XOR_INT.S */ 4225 /* File: armv5te/binop.S */ 4226 /* 4227 * Generic 32-bit binary operation. Provide an "instr" line that 4228 * specifies an instruction that performs "result = r0 op r1". 4229 * This could be an ARM instruction or a function call. (If the result 4230 * comes back in a register other than r0, you can override "result".) 4231 * 4232 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4233 * vCC (r1). Useful for integer division and modulus. Note that we 4234 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4235 * handles it correctly. 4236 * 4237 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4238 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4239 * mul-float, div-float, rem-float 4240 */ 4241 /* binop vAA, vBB, vCC */ 4242 FETCH(r0, 1) @ r0<- CCBB 4243 mov r9, rINST, lsr #8 @ r9<- AA 4244 mov r3, r0, lsr #8 @ r3<- CC 4245 and r2, r0, #255 @ r2<- BB 4246 GET_VREG(r1, r3) @ r1<- vCC 4247 GET_VREG(r0, r2) @ r0<- vBB 4248 .if 0 4249 cmp r1, #0 @ is second operand zero? 4250 beq common_errDivideByZero 4251 .endif 4252 4253 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4254 @ optional op; may set condition codes 4255 eor r0, r0, r1 @ r0<- op, r0-r3 changed 4256 GET_INST_OPCODE(ip) @ extract opcode from rINST 4257 SET_VREG(r0, r9) @ vAA<- r0 4258 GOTO_OPCODE(ip) @ jump to next instruction 4259 /* 11-14 instructions */ 4260 4261 4262 /* ------------------------------ */ 4263 .balign 64 4264 .L_OP_SHL_INT: /* 0x98 */ 4265 /* File: armv5te/OP_SHL_INT.S */ 4266 /* File: armv5te/binop.S */ 4267 /* 4268 * Generic 32-bit binary operation. Provide an "instr" line that 4269 * specifies an instruction that performs "result = r0 op r1". 4270 * This could be an ARM instruction or a function call. (If the result 4271 * comes back in a register other than r0, you can override "result".) 4272 * 4273 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4274 * vCC (r1). Useful for integer division and modulus. Note that we 4275 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4276 * handles it correctly. 4277 * 4278 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4279 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4280 * mul-float, div-float, rem-float 4281 */ 4282 /* binop vAA, vBB, vCC */ 4283 FETCH(r0, 1) @ r0<- CCBB 4284 mov r9, rINST, lsr #8 @ r9<- AA 4285 mov r3, r0, lsr #8 @ r3<- CC 4286 and r2, r0, #255 @ r2<- BB 4287 GET_VREG(r1, r3) @ r1<- vCC 4288 GET_VREG(r0, r2) @ r0<- vBB 4289 .if 0 4290 cmp r1, #0 @ is second operand zero? 4291 beq common_errDivideByZero 4292 .endif 4293 4294 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4295 and r1, r1, #31 @ optional op; may set condition codes 4296 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 4297 GET_INST_OPCODE(ip) @ extract opcode from rINST 4298 SET_VREG(r0, r9) @ vAA<- r0 4299 GOTO_OPCODE(ip) @ jump to next instruction 4300 /* 11-14 instructions */ 4301 4302 4303 /* ------------------------------ */ 4304 .balign 64 4305 .L_OP_SHR_INT: /* 0x99 */ 4306 /* File: armv5te/OP_SHR_INT.S */ 4307 /* File: armv5te/binop.S */ 4308 /* 4309 * Generic 32-bit binary operation. Provide an "instr" line that 4310 * specifies an instruction that performs "result = r0 op r1". 4311 * This could be an ARM instruction or a function call. (If the result 4312 * comes back in a register other than r0, you can override "result".) 4313 * 4314 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4315 * vCC (r1). Useful for integer division and modulus. Note that we 4316 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4317 * handles it correctly. 4318 * 4319 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4320 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4321 * mul-float, div-float, rem-float 4322 */ 4323 /* binop vAA, vBB, vCC */ 4324 FETCH(r0, 1) @ r0<- CCBB 4325 mov r9, rINST, lsr #8 @ r9<- AA 4326 mov r3, r0, lsr #8 @ r3<- CC 4327 and r2, r0, #255 @ r2<- BB 4328 GET_VREG(r1, r3) @ r1<- vCC 4329 GET_VREG(r0, r2) @ r0<- vBB 4330 .if 0 4331 cmp r1, #0 @ is second operand zero? 4332 beq common_errDivideByZero 4333 .endif 4334 4335 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4336 and r1, r1, #31 @ optional op; may set condition codes 4337 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 4338 GET_INST_OPCODE(ip) @ extract opcode from rINST 4339 SET_VREG(r0, r9) @ vAA<- r0 4340 GOTO_OPCODE(ip) @ jump to next instruction 4341 /* 11-14 instructions */ 4342 4343 4344 /* ------------------------------ */ 4345 .balign 64 4346 .L_OP_USHR_INT: /* 0x9a */ 4347 /* File: armv5te/OP_USHR_INT.S */ 4348 /* File: armv5te/binop.S */ 4349 /* 4350 * Generic 32-bit binary operation. Provide an "instr" line that 4351 * specifies an instruction that performs "result = r0 op r1". 4352 * This could be an ARM instruction or a function call. (If the result 4353 * comes back in a register other than r0, you can override "result".) 4354 * 4355 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4356 * vCC (r1). Useful for integer division and modulus. Note that we 4357 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4358 * handles it correctly. 4359 * 4360 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4361 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4362 * mul-float, div-float, rem-float 4363 */ 4364 /* binop vAA, vBB, vCC */ 4365 FETCH(r0, 1) @ r0<- CCBB 4366 mov r9, rINST, lsr #8 @ r9<- AA 4367 mov r3, r0, lsr #8 @ r3<- CC 4368 and r2, r0, #255 @ r2<- BB 4369 GET_VREG(r1, r3) @ r1<- vCC 4370 GET_VREG(r0, r2) @ r0<- vBB 4371 .if 0 4372 cmp r1, #0 @ is second operand zero? 4373 beq common_errDivideByZero 4374 .endif 4375 4376 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4377 and r1, r1, #31 @ optional op; may set condition codes 4378 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 4379 GET_INST_OPCODE(ip) @ extract opcode from rINST 4380 SET_VREG(r0, r9) @ vAA<- r0 4381 GOTO_OPCODE(ip) @ jump to next instruction 4382 /* 11-14 instructions */ 4383 4384 4385 /* ------------------------------ */ 4386 .balign 64 4387 .L_OP_ADD_LONG: /* 0x9b */ 4388 /* File: armv5te/OP_ADD_LONG.S */ 4389 /* File: armv5te/binopWide.S */ 4390 /* 4391 * Generic 64-bit binary operation. Provide an "instr" line that 4392 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4393 * This could be an ARM instruction or a function call. (If the result 4394 * comes back in a register other than r0, you can override "result".) 4395 * 4396 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4397 * vCC (r1). Useful for integer division and modulus. 4398 * 4399 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4400 * xor-long, add-double, sub-double, mul-double, div-double, 4401 * rem-double 4402 * 4403 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4404 */ 4405 /* binop vAA, vBB, vCC */ 4406 FETCH(r0, 1) @ r0<- CCBB 4407 mov r9, rINST, lsr #8 @ r9<- AA 4408 and r2, r0, #255 @ r2<- BB 4409 mov r3, r0, lsr #8 @ r3<- CC 4410 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4411 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4412 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4413 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4414 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4415 .if 0 4416 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4417 beq common_errDivideByZero 4418 .endif 4419 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4420 4421 adds r0, r0, r2 @ optional op; may set condition codes 4422 adc r1, r1, r3 @ result<- op, r0-r3 changed 4423 GET_INST_OPCODE(ip) @ extract opcode from rINST 4424 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4425 GOTO_OPCODE(ip) @ jump to next instruction 4426 /* 14-17 instructions */ 4427 4428 4429 /* ------------------------------ */ 4430 .balign 64 4431 .L_OP_SUB_LONG: /* 0x9c */ 4432 /* File: armv5te/OP_SUB_LONG.S */ 4433 /* File: armv5te/binopWide.S */ 4434 /* 4435 * Generic 64-bit binary operation. Provide an "instr" line that 4436 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4437 * This could be an ARM instruction or a function call. (If the result 4438 * comes back in a register other than r0, you can override "result".) 4439 * 4440 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4441 * vCC (r1). Useful for integer division and modulus. 4442 * 4443 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4444 * xor-long, add-double, sub-double, mul-double, div-double, 4445 * rem-double 4446 * 4447 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4448 */ 4449 /* binop vAA, vBB, vCC */ 4450 FETCH(r0, 1) @ r0<- CCBB 4451 mov r9, rINST, lsr #8 @ r9<- AA 4452 and r2, r0, #255 @ r2<- BB 4453 mov r3, r0, lsr #8 @ r3<- CC 4454 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4455 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4456 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4457 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4458 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4459 .if 0 4460 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4461 beq common_errDivideByZero 4462 .endif 4463 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4464 4465 subs r0, r0, r2 @ optional op; may set condition codes 4466 sbc r1, r1, r3 @ result<- op, r0-r3 changed 4467 GET_INST_OPCODE(ip) @ extract opcode from rINST 4468 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4469 GOTO_OPCODE(ip) @ jump to next instruction 4470 /* 14-17 instructions */ 4471 4472 4473 /* ------------------------------ */ 4474 .balign 64 4475 .L_OP_MUL_LONG: /* 0x9d */ 4476 /* File: armv5te/OP_MUL_LONG.S */ 4477 /* 4478 * Signed 64-bit integer multiply. 4479 * 4480 * Consider WXxYZ (r1r0 x r3r2) with a long multiply: 4481 * WX 4482 * x YZ 4483 * -------- 4484 * ZW ZX 4485 * YW YX 4486 * 4487 * The low word of the result holds ZX, the high word holds 4488 * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because 4489 * it doesn't fit in the low 64 bits. 4490 * 4491 * Unlike most ARM math operations, multiply instructions have 4492 * restrictions on using the same register more than once (Rd and Rm 4493 * cannot be the same). 4494 */ 4495 /* mul-long vAA, vBB, vCC */ 4496 FETCH(r0, 1) @ r0<- CCBB 4497 and r2, r0, #255 @ r2<- BB 4498 mov r3, r0, lsr #8 @ r3<- CC 4499 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4500 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4501 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4502 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4503 mul ip, r2, r1 @ ip<- ZxW 4504 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 4505 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 4506 mov r0, rINST, lsr #8 @ r0<- AA 4507 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 4508 add r0, rFP, r0, lsl #2 @ r0<- &fp[AA] 4509 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4510 b .LOP_MUL_LONG_finish 4511 4512 /* ------------------------------ */ 4513 .balign 64 4514 .L_OP_DIV_LONG: /* 0x9e */ 4515 /* File: armv5te/OP_DIV_LONG.S */ 4516 /* File: armv5te/binopWide.S */ 4517 /* 4518 * Generic 64-bit binary operation. Provide an "instr" line that 4519 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4520 * This could be an ARM instruction or a function call. (If the result 4521 * comes back in a register other than r0, you can override "result".) 4522 * 4523 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4524 * vCC (r1). Useful for integer division and modulus. 4525 * 4526 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4527 * xor-long, add-double, sub-double, mul-double, div-double, 4528 * rem-double 4529 * 4530 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4531 */ 4532 /* binop vAA, vBB, vCC */ 4533 FETCH(r0, 1) @ r0<- CCBB 4534 mov r9, rINST, lsr #8 @ r9<- AA 4535 and r2, r0, #255 @ r2<- BB 4536 mov r3, r0, lsr #8 @ r3<- CC 4537 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4538 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4539 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4540 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4541 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4542 .if 1 4543 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4544 beq common_errDivideByZero 4545 .endif 4546 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4547 4548 @ optional op; may set condition codes 4549 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4550 GET_INST_OPCODE(ip) @ extract opcode from rINST 4551 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4552 GOTO_OPCODE(ip) @ jump to next instruction 4553 /* 14-17 instructions */ 4554 4555 4556 /* ------------------------------ */ 4557 .balign 64 4558 .L_OP_REM_LONG: /* 0x9f */ 4559 /* File: armv5te/OP_REM_LONG.S */ 4560 /* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 4561 /* File: armv5te/binopWide.S */ 4562 /* 4563 * Generic 64-bit binary operation. Provide an "instr" line that 4564 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4565 * This could be an ARM instruction or a function call. (If the result 4566 * comes back in a register other than r0, you can override "result".) 4567 * 4568 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4569 * vCC (r1). Useful for integer division and modulus. 4570 * 4571 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4572 * xor-long, add-double, sub-double, mul-double, div-double, 4573 * rem-double 4574 * 4575 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4576 */ 4577 /* binop vAA, vBB, vCC */ 4578 FETCH(r0, 1) @ r0<- CCBB 4579 mov r9, rINST, lsr #8 @ r9<- AA 4580 and r2, r0, #255 @ r2<- BB 4581 mov r3, r0, lsr #8 @ r3<- CC 4582 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4583 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4584 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4585 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4586 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4587 .if 1 4588 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4589 beq common_errDivideByZero 4590 .endif 4591 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4592 4593 @ optional op; may set condition codes 4594 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4595 GET_INST_OPCODE(ip) @ extract opcode from rINST 4596 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 4597 GOTO_OPCODE(ip) @ jump to next instruction 4598 /* 14-17 instructions */ 4599 4600 4601 /* ------------------------------ */ 4602 .balign 64 4603 .L_OP_AND_LONG: /* 0xa0 */ 4604 /* File: armv5te/OP_AND_LONG.S */ 4605 /* File: armv5te/binopWide.S */ 4606 /* 4607 * Generic 64-bit binary operation. Provide an "instr" line that 4608 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4609 * This could be an ARM instruction or a function call. (If the result 4610 * comes back in a register other than r0, you can override "result".) 4611 * 4612 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4613 * vCC (r1). Useful for integer division and modulus. 4614 * 4615 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4616 * xor-long, add-double, sub-double, mul-double, div-double, 4617 * rem-double 4618 * 4619 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4620 */ 4621 /* binop vAA, vBB, vCC */ 4622 FETCH(r0, 1) @ r0<- CCBB 4623 mov r9, rINST, lsr #8 @ r9<- AA 4624 and r2, r0, #255 @ r2<- BB 4625 mov r3, r0, lsr #8 @ r3<- CC 4626 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4627 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4628 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4629 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4630 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4631 .if 0 4632 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4633 beq common_errDivideByZero 4634 .endif 4635 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4636 4637 and r0, r0, r2 @ optional op; may set condition codes 4638 and r1, r1, r3 @ result<- op, r0-r3 changed 4639 GET_INST_OPCODE(ip) @ extract opcode from rINST 4640 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4641 GOTO_OPCODE(ip) @ jump to next instruction 4642 /* 14-17 instructions */ 4643 4644 4645 /* ------------------------------ */ 4646 .balign 64 4647 .L_OP_OR_LONG: /* 0xa1 */ 4648 /* File: armv5te/OP_OR_LONG.S */ 4649 /* File: armv5te/binopWide.S */ 4650 /* 4651 * Generic 64-bit binary operation. Provide an "instr" line that 4652 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4653 * This could be an ARM instruction or a function call. (If the result 4654 * comes back in a register other than r0, you can override "result".) 4655 * 4656 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4657 * vCC (r1). Useful for integer division and modulus. 4658 * 4659 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4660 * xor-long, add-double, sub-double, mul-double, div-double, 4661 * rem-double 4662 * 4663 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4664 */ 4665 /* binop vAA, vBB, vCC */ 4666 FETCH(r0, 1) @ r0<- CCBB 4667 mov r9, rINST, lsr #8 @ r9<- AA 4668 and r2, r0, #255 @ r2<- BB 4669 mov r3, r0, lsr #8 @ r3<- CC 4670 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4671 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4672 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4673 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4674 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4675 .if 0 4676 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4677 beq common_errDivideByZero 4678 .endif 4679 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4680 4681 orr r0, r0, r2 @ optional op; may set condition codes 4682 orr r1, r1, r3 @ result<- op, r0-r3 changed 4683 GET_INST_OPCODE(ip) @ extract opcode from rINST 4684 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4685 GOTO_OPCODE(ip) @ jump to next instruction 4686 /* 14-17 instructions */ 4687 4688 4689 /* ------------------------------ */ 4690 .balign 64 4691 .L_OP_XOR_LONG: /* 0xa2 */ 4692 /* File: armv5te/OP_XOR_LONG.S */ 4693 /* File: armv5te/binopWide.S */ 4694 /* 4695 * Generic 64-bit binary operation. Provide an "instr" line that 4696 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4697 * This could be an ARM instruction or a function call. (If the result 4698 * comes back in a register other than r0, you can override "result".) 4699 * 4700 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4701 * vCC (r1). Useful for integer division and modulus. 4702 * 4703 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4704 * xor-long, add-double, sub-double, mul-double, div-double, 4705 * rem-double 4706 * 4707 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4708 */ 4709 /* binop vAA, vBB, vCC */ 4710 FETCH(r0, 1) @ r0<- CCBB 4711 mov r9, rINST, lsr #8 @ r9<- AA 4712 and r2, r0, #255 @ r2<- BB 4713 mov r3, r0, lsr #8 @ r3<- CC 4714 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4715 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4716 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4717 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4718 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4719 .if 0 4720 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4721 beq common_errDivideByZero 4722 .endif 4723 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4724 4725 eor r0, r0, r2 @ optional op; may set condition codes 4726 eor r1, r1, r3 @ result<- op, r0-r3 changed 4727 GET_INST_OPCODE(ip) @ extract opcode from rINST 4728 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4729 GOTO_OPCODE(ip) @ jump to next instruction 4730 /* 14-17 instructions */ 4731 4732 4733 /* ------------------------------ */ 4734 .balign 64 4735 .L_OP_SHL_LONG: /* 0xa3 */ 4736 /* File: armv5te/OP_SHL_LONG.S */ 4737 /* 4738 * Long integer shift. This is different from the generic 32/64-bit 4739 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4740 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4741 * 6 bits of the shift distance. 4742 */ 4743 /* shl-long vAA, vBB, vCC */ 4744 FETCH(r0, 1) @ r0<- CCBB 4745 mov r9, rINST, lsr #8 @ r9<- AA 4746 and r3, r0, #255 @ r3<- BB 4747 mov r0, r0, lsr #8 @ r0<- CC 4748 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4749 GET_VREG(r2, r0) @ r2<- vCC 4750 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4751 and r2, r2, #63 @ r2<- r2 & 0x3f 4752 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4753 4754 mov r1, r1, asl r2 @ r1<- r1 << r2 4755 rsb r3, r2, #32 @ r3<- 32 - r2 4756 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 4757 subs ip, r2, #32 @ ip<- r2 - 32 4758 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 4759 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4760 b .LOP_SHL_LONG_finish 4761 4762 /* ------------------------------ */ 4763 .balign 64 4764 .L_OP_SHR_LONG: /* 0xa4 */ 4765 /* File: armv5te/OP_SHR_LONG.S */ 4766 /* 4767 * Long integer shift. This is different from the generic 32/64-bit 4768 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4769 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4770 * 6 bits of the shift distance. 4771 */ 4772 /* shr-long vAA, vBB, vCC */ 4773 FETCH(r0, 1) @ r0<- CCBB 4774 mov r9, rINST, lsr #8 @ r9<- AA 4775 and r3, r0, #255 @ r3<- BB 4776 mov r0, r0, lsr #8 @ r0<- CC 4777 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4778 GET_VREG(r2, r0) @ r2<- vCC 4779 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4780 and r2, r2, #63 @ r0<- r0 & 0x3f 4781 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4782 4783 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4784 rsb r3, r2, #32 @ r3<- 32 - r2 4785 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4786 subs ip, r2, #32 @ ip<- r2 - 32 4787 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 4788 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4789 b .LOP_SHR_LONG_finish 4790 4791 /* ------------------------------ */ 4792 .balign 64 4793 .L_OP_USHR_LONG: /* 0xa5 */ 4794 /* File: armv5te/OP_USHR_LONG.S */ 4795 /* 4796 * Long integer shift. This is different from the generic 32/64-bit 4797 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4798 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4799 * 6 bits of the shift distance. 4800 */ 4801 /* ushr-long vAA, vBB, vCC */ 4802 FETCH(r0, 1) @ r0<- CCBB 4803 mov r9, rINST, lsr #8 @ r9<- AA 4804 and r3, r0, #255 @ r3<- BB 4805 mov r0, r0, lsr #8 @ r0<- CC 4806 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4807 GET_VREG(r2, r0) @ r2<- vCC 4808 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4809 and r2, r2, #63 @ r0<- r0 & 0x3f 4810 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4811 4812 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4813 rsb r3, r2, #32 @ r3<- 32 - r2 4814 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4815 subs ip, r2, #32 @ ip<- r2 - 32 4816 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 4817 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4818 b .LOP_USHR_LONG_finish 4819 4820 /* ------------------------------ */ 4821 .balign 64 4822 .L_OP_ADD_FLOAT: /* 0xa6 */ 4823 /* File: arm-vfp/OP_ADD_FLOAT.S */ 4824 /* File: arm-vfp/fbinop.S */ 4825 /* 4826 * Generic 32-bit floating-point operation. Provide an "instr" line that 4827 * specifies an instruction that performs "s2 = s0 op s1". Because we 4828 * use the "softfp" ABI, this must be an instruction, not a function call. 4829 * 4830 * For: add-float, sub-float, mul-float, div-float 4831 */ 4832 /* floatop vAA, vBB, vCC */ 4833 FETCH(r0, 1) @ r0<- CCBB 4834 mov r9, rINST, lsr #8 @ r9<- AA 4835 mov r3, r0, lsr #8 @ r3<- CC 4836 and r2, r0, #255 @ r2<- BB 4837 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4838 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4839 flds s1, [r3] @ s1<- vCC 4840 flds s0, [r2] @ s0<- vBB 4841 4842 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4843 fadds s2, s0, s1 @ s2<- op 4844 GET_INST_OPCODE(ip) @ extract opcode from rINST 4845 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4846 fsts s2, [r9] @ vAA<- s2 4847 GOTO_OPCODE(ip) @ jump to next instruction 4848 4849 4850 /* ------------------------------ */ 4851 .balign 64 4852 .L_OP_SUB_FLOAT: /* 0xa7 */ 4853 /* File: arm-vfp/OP_SUB_FLOAT.S */ 4854 /* File: arm-vfp/fbinop.S */ 4855 /* 4856 * Generic 32-bit floating-point operation. Provide an "instr" line that 4857 * specifies an instruction that performs "s2 = s0 op s1". Because we 4858 * use the "softfp" ABI, this must be an instruction, not a function call. 4859 * 4860 * For: add-float, sub-float, mul-float, div-float 4861 */ 4862 /* floatop vAA, vBB, vCC */ 4863 FETCH(r0, 1) @ r0<- CCBB 4864 mov r9, rINST, lsr #8 @ r9<- AA 4865 mov r3, r0, lsr #8 @ r3<- CC 4866 and r2, r0, #255 @ r2<- BB 4867 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4868 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4869 flds s1, [r3] @ s1<- vCC 4870 flds s0, [r2] @ s0<- vBB 4871 4872 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4873 fsubs s2, s0, s1 @ s2<- op 4874 GET_INST_OPCODE(ip) @ extract opcode from rINST 4875 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4876 fsts s2, [r9] @ vAA<- s2 4877 GOTO_OPCODE(ip) @ jump to next instruction 4878 4879 4880 /* ------------------------------ */ 4881 .balign 64 4882 .L_OP_MUL_FLOAT: /* 0xa8 */ 4883 /* File: arm-vfp/OP_MUL_FLOAT.S */ 4884 /* File: arm-vfp/fbinop.S */ 4885 /* 4886 * Generic 32-bit floating-point operation. Provide an "instr" line that 4887 * specifies an instruction that performs "s2 = s0 op s1". Because we 4888 * use the "softfp" ABI, this must be an instruction, not a function call. 4889 * 4890 * For: add-float, sub-float, mul-float, div-float 4891 */ 4892 /* floatop vAA, vBB, vCC */ 4893 FETCH(r0, 1) @ r0<- CCBB 4894 mov r9, rINST, lsr #8 @ r9<- AA 4895 mov r3, r0, lsr #8 @ r3<- CC 4896 and r2, r0, #255 @ r2<- BB 4897 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4898 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4899 flds s1, [r3] @ s1<- vCC 4900 flds s0, [r2] @ s0<- vBB 4901 4902 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4903 fmuls s2, s0, s1 @ s2<- op 4904 GET_INST_OPCODE(ip) @ extract opcode from rINST 4905 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4906 fsts s2, [r9] @ vAA<- s2 4907 GOTO_OPCODE(ip) @ jump to next instruction 4908 4909 4910 /* ------------------------------ */ 4911 .balign 64 4912 .L_OP_DIV_FLOAT: /* 0xa9 */ 4913 /* File: arm-vfp/OP_DIV_FLOAT.S */ 4914 /* File: arm-vfp/fbinop.S */ 4915 /* 4916 * Generic 32-bit floating-point operation. Provide an "instr" line that 4917 * specifies an instruction that performs "s2 = s0 op s1". Because we 4918 * use the "softfp" ABI, this must be an instruction, not a function call. 4919 * 4920 * For: add-float, sub-float, mul-float, div-float 4921 */ 4922 /* floatop vAA, vBB, vCC */ 4923 FETCH(r0, 1) @ r0<- CCBB 4924 mov r9, rINST, lsr #8 @ r9<- AA 4925 mov r3, r0, lsr #8 @ r3<- CC 4926 and r2, r0, #255 @ r2<- BB 4927 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4928 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4929 flds s1, [r3] @ s1<- vCC 4930 flds s0, [r2] @ s0<- vBB 4931 4932 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4933 fdivs s2, s0, s1 @ s2<- op 4934 GET_INST_OPCODE(ip) @ extract opcode from rINST 4935 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4936 fsts s2, [r9] @ vAA<- s2 4937 GOTO_OPCODE(ip) @ jump to next instruction 4938 4939 4940 /* ------------------------------ */ 4941 .balign 64 4942 .L_OP_REM_FLOAT: /* 0xaa */ 4943 /* File: armv5te/OP_REM_FLOAT.S */ 4944 /* EABI doesn't define a float remainder function, but libm does */ 4945 /* File: armv5te/binop.S */ 4946 /* 4947 * Generic 32-bit binary operation. Provide an "instr" line that 4948 * specifies an instruction that performs "result = r0 op r1". 4949 * This could be an ARM instruction or a function call. (If the result 4950 * comes back in a register other than r0, you can override "result".) 4951 * 4952 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4953 * vCC (r1). Useful for integer division and modulus. Note that we 4954 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4955 * handles it correctly. 4956 * 4957 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4958 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4959 * mul-float, div-float, rem-float 4960 */ 4961 /* binop vAA, vBB, vCC */ 4962 FETCH(r0, 1) @ r0<- CCBB 4963 mov r9, rINST, lsr #8 @ r9<- AA 4964 mov r3, r0, lsr #8 @ r3<- CC 4965 and r2, r0, #255 @ r2<- BB 4966 GET_VREG(r1, r3) @ r1<- vCC 4967 GET_VREG(r0, r2) @ r0<- vBB 4968 .if 0 4969 cmp r1, #0 @ is second operand zero? 4970 beq common_errDivideByZero 4971 .endif 4972 4973 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4974 @ optional op; may set condition codes 4975 bl fmodf @ r0<- op, r0-r3 changed 4976 GET_INST_OPCODE(ip) @ extract opcode from rINST 4977 SET_VREG(r0, r9) @ vAA<- r0 4978 GOTO_OPCODE(ip) @ jump to next instruction 4979 /* 11-14 instructions */ 4980 4981 4982 /* ------------------------------ */ 4983 .balign 64 4984 .L_OP_ADD_DOUBLE: /* 0xab */ 4985 /* File: arm-vfp/OP_ADD_DOUBLE.S */ 4986 /* File: arm-vfp/fbinopWide.S */ 4987 /* 4988 * Generic 64-bit double-precision floating point binary operation. 4989 * Provide an "instr" line that specifies an instruction that performs 4990 * "d2 = d0 op d1". 4991 * 4992 * for: add-double, sub-double, mul-double, div-double 4993 */ 4994 /* doubleop vAA, vBB, vCC */ 4995 FETCH(r0, 1) @ r0<- CCBB 4996 mov r9, rINST, lsr #8 @ r9<- AA 4997 mov r3, r0, lsr #8 @ r3<- CC 4998 and r2, r0, #255 @ r2<- BB 4999 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5000 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5001 fldd d1, [r3] @ d1<- vCC 5002 fldd d0, [r2] @ d0<- vBB 5003 5004 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5005 faddd d2, d0, d1 @ s2<- op 5006 GET_INST_OPCODE(ip) @ extract opcode from rINST 5007 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5008 fstd d2, [r9] @ vAA<- d2 5009 GOTO_OPCODE(ip) @ jump to next instruction 5010 5011 5012 /* ------------------------------ */ 5013 .balign 64 5014 .L_OP_SUB_DOUBLE: /* 0xac */ 5015 /* File: arm-vfp/OP_SUB_DOUBLE.S */ 5016 /* File: arm-vfp/fbinopWide.S */ 5017 /* 5018 * Generic 64-bit double-precision floating point binary operation. 5019 * Provide an "instr" line that specifies an instruction that performs 5020 * "d2 = d0 op d1". 5021 * 5022 * for: add-double, sub-double, mul-double, div-double 5023 */ 5024 /* doubleop vAA, vBB, vCC */ 5025 FETCH(r0, 1) @ r0<- CCBB 5026 mov r9, rINST, lsr #8 @ r9<- AA 5027 mov r3, r0, lsr #8 @ r3<- CC 5028 and r2, r0, #255 @ r2<- BB 5029 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5030 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5031 fldd d1, [r3] @ d1<- vCC 5032 fldd d0, [r2] @ d0<- vBB 5033 5034 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5035 fsubd d2, d0, d1 @ s2<- op 5036 GET_INST_OPCODE(ip) @ extract opcode from rINST 5037 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5038 fstd d2, [r9] @ vAA<- d2 5039 GOTO_OPCODE(ip) @ jump to next instruction 5040 5041 5042 /* ------------------------------ */ 5043 .balign 64 5044 .L_OP_MUL_DOUBLE: /* 0xad */ 5045 /* File: arm-vfp/OP_MUL_DOUBLE.S */ 5046 /* File: arm-vfp/fbinopWide.S */ 5047 /* 5048 * Generic 64-bit double-precision floating point binary operation. 5049 * Provide an "instr" line that specifies an instruction that performs 5050 * "d2 = d0 op d1". 5051 * 5052 * for: add-double, sub-double, mul-double, div-double 5053 */ 5054 /* doubleop vAA, vBB, vCC */ 5055 FETCH(r0, 1) @ r0<- CCBB 5056 mov r9, rINST, lsr #8 @ r9<- AA 5057 mov r3, r0, lsr #8 @ r3<- CC 5058 and r2, r0, #255 @ r2<- BB 5059 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5060 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5061 fldd d1, [r3] @ d1<- vCC 5062 fldd d0, [r2] @ d0<- vBB 5063 5064 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5065 fmuld d2, d0, d1 @ s2<- op 5066 GET_INST_OPCODE(ip) @ extract opcode from rINST 5067 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5068 fstd d2, [r9] @ vAA<- d2 5069 GOTO_OPCODE(ip) @ jump to next instruction 5070 5071 5072 /* ------------------------------ */ 5073 .balign 64 5074 .L_OP_DIV_DOUBLE: /* 0xae */ 5075 /* File: arm-vfp/OP_DIV_DOUBLE.S */ 5076 /* File: arm-vfp/fbinopWide.S */ 5077 /* 5078 * Generic 64-bit double-precision floating point binary operation. 5079 * Provide an "instr" line that specifies an instruction that performs 5080 * "d2 = d0 op d1". 5081 * 5082 * for: add-double, sub-double, mul-double, div-double 5083 */ 5084 /* doubleop vAA, vBB, vCC */ 5085 FETCH(r0, 1) @ r0<- CCBB 5086 mov r9, rINST, lsr #8 @ r9<- AA 5087 mov r3, r0, lsr #8 @ r3<- CC 5088 and r2, r0, #255 @ r2<- BB 5089 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5090 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5091 fldd d1, [r3] @ d1<- vCC 5092 fldd d0, [r2] @ d0<- vBB 5093 5094 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5095 fdivd d2, d0, d1 @ s2<- op 5096 GET_INST_OPCODE(ip) @ extract opcode from rINST 5097 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5098 fstd d2, [r9] @ vAA<- d2 5099 GOTO_OPCODE(ip) @ jump to next instruction 5100 5101 5102 /* ------------------------------ */ 5103 .balign 64 5104 .L_OP_REM_DOUBLE: /* 0xaf */ 5105 /* File: armv5te/OP_REM_DOUBLE.S */ 5106 /* EABI doesn't define a double remainder function, but libm does */ 5107 /* File: armv5te/binopWide.S */ 5108 /* 5109 * Generic 64-bit binary operation. Provide an "instr" line that 5110 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5111 * This could be an ARM instruction or a function call. (If the result 5112 * comes back in a register other than r0, you can override "result".) 5113 * 5114 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5115 * vCC (r1). Useful for integer division and modulus. 5116 * 5117 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5118 * xor-long, add-double, sub-double, mul-double, div-double, 5119 * rem-double 5120 * 5121 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5122 */ 5123 /* binop vAA, vBB, vCC */ 5124 FETCH(r0, 1) @ r0<- CCBB 5125 mov r9, rINST, lsr #8 @ r9<- AA 5126 and r2, r0, #255 @ r2<- BB 5127 mov r3, r0, lsr #8 @ r3<- CC 5128 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5129 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5130 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5131 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5132 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5133 .if 0 5134 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5135 beq common_errDivideByZero 5136 .endif 5137 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5138 5139 @ optional op; may set condition codes 5140 bl fmod @ result<- op, r0-r3 changed 5141 GET_INST_OPCODE(ip) @ extract opcode from rINST 5142 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5143 GOTO_OPCODE(ip) @ jump to next instruction 5144 /* 14-17 instructions */ 5145 5146 5147 /* ------------------------------ */ 5148 .balign 64 5149 .L_OP_ADD_INT_2ADDR: /* 0xb0 */ 5150 /* File: armv6t2/OP_ADD_INT_2ADDR.S */ 5151 /* File: armv6t2/binop2addr.S */ 5152 /* 5153 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5154 * that specifies an instruction that performs "result = r0 op r1". 5155 * This could be an ARM instruction or a function call. (If the result 5156 * comes back in a register other than r0, you can override "result".) 5157 * 5158 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5159 * vCC (r1). Useful for integer division and modulus. 5160 * 5161 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5162 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5163 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5164 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5165 */ 5166 /* binop/2addr vA, vB */ 5167 mov r3, rINST, lsr #12 @ r3<- B 5168 ubfx r9, rINST, #8, #4 @ r9<- A 5169 GET_VREG(r1, r3) @ r1<- vB 5170 GET_VREG(r0, r9) @ r0<- vA 5171 .if 0 5172 cmp r1, #0 @ is second operand zero? 5173 beq common_errDivideByZero 5174 .endif 5175 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5176 5177 @ optional op; may set condition codes 5178 add r0, r0, r1 @ r0<- op, r0-r3 changed 5179 GET_INST_OPCODE(ip) @ extract opcode from rINST 5180 SET_VREG(r0, r9) @ vAA<- r0 5181 GOTO_OPCODE(ip) @ jump to next instruction 5182 /* 10-13 instructions */ 5183 5184 5185 /* ------------------------------ */ 5186 .balign 64 5187 .L_OP_SUB_INT_2ADDR: /* 0xb1 */ 5188 /* File: armv6t2/OP_SUB_INT_2ADDR.S */ 5189 /* File: armv6t2/binop2addr.S */ 5190 /* 5191 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5192 * that specifies an instruction that performs "result = r0 op r1". 5193 * This could be an ARM instruction or a function call. (If the result 5194 * comes back in a register other than r0, you can override "result".) 5195 * 5196 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5197 * vCC (r1). Useful for integer division and modulus. 5198 * 5199 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5200 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5201 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5202 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5203 */ 5204 /* binop/2addr vA, vB */ 5205 mov r3, rINST, lsr #12 @ r3<- B 5206 ubfx r9, rINST, #8, #4 @ r9<- A 5207 GET_VREG(r1, r3) @ r1<- vB 5208 GET_VREG(r0, r9) @ r0<- vA 5209 .if 0 5210 cmp r1, #0 @ is second operand zero? 5211 beq common_errDivideByZero 5212 .endif 5213 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5214 5215 @ optional op; may set condition codes 5216 sub r0, r0, r1 @ r0<- op, r0-r3 changed 5217 GET_INST_OPCODE(ip) @ extract opcode from rINST 5218 SET_VREG(r0, r9) @ vAA<- r0 5219 GOTO_OPCODE(ip) @ jump to next instruction 5220 /* 10-13 instructions */ 5221 5222 5223 /* ------------------------------ */ 5224 .balign 64 5225 .L_OP_MUL_INT_2ADDR: /* 0xb2 */ 5226 /* File: armv6t2/OP_MUL_INT_2ADDR.S */ 5227 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 5228 /* File: armv6t2/binop2addr.S */ 5229 /* 5230 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5231 * that specifies an instruction that performs "result = r0 op r1". 5232 * This could be an ARM instruction or a function call. (If the result 5233 * comes back in a register other than r0, you can override "result".) 5234 * 5235 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5236 * vCC (r1). Useful for integer division and modulus. 5237 * 5238 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5239 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5240 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5241 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5242 */ 5243 /* binop/2addr vA, vB */ 5244 mov r3, rINST, lsr #12 @ r3<- B 5245 ubfx r9, rINST, #8, #4 @ r9<- A 5246 GET_VREG(r1, r3) @ r1<- vB 5247 GET_VREG(r0, r9) @ r0<- vA 5248 .if 0 5249 cmp r1, #0 @ is second operand zero? 5250 beq common_errDivideByZero 5251 .endif 5252 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5253 5254 @ optional op; may set condition codes 5255 mul r0, r1, r0 @ r0<- op, r0-r3 changed 5256 GET_INST_OPCODE(ip) @ extract opcode from rINST 5257 SET_VREG(r0, r9) @ vAA<- r0 5258 GOTO_OPCODE(ip) @ jump to next instruction 5259 /* 10-13 instructions */ 5260 5261 5262 /* ------------------------------ */ 5263 .balign 64 5264 .L_OP_DIV_INT_2ADDR: /* 0xb3 */ 5265 /* File: armv6t2/OP_DIV_INT_2ADDR.S */ 5266 /* File: armv6t2/binop2addr.S */ 5267 /* 5268 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5269 * that specifies an instruction that performs "result = r0 op r1". 5270 * This could be an ARM instruction or a function call. (If the result 5271 * comes back in a register other than r0, you can override "result".) 5272 * 5273 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5274 * vCC (r1). Useful for integer division and modulus. 5275 * 5276 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5277 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5278 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5279 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5280 */ 5281 /* binop/2addr vA, vB */ 5282 mov r3, rINST, lsr #12 @ r3<- B 5283 ubfx r9, rINST, #8, #4 @ r9<- A 5284 GET_VREG(r1, r3) @ r1<- vB 5285 GET_VREG(r0, r9) @ r0<- vA 5286 .if 1 5287 cmp r1, #0 @ is second operand zero? 5288 beq common_errDivideByZero 5289 .endif 5290 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5291 5292 @ optional op; may set condition codes 5293 bl __aeabi_idiv @ r0<- op, r0-r3 changed 5294 GET_INST_OPCODE(ip) @ extract opcode from rINST 5295 SET_VREG(r0, r9) @ vAA<- r0 5296 GOTO_OPCODE(ip) @ jump to next instruction 5297 /* 10-13 instructions */ 5298 5299 5300 /* ------------------------------ */ 5301 .balign 64 5302 .L_OP_REM_INT_2ADDR: /* 0xb4 */ 5303 /* File: armv6t2/OP_REM_INT_2ADDR.S */ 5304 /* idivmod returns quotient in r0 and remainder in r1 */ 5305 /* File: armv6t2/binop2addr.S */ 5306 /* 5307 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5308 * that specifies an instruction that performs "result = r0 op r1". 5309 * This could be an ARM instruction or a function call. (If the result 5310 * comes back in a register other than r0, you can override "result".) 5311 * 5312 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5313 * vCC (r1). Useful for integer division and modulus. 5314 * 5315 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5316 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5317 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5318 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5319 */ 5320 /* binop/2addr vA, vB */ 5321 mov r3, rINST, lsr #12 @ r3<- B 5322 ubfx r9, rINST, #8, #4 @ r9<- A 5323 GET_VREG(r1, r3) @ r1<- vB 5324 GET_VREG(r0, r9) @ r0<- vA 5325 .if 1 5326 cmp r1, #0 @ is second operand zero? 5327 beq common_errDivideByZero 5328 .endif 5329 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5330 5331 @ optional op; may set condition codes 5332 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 5333 GET_INST_OPCODE(ip) @ extract opcode from rINST 5334 SET_VREG(r1, r9) @ vAA<- r1 5335 GOTO_OPCODE(ip) @ jump to next instruction 5336 /* 10-13 instructions */ 5337 5338 5339 /* ------------------------------ */ 5340 .balign 64 5341 .L_OP_AND_INT_2ADDR: /* 0xb5 */ 5342 /* File: armv6t2/OP_AND_INT_2ADDR.S */ 5343 /* File: armv6t2/binop2addr.S */ 5344 /* 5345 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5346 * that specifies an instruction that performs "result = r0 op r1". 5347 * This could be an ARM instruction or a function call. (If the result 5348 * comes back in a register other than r0, you can override "result".) 5349 * 5350 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5351 * vCC (r1). Useful for integer division and modulus. 5352 * 5353 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5354 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5355 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5356 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5357 */ 5358 /* binop/2addr vA, vB */ 5359 mov r3, rINST, lsr #12 @ r3<- B 5360 ubfx r9, rINST, #8, #4 @ r9<- A 5361 GET_VREG(r1, r3) @ r1<- vB 5362 GET_VREG(r0, r9) @ r0<- vA 5363 .if 0 5364 cmp r1, #0 @ is second operand zero? 5365 beq common_errDivideByZero 5366 .endif 5367 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5368 5369 @ optional op; may set condition codes 5370 and r0, r0, r1 @ r0<- op, r0-r3 changed 5371 GET_INST_OPCODE(ip) @ extract opcode from rINST 5372 SET_VREG(r0, r9) @ vAA<- r0 5373 GOTO_OPCODE(ip) @ jump to next instruction 5374 /* 10-13 instructions */ 5375 5376 5377 /* ------------------------------ */ 5378 .balign 64 5379 .L_OP_OR_INT_2ADDR: /* 0xb6 */ 5380 /* File: armv6t2/OP_OR_INT_2ADDR.S */ 5381 /* File: armv6t2/binop2addr.S */ 5382 /* 5383 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5384 * that specifies an instruction that performs "result = r0 op r1". 5385 * This could be an ARM instruction or a function call. (If the result 5386 * comes back in a register other than r0, you can override "result".) 5387 * 5388 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5389 * vCC (r1). Useful for integer division and modulus. 5390 * 5391 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5392 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5393 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5394 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5395 */ 5396 /* binop/2addr vA, vB */ 5397 mov r3, rINST, lsr #12 @ r3<- B 5398 ubfx r9, rINST, #8, #4 @ r9<- A 5399 GET_VREG(r1, r3) @ r1<- vB 5400 GET_VREG(r0, r9) @ r0<- vA 5401 .if 0 5402 cmp r1, #0 @ is second operand zero? 5403 beq common_errDivideByZero 5404 .endif 5405 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5406 5407 @ optional op; may set condition codes 5408 orr r0, r0, r1 @ r0<- op, r0-r3 changed 5409 GET_INST_OPCODE(ip) @ extract opcode from rINST 5410 SET_VREG(r0, r9) @ vAA<- r0 5411 GOTO_OPCODE(ip) @ jump to next instruction 5412 /* 10-13 instructions */ 5413 5414 5415 /* ------------------------------ */ 5416 .balign 64 5417 .L_OP_XOR_INT_2ADDR: /* 0xb7 */ 5418 /* File: armv6t2/OP_XOR_INT_2ADDR.S */ 5419 /* File: armv6t2/binop2addr.S */ 5420 /* 5421 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5422 * that specifies an instruction that performs "result = r0 op r1". 5423 * This could be an ARM instruction or a function call. (If the result 5424 * comes back in a register other than r0, you can override "result".) 5425 * 5426 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5427 * vCC (r1). Useful for integer division and modulus. 5428 * 5429 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5430 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5431 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5432 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5433 */ 5434 /* binop/2addr vA, vB */ 5435 mov r3, rINST, lsr #12 @ r3<- B 5436 ubfx r9, rINST, #8, #4 @ r9<- A 5437 GET_VREG(r1, r3) @ r1<- vB 5438 GET_VREG(r0, r9) @ r0<- vA 5439 .if 0 5440 cmp r1, #0 @ is second operand zero? 5441 beq common_errDivideByZero 5442 .endif 5443 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5444 5445 @ optional op; may set condition codes 5446 eor r0, r0, r1 @ r0<- op, r0-r3 changed 5447 GET_INST_OPCODE(ip) @ extract opcode from rINST 5448 SET_VREG(r0, r9) @ vAA<- r0 5449 GOTO_OPCODE(ip) @ jump to next instruction 5450 /* 10-13 instructions */ 5451 5452 5453 /* ------------------------------ */ 5454 .balign 64 5455 .L_OP_SHL_INT_2ADDR: /* 0xb8 */ 5456 /* File: armv6t2/OP_SHL_INT_2ADDR.S */ 5457 /* File: armv6t2/binop2addr.S */ 5458 /* 5459 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5460 * that specifies an instruction that performs "result = r0 op r1". 5461 * This could be an ARM instruction or a function call. (If the result 5462 * comes back in a register other than r0, you can override "result".) 5463 * 5464 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5465 * vCC (r1). Useful for integer division and modulus. 5466 * 5467 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5468 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5469 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5470 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5471 */ 5472 /* binop/2addr vA, vB */ 5473 mov r3, rINST, lsr #12 @ r3<- B 5474 ubfx r9, rINST, #8, #4 @ r9<- A 5475 GET_VREG(r1, r3) @ r1<- vB 5476 GET_VREG(r0, r9) @ r0<- vA 5477 .if 0 5478 cmp r1, #0 @ is second operand zero? 5479 beq common_errDivideByZero 5480 .endif 5481 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5482 5483 and r1, r1, #31 @ optional op; may set condition codes 5484 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 5485 GET_INST_OPCODE(ip) @ extract opcode from rINST 5486 SET_VREG(r0, r9) @ vAA<- r0 5487 GOTO_OPCODE(ip) @ jump to next instruction 5488 /* 10-13 instructions */ 5489 5490 5491 /* ------------------------------ */ 5492 .balign 64 5493 .L_OP_SHR_INT_2ADDR: /* 0xb9 */ 5494 /* File: armv6t2/OP_SHR_INT_2ADDR.S */ 5495 /* File: armv6t2/binop2addr.S */ 5496 /* 5497 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5498 * that specifies an instruction that performs "result = r0 op r1". 5499 * This could be an ARM instruction or a function call. (If the result 5500 * comes back in a register other than r0, you can override "result".) 5501 * 5502 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5503 * vCC (r1). Useful for integer division and modulus. 5504 * 5505 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5506 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5507 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5508 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5509 */ 5510 /* binop/2addr vA, vB */ 5511 mov r3, rINST, lsr #12 @ r3<- B 5512 ubfx r9, rINST, #8, #4 @ r9<- A 5513 GET_VREG(r1, r3) @ r1<- vB 5514 GET_VREG(r0, r9) @ r0<- vA 5515 .if 0 5516 cmp r1, #0 @ is second operand zero? 5517 beq common_errDivideByZero 5518 .endif 5519 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5520 5521 and r1, r1, #31 @ optional op; may set condition codes 5522 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 5523 GET_INST_OPCODE(ip) @ extract opcode from rINST 5524 SET_VREG(r0, r9) @ vAA<- r0 5525 GOTO_OPCODE(ip) @ jump to next instruction 5526 /* 10-13 instructions */ 5527 5528 5529 /* ------------------------------ */ 5530 .balign 64 5531 .L_OP_USHR_INT_2ADDR: /* 0xba */ 5532 /* File: armv6t2/OP_USHR_INT_2ADDR.S */ 5533 /* File: armv6t2/binop2addr.S */ 5534 /* 5535 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5536 * that specifies an instruction that performs "result = r0 op r1". 5537 * This could be an ARM instruction or a function call. (If the result 5538 * comes back in a register other than r0, you can override "result".) 5539 * 5540 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5541 * vCC (r1). Useful for integer division and modulus. 5542 * 5543 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5544 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5545 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5546 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5547 */ 5548 /* binop/2addr vA, vB */ 5549 mov r3, rINST, lsr #12 @ r3<- B 5550 ubfx r9, rINST, #8, #4 @ r9<- A 5551 GET_VREG(r1, r3) @ r1<- vB 5552 GET_VREG(r0, r9) @ r0<- vA 5553 .if 0 5554 cmp r1, #0 @ is second operand zero? 5555 beq common_errDivideByZero 5556 .endif 5557 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5558 5559 and r1, r1, #31 @ optional op; may set condition codes 5560 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 5561 GET_INST_OPCODE(ip) @ extract opcode from rINST 5562 SET_VREG(r0, r9) @ vAA<- r0 5563 GOTO_OPCODE(ip) @ jump to next instruction 5564 /* 10-13 instructions */ 5565 5566 5567 /* ------------------------------ */ 5568 .balign 64 5569 .L_OP_ADD_LONG_2ADDR: /* 0xbb */ 5570 /* File: armv6t2/OP_ADD_LONG_2ADDR.S */ 5571 /* File: armv6t2/binopWide2addr.S */ 5572 /* 5573 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5574 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5575 * This could be an ARM instruction or a function call. (If the result 5576 * comes back in a register other than r0, you can override "result".) 5577 * 5578 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5579 * vCC (r1). Useful for integer division and modulus. 5580 * 5581 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5582 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5583 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5584 * rem-double/2addr 5585 */ 5586 /* binop/2addr vA, vB */ 5587 mov r1, rINST, lsr #12 @ r1<- B 5588 ubfx r9, rINST, #8, #4 @ r9<- A 5589 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5590 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5591 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5592 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5593 .if 0 5594 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5595 beq common_errDivideByZero 5596 .endif 5597 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5598 5599 adds r0, r0, r2 @ optional op; may set condition codes 5600 adc r1, r1, r3 @ result<- op, r0-r3 changed 5601 GET_INST_OPCODE(ip) @ extract opcode from rINST 5602 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5603 GOTO_OPCODE(ip) @ jump to next instruction 5604 /* 12-15 instructions */ 5605 5606 5607 /* ------------------------------ */ 5608 .balign 64 5609 .L_OP_SUB_LONG_2ADDR: /* 0xbc */ 5610 /* File: armv6t2/OP_SUB_LONG_2ADDR.S */ 5611 /* File: armv6t2/binopWide2addr.S */ 5612 /* 5613 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5614 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5615 * This could be an ARM instruction or a function call. (If the result 5616 * comes back in a register other than r0, you can override "result".) 5617 * 5618 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5619 * vCC (r1). Useful for integer division and modulus. 5620 * 5621 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5622 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5623 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5624 * rem-double/2addr 5625 */ 5626 /* binop/2addr vA, vB */ 5627 mov r1, rINST, lsr #12 @ r1<- B 5628 ubfx r9, rINST, #8, #4 @ r9<- A 5629 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5630 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5631 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5632 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5633 .if 0 5634 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5635 beq common_errDivideByZero 5636 .endif 5637 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5638 5639 subs r0, r0, r2 @ optional op; may set condition codes 5640 sbc r1, r1, r3 @ result<- op, r0-r3 changed 5641 GET_INST_OPCODE(ip) @ extract opcode from rINST 5642 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5643 GOTO_OPCODE(ip) @ jump to next instruction 5644 /* 12-15 instructions */ 5645 5646 5647 /* ------------------------------ */ 5648 .balign 64 5649 .L_OP_MUL_LONG_2ADDR: /* 0xbd */ 5650 /* File: armv6t2/OP_MUL_LONG_2ADDR.S */ 5651 /* 5652 * Signed 64-bit integer multiply, "/2addr" version. 5653 * 5654 * See OP_MUL_LONG for an explanation. 5655 * 5656 * We get a little tight on registers, so to avoid looking up &fp[A] 5657 * again we stuff it into rINST. 5658 */ 5659 /* mul-long/2addr vA, vB */ 5660 mov r1, rINST, lsr #12 @ r1<- B 5661 ubfx r9, rINST, #8, #4 @ r9<- A 5662 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5663 add rINST, rFP, r9, lsl #2 @ rINST<- &fp[A] 5664 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5665 ldmia rINST, {r0-r1} @ r0/r1<- vAA/vAA+1 5666 mul ip, r2, r1 @ ip<- ZxW 5667 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 5668 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 5669 mov r0, rINST @ r0<- &fp[A] (free up rINST) 5670 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5671 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 5672 GET_INST_OPCODE(ip) @ extract opcode from rINST 5673 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 5674 GOTO_OPCODE(ip) @ jump to next instruction 5675 5676 /* ------------------------------ */ 5677 .balign 64 5678 .L_OP_DIV_LONG_2ADDR: /* 0xbe */ 5679 /* File: armv6t2/OP_DIV_LONG_2ADDR.S */ 5680 /* File: armv6t2/binopWide2addr.S */ 5681 /* 5682 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5683 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5684 * This could be an ARM instruction or a function call. (If the result 5685 * comes back in a register other than r0, you can override "result".) 5686 * 5687 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5688 * vCC (r1). Useful for integer division and modulus. 5689 * 5690 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5691 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5692 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5693 * rem-double/2addr 5694 */ 5695 /* binop/2addr vA, vB */ 5696 mov r1, rINST, lsr #12 @ r1<- B 5697 ubfx r9, rINST, #8, #4 @ r9<- A 5698 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5699 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5700 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5701 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5702 .if 1 5703 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5704 beq common_errDivideByZero 5705 .endif 5706 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5707 5708 @ optional op; may set condition codes 5709 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5710 GET_INST_OPCODE(ip) @ extract opcode from rINST 5711 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5712 GOTO_OPCODE(ip) @ jump to next instruction 5713 /* 12-15 instructions */ 5714 5715 5716 /* ------------------------------ */ 5717 .balign 64 5718 .L_OP_REM_LONG_2ADDR: /* 0xbf */ 5719 /* File: armv6t2/OP_REM_LONG_2ADDR.S */ 5720 /* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 5721 /* File: armv6t2/binopWide2addr.S */ 5722 /* 5723 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5724 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5725 * This could be an ARM instruction or a function call. (If the result 5726 * comes back in a register other than r0, you can override "result".) 5727 * 5728 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5729 * vCC (r1). Useful for integer division and modulus. 5730 * 5731 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5732 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5733 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5734 * rem-double/2addr 5735 */ 5736 /* binop/2addr vA, vB */ 5737 mov r1, rINST, lsr #12 @ r1<- B 5738 ubfx r9, rINST, #8, #4 @ r9<- A 5739 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5740 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5741 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5742 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5743 .if 1 5744 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5745 beq common_errDivideByZero 5746 .endif 5747 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5748 5749 @ optional op; may set condition codes 5750 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5751 GET_INST_OPCODE(ip) @ extract opcode from rINST 5752 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 5753 GOTO_OPCODE(ip) @ jump to next instruction 5754 /* 12-15 instructions */ 5755 5756 5757 /* ------------------------------ */ 5758 .balign 64 5759 .L_OP_AND_LONG_2ADDR: /* 0xc0 */ 5760 /* File: armv6t2/OP_AND_LONG_2ADDR.S */ 5761 /* File: armv6t2/binopWide2addr.S */ 5762 /* 5763 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5764 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5765 * This could be an ARM instruction or a function call. (If the result 5766 * comes back in a register other than r0, you can override "result".) 5767 * 5768 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5769 * vCC (r1). Useful for integer division and modulus. 5770 * 5771 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5772 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5773 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5774 * rem-double/2addr 5775 */ 5776 /* binop/2addr vA, vB */ 5777 mov r1, rINST, lsr #12 @ r1<- B 5778 ubfx r9, rINST, #8, #4 @ r9<- A 5779 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5780 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5781 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5782 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5783 .if 0 5784 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5785 beq common_errDivideByZero 5786 .endif 5787 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5788 5789 and r0, r0, r2 @ optional op; may set condition codes 5790 and r1, r1, r3 @ result<- op, r0-r3 changed 5791 GET_INST_OPCODE(ip) @ extract opcode from rINST 5792 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5793 GOTO_OPCODE(ip) @ jump to next instruction 5794 /* 12-15 instructions */ 5795 5796 5797 /* ------------------------------ */ 5798 .balign 64 5799 .L_OP_OR_LONG_2ADDR: /* 0xc1 */ 5800 /* File: armv6t2/OP_OR_LONG_2ADDR.S */ 5801 /* File: armv6t2/binopWide2addr.S */ 5802 /* 5803 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5804 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5805 * This could be an ARM instruction or a function call. (If the result 5806 * comes back in a register other than r0, you can override "result".) 5807 * 5808 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5809 * vCC (r1). Useful for integer division and modulus. 5810 * 5811 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5812 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5813 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5814 * rem-double/2addr 5815 */ 5816 /* binop/2addr vA, vB */ 5817 mov r1, rINST, lsr #12 @ r1<- B 5818 ubfx r9, rINST, #8, #4 @ r9<- A 5819 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5820 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5821 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5822 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5823 .if 0 5824 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5825 beq common_errDivideByZero 5826 .endif 5827 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5828 5829 orr r0, r0, r2 @ optional op; may set condition codes 5830 orr r1, r1, r3 @ result<- op, r0-r3 changed 5831 GET_INST_OPCODE(ip) @ extract opcode from rINST 5832 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5833 GOTO_OPCODE(ip) @ jump to next instruction 5834 /* 12-15 instructions */ 5835 5836 5837 /* ------------------------------ */ 5838 .balign 64 5839 .L_OP_XOR_LONG_2ADDR: /* 0xc2 */ 5840 /* File: armv6t2/OP_XOR_LONG_2ADDR.S */ 5841 /* File: armv6t2/binopWide2addr.S */ 5842 /* 5843 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5844 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5845 * This could be an ARM instruction or a function call. (If the result 5846 * comes back in a register other than r0, you can override "result".) 5847 * 5848 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5849 * vCC (r1). Useful for integer division and modulus. 5850 * 5851 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5852 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5853 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5854 * rem-double/2addr 5855 */ 5856 /* binop/2addr vA, vB */ 5857 mov r1, rINST, lsr #12 @ r1<- B 5858 ubfx r9, rINST, #8, #4 @ r9<- A 5859 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5860 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5861 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5862 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5863 .if 0 5864 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5865 beq common_errDivideByZero 5866 .endif 5867 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5868 5869 eor r0, r0, r2 @ optional op; may set condition codes 5870 eor r1, r1, r3 @ result<- op, r0-r3 changed 5871 GET_INST_OPCODE(ip) @ extract opcode from rINST 5872 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5873 GOTO_OPCODE(ip) @ jump to next instruction 5874 /* 12-15 instructions */ 5875 5876 5877 /* ------------------------------ */ 5878 .balign 64 5879 .L_OP_SHL_LONG_2ADDR: /* 0xc3 */ 5880 /* File: armv6t2/OP_SHL_LONG_2ADDR.S */ 5881 /* 5882 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5883 * 32-bit shift distance. 5884 */ 5885 /* shl-long/2addr vA, vB */ 5886 mov r3, rINST, lsr #12 @ r3<- B 5887 ubfx r9, rINST, #8, #4 @ r9<- A 5888 GET_VREG(r2, r3) @ r2<- vB 5889 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5890 and r2, r2, #63 @ r2<- r2 & 0x3f 5891 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5892 5893 mov r1, r1, asl r2 @ r1<- r1 << r2 5894 rsb r3, r2, #32 @ r3<- 32 - r2 5895 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 5896 subs ip, r2, #32 @ ip<- r2 - 32 5897 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5898 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 5899 mov r0, r0, asl r2 @ r0<- r0 << r2 5900 b .LOP_SHL_LONG_2ADDR_finish 5901 5902 /* ------------------------------ */ 5903 .balign 64 5904 .L_OP_SHR_LONG_2ADDR: /* 0xc4 */ 5905 /* File: armv6t2/OP_SHR_LONG_2ADDR.S */ 5906 /* 5907 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5908 * 32-bit shift distance. 5909 */ 5910 /* shr-long/2addr vA, vB */ 5911 mov r3, rINST, lsr #12 @ r3<- B 5912 ubfx r9, rINST, #8, #4 @ r9<- A 5913 GET_VREG(r2, r3) @ r2<- vB 5914 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5915 and r2, r2, #63 @ r2<- r2 & 0x3f 5916 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5917 5918 mov r0, r0, lsr r2 @ r0<- r2 >> r2 5919 rsb r3, r2, #32 @ r3<- 32 - r2 5920 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 5921 subs ip, r2, #32 @ ip<- r2 - 32 5922 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5923 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 5924 mov r1, r1, asr r2 @ r1<- r1 >> r2 5925 b .LOP_SHR_LONG_2ADDR_finish 5926 5927 /* ------------------------------ */ 5928 .balign 64 5929 .L_OP_USHR_LONG_2ADDR: /* 0xc5 */ 5930 /* File: armv6t2/OP_USHR_LONG_2ADDR.S */ 5931 /* 5932 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5933 * 32-bit shift distance. 5934 */ 5935 /* ushr-long/2addr vA, vB */ 5936 mov r3, rINST, lsr #12 @ r3<- B 5937 ubfx r9, rINST, #8, #4 @ r9<- A 5938 GET_VREG(r2, r3) @ r2<- vB 5939 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5940 and r2, r2, #63 @ r2<- r2 & 0x3f 5941 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5942 5943 mov r0, r0, lsr r2 @ r0<- r2 >> r2 5944 rsb r3, r2, #32 @ r3<- 32 - r2 5945 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 5946 subs ip, r2, #32 @ ip<- r2 - 32 5947 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5948 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 5949 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 5950 b .LOP_USHR_LONG_2ADDR_finish 5951 5952 /* ------------------------------ */ 5953 .balign 64 5954 .L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 5955 /* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */ 5956 /* File: arm-vfp/fbinop2addr.S */ 5957 /* 5958 * Generic 32-bit floating point "/2addr" binary operation. Provide 5959 * an "instr" line that specifies an instruction that performs 5960 * "s2 = s0 op s1". 5961 * 5962 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 5963 */ 5964 /* binop/2addr vA, vB */ 5965 mov r3, rINST, lsr #12 @ r3<- B 5966 mov r9, rINST, lsr #8 @ r9<- A+ 5967 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 5968 and r9, r9, #15 @ r9<- A 5969 flds s1, [r3] @ s1<- vB 5970 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 5971 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5972 flds s0, [r9] @ s0<- vA 5973 5974 fadds s2, s0, s1 @ s2<- op 5975 GET_INST_OPCODE(ip) @ extract opcode from rINST 5976 fsts s2, [r9] @ vAA<- s2 5977 GOTO_OPCODE(ip) @ jump to next instruction 5978 5979 5980 /* ------------------------------ */ 5981 .balign 64 5982 .L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 5983 /* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */ 5984 /* File: arm-vfp/fbinop2addr.S */ 5985 /* 5986 * Generic 32-bit floating point "/2addr" binary operation. Provide 5987 * an "instr" line that specifies an instruction that performs 5988 * "s2 = s0 op s1". 5989 * 5990 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 5991 */ 5992 /* binop/2addr vA, vB */ 5993 mov r3, rINST, lsr #12 @ r3<- B 5994 mov r9, rINST, lsr #8 @ r9<- A+ 5995 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 5996 and r9, r9, #15 @ r9<- A 5997 flds s1, [r3] @ s1<- vB 5998 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 5999 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6000 flds s0, [r9] @ s0<- vA 6001 6002 fsubs s2, s0, s1 @ s2<- op 6003 GET_INST_OPCODE(ip) @ extract opcode from rINST 6004 fsts s2, [r9] @ vAA<- s2 6005 GOTO_OPCODE(ip) @ jump to next instruction 6006 6007 6008 /* ------------------------------ */ 6009 .balign 64 6010 .L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 6011 /* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */ 6012 /* File: arm-vfp/fbinop2addr.S */ 6013 /* 6014 * Generic 32-bit floating point "/2addr" binary operation. Provide 6015 * an "instr" line that specifies an instruction that performs 6016 * "s2 = s0 op s1". 6017 * 6018 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6019 */ 6020 /* binop/2addr vA, vB */ 6021 mov r3, rINST, lsr #12 @ r3<- B 6022 mov r9, rINST, lsr #8 @ r9<- A+ 6023 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6024 and r9, r9, #15 @ r9<- A 6025 flds s1, [r3] @ s1<- vB 6026 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6027 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6028 flds s0, [r9] @ s0<- vA 6029 6030 fmuls s2, s0, s1 @ s2<- op 6031 GET_INST_OPCODE(ip) @ extract opcode from rINST 6032 fsts s2, [r9] @ vAA<- s2 6033 GOTO_OPCODE(ip) @ jump to next instruction 6034 6035 6036 /* ------------------------------ */ 6037 .balign 64 6038 .L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 6039 /* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */ 6040 /* File: arm-vfp/fbinop2addr.S */ 6041 /* 6042 * Generic 32-bit floating point "/2addr" binary operation. Provide 6043 * an "instr" line that specifies an instruction that performs 6044 * "s2 = s0 op s1". 6045 * 6046 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6047 */ 6048 /* binop/2addr vA, vB */ 6049 mov r3, rINST, lsr #12 @ r3<- B 6050 mov r9, rINST, lsr #8 @ r9<- A+ 6051 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6052 and r9, r9, #15 @ r9<- A 6053 flds s1, [r3] @ s1<- vB 6054 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6055 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6056 flds s0, [r9] @ s0<- vA 6057 6058 fdivs s2, s0, s1 @ s2<- op 6059 GET_INST_OPCODE(ip) @ extract opcode from rINST 6060 fsts s2, [r9] @ vAA<- s2 6061 GOTO_OPCODE(ip) @ jump to next instruction 6062 6063 6064 /* ------------------------------ */ 6065 .balign 64 6066 .L_OP_REM_FLOAT_2ADDR: /* 0xca */ 6067 /* File: armv6t2/OP_REM_FLOAT_2ADDR.S */ 6068 /* EABI doesn't define a float remainder function, but libm does */ 6069 /* File: armv6t2/binop2addr.S */ 6070 /* 6071 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6072 * that specifies an instruction that performs "result = r0 op r1". 6073 * This could be an ARM instruction or a function call. (If the result 6074 * comes back in a register other than r0, you can override "result".) 6075 * 6076 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6077 * vCC (r1). Useful for integer division and modulus. 6078 * 6079 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6080 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6081 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6082 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6083 */ 6084 /* binop/2addr vA, vB */ 6085 mov r3, rINST, lsr #12 @ r3<- B 6086 ubfx r9, rINST, #8, #4 @ r9<- A 6087 GET_VREG(r1, r3) @ r1<- vB 6088 GET_VREG(r0, r9) @ r0<- vA 6089 .if 0 6090 cmp r1, #0 @ is second operand zero? 6091 beq common_errDivideByZero 6092 .endif 6093 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6094 6095 @ optional op; may set condition codes 6096 bl fmodf @ r0<- op, r0-r3 changed 6097 GET_INST_OPCODE(ip) @ extract opcode from rINST 6098 SET_VREG(r0, r9) @ vAA<- r0 6099 GOTO_OPCODE(ip) @ jump to next instruction 6100 /* 10-13 instructions */ 6101 6102 6103 /* ------------------------------ */ 6104 .balign 64 6105 .L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 6106 /* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */ 6107 /* File: arm-vfp/fbinopWide2addr.S */ 6108 /* 6109 * Generic 64-bit floating point "/2addr" binary operation. Provide 6110 * an "instr" line that specifies an instruction that performs 6111 * "d2 = d0 op d1". 6112 * 6113 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6114 * div-double/2addr 6115 */ 6116 /* binop/2addr vA, vB */ 6117 mov r3, rINST, lsr #12 @ r3<- B 6118 mov r9, rINST, lsr #8 @ r9<- A+ 6119 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6120 and r9, r9, #15 @ r9<- A 6121 fldd d1, [r3] @ d1<- vB 6122 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6123 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6124 fldd d0, [r9] @ d0<- vA 6125 6126 faddd d2, d0, d1 @ d2<- op 6127 GET_INST_OPCODE(ip) @ extract opcode from rINST 6128 fstd d2, [r9] @ vAA<- d2 6129 GOTO_OPCODE(ip) @ jump to next instruction 6130 6131 6132 /* ------------------------------ */ 6133 .balign 64 6134 .L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 6135 /* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */ 6136 /* File: arm-vfp/fbinopWide2addr.S */ 6137 /* 6138 * Generic 64-bit floating point "/2addr" binary operation. Provide 6139 * an "instr" line that specifies an instruction that performs 6140 * "d2 = d0 op d1". 6141 * 6142 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6143 * div-double/2addr 6144 */ 6145 /* binop/2addr vA, vB */ 6146 mov r3, rINST, lsr #12 @ r3<- B 6147 mov r9, rINST, lsr #8 @ r9<- A+ 6148 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6149 and r9, r9, #15 @ r9<- A 6150 fldd d1, [r3] @ d1<- vB 6151 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6152 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6153 fldd d0, [r9] @ d0<- vA 6154 6155 fsubd d2, d0, d1 @ d2<- op 6156 GET_INST_OPCODE(ip) @ extract opcode from rINST 6157 fstd d2, [r9] @ vAA<- d2 6158 GOTO_OPCODE(ip) @ jump to next instruction 6159 6160 6161 /* ------------------------------ */ 6162 .balign 64 6163 .L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 6164 /* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */ 6165 /* File: arm-vfp/fbinopWide2addr.S */ 6166 /* 6167 * Generic 64-bit floating point "/2addr" binary operation. Provide 6168 * an "instr" line that specifies an instruction that performs 6169 * "d2 = d0 op d1". 6170 * 6171 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6172 * div-double/2addr 6173 */ 6174 /* binop/2addr vA, vB */ 6175 mov r3, rINST, lsr #12 @ r3<- B 6176 mov r9, rINST, lsr #8 @ r9<- A+ 6177 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6178 and r9, r9, #15 @ r9<- A 6179 fldd d1, [r3] @ d1<- vB 6180 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6181 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6182 fldd d0, [r9] @ d0<- vA 6183 6184 fmuld d2, d0, d1 @ d2<- op 6185 GET_INST_OPCODE(ip) @ extract opcode from rINST 6186 fstd d2, [r9] @ vAA<- d2 6187 GOTO_OPCODE(ip) @ jump to next instruction 6188 6189 6190 /* ------------------------------ */ 6191 .balign 64 6192 .L_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 6193 /* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */ 6194 /* File: arm-vfp/fbinopWide2addr.S */ 6195 /* 6196 * Generic 64-bit floating point "/2addr" binary operation. Provide 6197 * an "instr" line that specifies an instruction that performs 6198 * "d2 = d0 op d1". 6199 * 6200 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6201 * div-double/2addr 6202 */ 6203 /* binop/2addr vA, vB */ 6204 mov r3, rINST, lsr #12 @ r3<- B 6205 mov r9, rINST, lsr #8 @ r9<- A+ 6206 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6207 and r9, r9, #15 @ r9<- A 6208 fldd d1, [r3] @ d1<- vB 6209 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6210 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6211 fldd d0, [r9] @ d0<- vA 6212 6213 fdivd d2, d0, d1 @ d2<- op 6214 GET_INST_OPCODE(ip) @ extract opcode from rINST 6215 fstd d2, [r9] @ vAA<- d2 6216 GOTO_OPCODE(ip) @ jump to next instruction 6217 6218 6219 /* ------------------------------ */ 6220 .balign 64 6221 .L_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 6222 /* File: armv6t2/OP_REM_DOUBLE_2ADDR.S */ 6223 /* EABI doesn't define a double remainder function, but libm does */ 6224 /* File: armv6t2/binopWide2addr.S */ 6225 /* 6226 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6227 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6228 * This could be an ARM instruction or a function call. (If the result 6229 * comes back in a register other than r0, you can override "result".) 6230 * 6231 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6232 * vCC (r1). Useful for integer division and modulus. 6233 * 6234 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6235 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6236 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6237 * rem-double/2addr 6238 */ 6239 /* binop/2addr vA, vB */ 6240 mov r1, rINST, lsr #12 @ r1<- B 6241 ubfx r9, rINST, #8, #4 @ r9<- A 6242 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6243 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6244 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6245 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6246 .if 0 6247 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6248 beq common_errDivideByZero 6249 .endif 6250 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6251 6252 @ optional op; may set condition codes 6253 bl fmod @ result<- op, r0-r3 changed 6254 GET_INST_OPCODE(ip) @ extract opcode from rINST 6255 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6256 GOTO_OPCODE(ip) @ jump to next instruction 6257 /* 12-15 instructions */ 6258 6259 6260 /* ------------------------------ */ 6261 .balign 64 6262 .L_OP_ADD_INT_LIT16: /* 0xd0 */ 6263 /* File: armv6t2/OP_ADD_INT_LIT16.S */ 6264 /* File: armv6t2/binopLit16.S */ 6265 /* 6266 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6267 * that specifies an instruction that performs "result = r0 op r1". 6268 * This could be an ARM instruction or a function call. (If the result 6269 * comes back in a register other than r0, you can override "result".) 6270 * 6271 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6272 * vCC (r1). Useful for integer division and modulus. 6273 * 6274 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6275 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6276 */ 6277 /* binop/lit16 vA, vB, #+CCCC */ 6278 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6279 mov r2, rINST, lsr #12 @ r2<- B 6280 ubfx r9, rINST, #8, #4 @ r9<- A 6281 GET_VREG(r0, r2) @ r0<- vB 6282 .if 0 6283 cmp r1, #0 @ is second operand zero? 6284 beq common_errDivideByZero 6285 .endif 6286 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6287 6288 add r0, r0, r1 @ r0<- op, r0-r3 changed 6289 GET_INST_OPCODE(ip) @ extract opcode from rINST 6290 SET_VREG(r0, r9) @ vAA<- r0 6291 GOTO_OPCODE(ip) @ jump to next instruction 6292 /* 10-13 instructions */ 6293 6294 6295 /* ------------------------------ */ 6296 .balign 64 6297 .L_OP_RSUB_INT: /* 0xd1 */ 6298 /* File: armv6t2/OP_RSUB_INT.S */ 6299 /* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */ 6300 /* File: armv6t2/binopLit16.S */ 6301 /* 6302 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6303 * that specifies an instruction that performs "result = r0 op r1". 6304 * This could be an ARM instruction or a function call. (If the result 6305 * comes back in a register other than r0, you can override "result".) 6306 * 6307 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6308 * vCC (r1). Useful for integer division and modulus. 6309 * 6310 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6311 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6312 */ 6313 /* binop/lit16 vA, vB, #+CCCC */ 6314 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6315 mov r2, rINST, lsr #12 @ r2<- B 6316 ubfx r9, rINST, #8, #4 @ r9<- A 6317 GET_VREG(r0, r2) @ r0<- vB 6318 .if 0 6319 cmp r1, #0 @ is second operand zero? 6320 beq common_errDivideByZero 6321 .endif 6322 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6323 6324 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6325 GET_INST_OPCODE(ip) @ extract opcode from rINST 6326 SET_VREG(r0, r9) @ vAA<- r0 6327 GOTO_OPCODE(ip) @ jump to next instruction 6328 /* 10-13 instructions */ 6329 6330 6331 /* ------------------------------ */ 6332 .balign 64 6333 .L_OP_MUL_INT_LIT16: /* 0xd2 */ 6334 /* File: armv6t2/OP_MUL_INT_LIT16.S */ 6335 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6336 /* File: armv6t2/binopLit16.S */ 6337 /* 6338 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6339 * that specifies an instruction that performs "result = r0 op r1". 6340 * This could be an ARM instruction or a function call. (If the result 6341 * comes back in a register other than r0, you can override "result".) 6342 * 6343 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6344 * vCC (r1). Useful for integer division and modulus. 6345 * 6346 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6347 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6348 */ 6349 /* binop/lit16 vA, vB, #+CCCC */ 6350 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6351 mov r2, rINST, lsr #12 @ r2<- B 6352 ubfx r9, rINST, #8, #4 @ r9<- A 6353 GET_VREG(r0, r2) @ r0<- vB 6354 .if 0 6355 cmp r1, #0 @ is second operand zero? 6356 beq common_errDivideByZero 6357 .endif 6358 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6359 6360 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6361 GET_INST_OPCODE(ip) @ extract opcode from rINST 6362 SET_VREG(r0, r9) @ vAA<- r0 6363 GOTO_OPCODE(ip) @ jump to next instruction 6364 /* 10-13 instructions */ 6365 6366 6367 /* ------------------------------ */ 6368 .balign 64 6369 .L_OP_DIV_INT_LIT16: /* 0xd3 */ 6370 /* File: armv6t2/OP_DIV_INT_LIT16.S */ 6371 /* File: armv6t2/binopLit16.S */ 6372 /* 6373 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6374 * that specifies an instruction that performs "result = r0 op r1". 6375 * This could be an ARM instruction or a function call. (If the result 6376 * comes back in a register other than r0, you can override "result".) 6377 * 6378 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6379 * vCC (r1). Useful for integer division and modulus. 6380 * 6381 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6382 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6383 */ 6384 /* binop/lit16 vA, vB, #+CCCC */ 6385 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6386 mov r2, rINST, lsr #12 @ r2<- B 6387 ubfx r9, rINST, #8, #4 @ r9<- A 6388 GET_VREG(r0, r2) @ r0<- vB 6389 .if 1 6390 cmp r1, #0 @ is second operand zero? 6391 beq common_errDivideByZero 6392 .endif 6393 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6394 6395 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6396 GET_INST_OPCODE(ip) @ extract opcode from rINST 6397 SET_VREG(r0, r9) @ vAA<- r0 6398 GOTO_OPCODE(ip) @ jump to next instruction 6399 /* 10-13 instructions */ 6400 6401 6402 /* ------------------------------ */ 6403 .balign 64 6404 .L_OP_REM_INT_LIT16: /* 0xd4 */ 6405 /* File: armv6t2/OP_REM_INT_LIT16.S */ 6406 /* idivmod returns quotient in r0 and remainder in r1 */ 6407 /* File: armv6t2/binopLit16.S */ 6408 /* 6409 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6410 * that specifies an instruction that performs "result = r0 op r1". 6411 * This could be an ARM instruction or a function call. (If the result 6412 * comes back in a register other than r0, you can override "result".) 6413 * 6414 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6415 * vCC (r1). Useful for integer division and modulus. 6416 * 6417 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6418 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6419 */ 6420 /* binop/lit16 vA, vB, #+CCCC */ 6421 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6422 mov r2, rINST, lsr #12 @ r2<- B 6423 ubfx r9, rINST, #8, #4 @ r9<- A 6424 GET_VREG(r0, r2) @ r0<- vB 6425 .if 1 6426 cmp r1, #0 @ is second operand zero? 6427 beq common_errDivideByZero 6428 .endif 6429 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6430 6431 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6432 GET_INST_OPCODE(ip) @ extract opcode from rINST 6433 SET_VREG(r1, r9) @ vAA<- r1 6434 GOTO_OPCODE(ip) @ jump to next instruction 6435 /* 10-13 instructions */ 6436 6437 6438 /* ------------------------------ */ 6439 .balign 64 6440 .L_OP_AND_INT_LIT16: /* 0xd5 */ 6441 /* File: armv6t2/OP_AND_INT_LIT16.S */ 6442 /* File: armv6t2/binopLit16.S */ 6443 /* 6444 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6445 * that specifies an instruction that performs "result = r0 op r1". 6446 * This could be an ARM instruction or a function call. (If the result 6447 * comes back in a register other than r0, you can override "result".) 6448 * 6449 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6450 * vCC (r1). Useful for integer division and modulus. 6451 * 6452 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6453 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6454 */ 6455 /* binop/lit16 vA, vB, #+CCCC */ 6456 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6457 mov r2, rINST, lsr #12 @ r2<- B 6458 ubfx r9, rINST, #8, #4 @ r9<- A 6459 GET_VREG(r0, r2) @ r0<- vB 6460 .if 0 6461 cmp r1, #0 @ is second operand zero? 6462 beq common_errDivideByZero 6463 .endif 6464 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6465 6466 and r0, r0, r1 @ r0<- op, r0-r3 changed 6467 GET_INST_OPCODE(ip) @ extract opcode from rINST 6468 SET_VREG(r0, r9) @ vAA<- r0 6469 GOTO_OPCODE(ip) @ jump to next instruction 6470 /* 10-13 instructions */ 6471 6472 6473 /* ------------------------------ */ 6474 .balign 64 6475 .L_OP_OR_INT_LIT16: /* 0xd6 */ 6476 /* File: armv6t2/OP_OR_INT_LIT16.S */ 6477 /* File: armv6t2/binopLit16.S */ 6478 /* 6479 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6480 * that specifies an instruction that performs "result = r0 op r1". 6481 * This could be an ARM instruction or a function call. (If the result 6482 * comes back in a register other than r0, you can override "result".) 6483 * 6484 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6485 * vCC (r1). Useful for integer division and modulus. 6486 * 6487 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6488 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6489 */ 6490 /* binop/lit16 vA, vB, #+CCCC */ 6491 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6492 mov r2, rINST, lsr #12 @ r2<- B 6493 ubfx r9, rINST, #8, #4 @ r9<- A 6494 GET_VREG(r0, r2) @ r0<- vB 6495 .if 0 6496 cmp r1, #0 @ is second operand zero? 6497 beq common_errDivideByZero 6498 .endif 6499 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6500 6501 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6502 GET_INST_OPCODE(ip) @ extract opcode from rINST 6503 SET_VREG(r0, r9) @ vAA<- r0 6504 GOTO_OPCODE(ip) @ jump to next instruction 6505 /* 10-13 instructions */ 6506 6507 6508 /* ------------------------------ */ 6509 .balign 64 6510 .L_OP_XOR_INT_LIT16: /* 0xd7 */ 6511 /* File: armv6t2/OP_XOR_INT_LIT16.S */ 6512 /* File: armv6t2/binopLit16.S */ 6513 /* 6514 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6515 * that specifies an instruction that performs "result = r0 op r1". 6516 * This could be an ARM instruction or a function call. (If the result 6517 * comes back in a register other than r0, you can override "result".) 6518 * 6519 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6520 * vCC (r1). Useful for integer division and modulus. 6521 * 6522 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6523 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6524 */ 6525 /* binop/lit16 vA, vB, #+CCCC */ 6526 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6527 mov r2, rINST, lsr #12 @ r2<- B 6528 ubfx r9, rINST, #8, #4 @ r9<- A 6529 GET_VREG(r0, r2) @ r0<- vB 6530 .if 0 6531 cmp r1, #0 @ is second operand zero? 6532 beq common_errDivideByZero 6533 .endif 6534 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6535 6536 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6537 GET_INST_OPCODE(ip) @ extract opcode from rINST 6538 SET_VREG(r0, r9) @ vAA<- r0 6539 GOTO_OPCODE(ip) @ jump to next instruction 6540 /* 10-13 instructions */ 6541 6542 6543 /* ------------------------------ */ 6544 .balign 64 6545 .L_OP_ADD_INT_LIT8: /* 0xd8 */ 6546 /* File: armv5te/OP_ADD_INT_LIT8.S */ 6547 /* File: armv5te/binopLit8.S */ 6548 /* 6549 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6550 * that specifies an instruction that performs "result = r0 op r1". 6551 * This could be an ARM instruction or a function call. (If the result 6552 * comes back in a register other than r0, you can override "result".) 6553 * 6554 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6555 * vCC (r1). Useful for integer division and modulus. 6556 * 6557 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6558 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6559 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6560 */ 6561 /* binop/lit8 vAA, vBB, #+CC */ 6562 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6563 mov r9, rINST, lsr #8 @ r9<- AA 6564 and r2, r3, #255 @ r2<- BB 6565 GET_VREG(r0, r2) @ r0<- vBB 6566 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6567 .if 0 6568 @cmp r1, #0 @ is second operand zero? 6569 beq common_errDivideByZero 6570 .endif 6571 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6572 6573 @ optional op; may set condition codes 6574 add r0, r0, r1 @ r0<- op, r0-r3 changed 6575 GET_INST_OPCODE(ip) @ extract opcode from rINST 6576 SET_VREG(r0, r9) @ vAA<- r0 6577 GOTO_OPCODE(ip) @ jump to next instruction 6578 /* 10-12 instructions */ 6579 6580 6581 /* ------------------------------ */ 6582 .balign 64 6583 .L_OP_RSUB_INT_LIT8: /* 0xd9 */ 6584 /* File: armv5te/OP_RSUB_INT_LIT8.S */ 6585 /* File: armv5te/binopLit8.S */ 6586 /* 6587 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6588 * that specifies an instruction that performs "result = r0 op r1". 6589 * This could be an ARM instruction or a function call. (If the result 6590 * comes back in a register other than r0, you can override "result".) 6591 * 6592 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6593 * vCC (r1). Useful for integer division and modulus. 6594 * 6595 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6596 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6597 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6598 */ 6599 /* binop/lit8 vAA, vBB, #+CC */ 6600 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6601 mov r9, rINST, lsr #8 @ r9<- AA 6602 and r2, r3, #255 @ r2<- BB 6603 GET_VREG(r0, r2) @ r0<- vBB 6604 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6605 .if 0 6606 @cmp r1, #0 @ is second operand zero? 6607 beq common_errDivideByZero 6608 .endif 6609 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6610 6611 @ optional op; may set condition codes 6612 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6613 GET_INST_OPCODE(ip) @ extract opcode from rINST 6614 SET_VREG(r0, r9) @ vAA<- r0 6615 GOTO_OPCODE(ip) @ jump to next instruction 6616 /* 10-12 instructions */ 6617 6618 6619 /* ------------------------------ */ 6620 .balign 64 6621 .L_OP_MUL_INT_LIT8: /* 0xda */ 6622 /* File: armv5te/OP_MUL_INT_LIT8.S */ 6623 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6624 /* File: armv5te/binopLit8.S */ 6625 /* 6626 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6627 * that specifies an instruction that performs "result = r0 op r1". 6628 * This could be an ARM instruction or a function call. (If the result 6629 * comes back in a register other than r0, you can override "result".) 6630 * 6631 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6632 * vCC (r1). Useful for integer division and modulus. 6633 * 6634 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6635 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6636 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6637 */ 6638 /* binop/lit8 vAA, vBB, #+CC */ 6639 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6640 mov r9, rINST, lsr #8 @ r9<- AA 6641 and r2, r3, #255 @ r2<- BB 6642 GET_VREG(r0, r2) @ r0<- vBB 6643 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6644 .if 0 6645 @cmp r1, #0 @ is second operand zero? 6646 beq common_errDivideByZero 6647 .endif 6648 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6649 6650 @ optional op; may set condition codes 6651 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6652 GET_INST_OPCODE(ip) @ extract opcode from rINST 6653 SET_VREG(r0, r9) @ vAA<- r0 6654 GOTO_OPCODE(ip) @ jump to next instruction 6655 /* 10-12 instructions */ 6656 6657 6658 /* ------------------------------ */ 6659 .balign 64 6660 .L_OP_DIV_INT_LIT8: /* 0xdb */ 6661 /* File: armv5te/OP_DIV_INT_LIT8.S */ 6662 /* File: armv5te/binopLit8.S */ 6663 /* 6664 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6665 * that specifies an instruction that performs "result = r0 op r1". 6666 * This could be an ARM instruction or a function call. (If the result 6667 * comes back in a register other than r0, you can override "result".) 6668 * 6669 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6670 * vCC (r1). Useful for integer division and modulus. 6671 * 6672 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6673 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6674 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6675 */ 6676 /* binop/lit8 vAA, vBB, #+CC */ 6677 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6678 mov r9, rINST, lsr #8 @ r9<- AA 6679 and r2, r3, #255 @ r2<- BB 6680 GET_VREG(r0, r2) @ r0<- vBB 6681 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6682 .if 1 6683 @cmp r1, #0 @ is second operand zero? 6684 beq common_errDivideByZero 6685 .endif 6686 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6687 6688 @ optional op; may set condition codes 6689 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6690 GET_INST_OPCODE(ip) @ extract opcode from rINST 6691 SET_VREG(r0, r9) @ vAA<- r0 6692 GOTO_OPCODE(ip) @ jump to next instruction 6693 /* 10-12 instructions */ 6694 6695 6696 /* ------------------------------ */ 6697 .balign 64 6698 .L_OP_REM_INT_LIT8: /* 0xdc */ 6699 /* File: armv5te/OP_REM_INT_LIT8.S */ 6700 /* idivmod returns quotient in r0 and remainder in r1 */ 6701 /* File: armv5te/binopLit8.S */ 6702 /* 6703 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6704 * that specifies an instruction that performs "result = r0 op r1". 6705 * This could be an ARM instruction or a function call. (If the result 6706 * comes back in a register other than r0, you can override "result".) 6707 * 6708 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6709 * vCC (r1). Useful for integer division and modulus. 6710 * 6711 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6712 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6713 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6714 */ 6715 /* binop/lit8 vAA, vBB, #+CC */ 6716 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6717 mov r9, rINST, lsr #8 @ r9<- AA 6718 and r2, r3, #255 @ r2<- BB 6719 GET_VREG(r0, r2) @ r0<- vBB 6720 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6721 .if 1 6722 @cmp r1, #0 @ is second operand zero? 6723 beq common_errDivideByZero 6724 .endif 6725 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6726 6727 @ optional op; may set condition codes 6728 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6729 GET_INST_OPCODE(ip) @ extract opcode from rINST 6730 SET_VREG(r1, r9) @ vAA<- r1 6731 GOTO_OPCODE(ip) @ jump to next instruction 6732 /* 10-12 instructions */ 6733 6734 6735 /* ------------------------------ */ 6736 .balign 64 6737 .L_OP_AND_INT_LIT8: /* 0xdd */ 6738 /* File: armv5te/OP_AND_INT_LIT8.S */ 6739 /* File: armv5te/binopLit8.S */ 6740 /* 6741 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6742 * that specifies an instruction that performs "result = r0 op r1". 6743 * This could be an ARM instruction or a function call. (If the result 6744 * comes back in a register other than r0, you can override "result".) 6745 * 6746 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6747 * vCC (r1). Useful for integer division and modulus. 6748 * 6749 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6750 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6751 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6752 */ 6753 /* binop/lit8 vAA, vBB, #+CC */ 6754 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6755 mov r9, rINST, lsr #8 @ r9<- AA 6756 and r2, r3, #255 @ r2<- BB 6757 GET_VREG(r0, r2) @ r0<- vBB 6758 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6759 .if 0 6760 @cmp r1, #0 @ is second operand zero? 6761 beq common_errDivideByZero 6762 .endif 6763 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6764 6765 @ optional op; may set condition codes 6766 and r0, r0, r1 @ r0<- op, r0-r3 changed 6767 GET_INST_OPCODE(ip) @ extract opcode from rINST 6768 SET_VREG(r0, r9) @ vAA<- r0 6769 GOTO_OPCODE(ip) @ jump to next instruction 6770 /* 10-12 instructions */ 6771 6772 6773 /* ------------------------------ */ 6774 .balign 64 6775 .L_OP_OR_INT_LIT8: /* 0xde */ 6776 /* File: armv5te/OP_OR_INT_LIT8.S */ 6777 /* File: armv5te/binopLit8.S */ 6778 /* 6779 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6780 * that specifies an instruction that performs "result = r0 op r1". 6781 * This could be an ARM instruction or a function call. (If the result 6782 * comes back in a register other than r0, you can override "result".) 6783 * 6784 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6785 * vCC (r1). Useful for integer division and modulus. 6786 * 6787 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6788 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6789 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6790 */ 6791 /* binop/lit8 vAA, vBB, #+CC */ 6792 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6793 mov r9, rINST, lsr #8 @ r9<- AA 6794 and r2, r3, #255 @ r2<- BB 6795 GET_VREG(r0, r2) @ r0<- vBB 6796 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6797 .if 0 6798 @cmp r1, #0 @ is second operand zero? 6799 beq common_errDivideByZero 6800 .endif 6801 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6802 6803 @ optional op; may set condition codes 6804 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6805 GET_INST_OPCODE(ip) @ extract opcode from rINST 6806 SET_VREG(r0, r9) @ vAA<- r0 6807 GOTO_OPCODE(ip) @ jump to next instruction 6808 /* 10-12 instructions */ 6809 6810 6811 /* ------------------------------ */ 6812 .balign 64 6813 .L_OP_XOR_INT_LIT8: /* 0xdf */ 6814 /* File: armv5te/OP_XOR_INT_LIT8.S */ 6815 /* File: armv5te/binopLit8.S */ 6816 /* 6817 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6818 * that specifies an instruction that performs "result = r0 op r1". 6819 * This could be an ARM instruction or a function call. (If the result 6820 * comes back in a register other than r0, you can override "result".) 6821 * 6822 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6823 * vCC (r1). Useful for integer division and modulus. 6824 * 6825 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6826 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6827 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6828 */ 6829 /* binop/lit8 vAA, vBB, #+CC */ 6830 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6831 mov r9, rINST, lsr #8 @ r9<- AA 6832 and r2, r3, #255 @ r2<- BB 6833 GET_VREG(r0, r2) @ r0<- vBB 6834 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6835 .if 0 6836 @cmp r1, #0 @ is second operand zero? 6837 beq common_errDivideByZero 6838 .endif 6839 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6840 6841 @ optional op; may set condition codes 6842 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6843 GET_INST_OPCODE(ip) @ extract opcode from rINST 6844 SET_VREG(r0, r9) @ vAA<- r0 6845 GOTO_OPCODE(ip) @ jump to next instruction 6846 /* 10-12 instructions */ 6847 6848 6849 /* ------------------------------ */ 6850 .balign 64 6851 .L_OP_SHL_INT_LIT8: /* 0xe0 */ 6852 /* File: armv5te/OP_SHL_INT_LIT8.S */ 6853 /* File: armv5te/binopLit8.S */ 6854 /* 6855 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6856 * that specifies an instruction that performs "result = r0 op r1". 6857 * This could be an ARM instruction or a function call. (If the result 6858 * comes back in a register other than r0, you can override "result".) 6859 * 6860 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6861 * vCC (r1). Useful for integer division and modulus. 6862 * 6863 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6864 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6865 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6866 */ 6867 /* binop/lit8 vAA, vBB, #+CC */ 6868 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6869 mov r9, rINST, lsr #8 @ r9<- AA 6870 and r2, r3, #255 @ r2<- BB 6871 GET_VREG(r0, r2) @ r0<- vBB 6872 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6873 .if 0 6874 @cmp r1, #0 @ is second operand zero? 6875 beq common_errDivideByZero 6876 .endif 6877 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6878 6879 and r1, r1, #31 @ optional op; may set condition codes 6880 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 6881 GET_INST_OPCODE(ip) @ extract opcode from rINST 6882 SET_VREG(r0, r9) @ vAA<- r0 6883 GOTO_OPCODE(ip) @ jump to next instruction 6884 /* 10-12 instructions */ 6885 6886 6887 /* ------------------------------ */ 6888 .balign 64 6889 .L_OP_SHR_INT_LIT8: /* 0xe1 */ 6890 /* File: armv5te/OP_SHR_INT_LIT8.S */ 6891 /* File: armv5te/binopLit8.S */ 6892 /* 6893 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6894 * that specifies an instruction that performs "result = r0 op r1". 6895 * This could be an ARM instruction or a function call. (If the result 6896 * comes back in a register other than r0, you can override "result".) 6897 * 6898 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6899 * vCC (r1). Useful for integer division and modulus. 6900 * 6901 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6902 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6903 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6904 */ 6905 /* binop/lit8 vAA, vBB, #+CC */ 6906 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6907 mov r9, rINST, lsr #8 @ r9<- AA 6908 and r2, r3, #255 @ r2<- BB 6909 GET_VREG(r0, r2) @ r0<- vBB 6910 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6911 .if 0 6912 @cmp r1, #0 @ is second operand zero? 6913 beq common_errDivideByZero 6914 .endif 6915 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6916 6917 and r1, r1, #31 @ optional op; may set condition codes 6918 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 6919 GET_INST_OPCODE(ip) @ extract opcode from rINST 6920 SET_VREG(r0, r9) @ vAA<- r0 6921 GOTO_OPCODE(ip) @ jump to next instruction 6922 /* 10-12 instructions */ 6923 6924 6925 /* ------------------------------ */ 6926 .balign 64 6927 .L_OP_USHR_INT_LIT8: /* 0xe2 */ 6928 /* File: armv5te/OP_USHR_INT_LIT8.S */ 6929 /* File: armv5te/binopLit8.S */ 6930 /* 6931 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6932 * that specifies an instruction that performs "result = r0 op r1". 6933 * This could be an ARM instruction or a function call. (If the result 6934 * comes back in a register other than r0, you can override "result".) 6935 * 6936 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6937 * vCC (r1). Useful for integer division and modulus. 6938 * 6939 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6940 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6941 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6942 */ 6943 /* binop/lit8 vAA, vBB, #+CC */ 6944 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6945 mov r9, rINST, lsr #8 @ r9<- AA 6946 and r2, r3, #255 @ r2<- BB 6947 GET_VREG(r0, r2) @ r0<- vBB 6948 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6949 .if 0 6950 @cmp r1, #0 @ is second operand zero? 6951 beq common_errDivideByZero 6952 .endif 6953 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6954 6955 and r1, r1, #31 @ optional op; may set condition codes 6956 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 6957 GET_INST_OPCODE(ip) @ extract opcode from rINST 6958 SET_VREG(r0, r9) @ vAA<- r0 6959 GOTO_OPCODE(ip) @ jump to next instruction 6960 /* 10-12 instructions */ 6961 6962 6963 /* ------------------------------ */ 6964 .balign 64 6965 .L_OP_IGET_VOLATILE: /* 0xe3 */ 6966 /* File: armv5te/OP_IGET_VOLATILE.S */ 6967 /* File: armv5te/OP_IGET.S */ 6968 /* 6969 * General 32-bit instance field get. 6970 * 6971 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 6972 */ 6973 /* op vA, vB, field@CCCC */ 6974 mov r0, rINST, lsr #12 @ r0<- B 6975 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 6976 FETCH(r1, 1) @ r1<- field ref CCCC 6977 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 6978 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 6979 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 6980 cmp r0, #0 @ is resolved entry null? 6981 bne .LOP_IGET_VOLATILE_finish @ no, already resolved 6982 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 6983 EXPORT_PC() @ resolve() could throw 6984 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 6985 bl dvmResolveInstField @ r0<- resolved InstField ptr 6986 cmp r0, #0 6987 bne .LOP_IGET_VOLATILE_finish 6988 b common_exceptionThrown 6989 6990 6991 /* ------------------------------ */ 6992 .balign 64 6993 .L_OP_IPUT_VOLATILE: /* 0xe4 */ 6994 /* File: armv5te/OP_IPUT_VOLATILE.S */ 6995 /* File: armv5te/OP_IPUT.S */ 6996 /* 6997 * General 32-bit instance field put. 6998 * 6999 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 7000 */ 7001 /* op vA, vB, field@CCCC */ 7002 mov r0, rINST, lsr #12 @ r0<- B 7003 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7004 FETCH(r1, 1) @ r1<- field ref CCCC 7005 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7006 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7007 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7008 cmp r0, #0 @ is resolved entry null? 7009 bne .LOP_IPUT_VOLATILE_finish @ no, already resolved 7010 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7011 EXPORT_PC() @ resolve() could throw 7012 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7013 bl dvmResolveInstField @ r0<- resolved InstField ptr 7014 cmp r0, #0 @ success? 7015 bne .LOP_IPUT_VOLATILE_finish @ yes, finish up 7016 b common_exceptionThrown 7017 7018 7019 /* ------------------------------ */ 7020 .balign 64 7021 .L_OP_SGET_VOLATILE: /* 0xe5 */ 7022 /* File: armv5te/OP_SGET_VOLATILE.S */ 7023 /* File: armv5te/OP_SGET.S */ 7024 /* 7025 * General 32-bit SGET handler. 7026 * 7027 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7028 */ 7029 /* op vAA, field@BBBB */ 7030 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7031 FETCH(r1, 1) @ r1<- field ref BBBB 7032 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7033 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7034 cmp r0, #0 @ is resolved entry null? 7035 beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve 7036 .LOP_SGET_VOLATILE_finish: @ field ptr in r0 7037 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7038 SMP_DMB @ acquiring load 7039 mov r2, rINST, lsr #8 @ r2<- AA 7040 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7041 SET_VREG(r1, r2) @ fp[AA]<- r1 7042 GET_INST_OPCODE(ip) @ extract opcode from rINST 7043 GOTO_OPCODE(ip) @ jump to next instruction 7044 7045 7046 /* ------------------------------ */ 7047 .balign 64 7048 .L_OP_SPUT_VOLATILE: /* 0xe6 */ 7049 /* File: armv5te/OP_SPUT_VOLATILE.S */ 7050 /* File: armv5te/OP_SPUT.S */ 7051 /* 7052 * General 32-bit SPUT handler. 7053 * 7054 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 7055 */ 7056 /* op vAA, field@BBBB */ 7057 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7058 FETCH(r1, 1) @ r1<- field ref BBBB 7059 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7060 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7061 cmp r0, #0 @ is resolved entry null? 7062 beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve 7063 .LOP_SPUT_VOLATILE_finish: @ field ptr in r0 7064 mov r2, rINST, lsr #8 @ r2<- AA 7065 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7066 GET_VREG(r1, r2) @ r1<- fp[AA] 7067 GET_INST_OPCODE(ip) @ extract opcode from rINST 7068 SMP_DMB_ST @ releasing store 7069 str r1, [r0, #offStaticField_value] @ field<- vAA 7070 SMP_DMB 7071 GOTO_OPCODE(ip) @ jump to next instruction 7072 7073 7074 /* ------------------------------ */ 7075 .balign 64 7076 .L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 7077 /* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */ 7078 /* File: armv5te/OP_IGET.S */ 7079 /* 7080 * General 32-bit instance field get. 7081 * 7082 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7083 */ 7084 /* op vA, vB, field@CCCC */ 7085 mov r0, rINST, lsr #12 @ r0<- B 7086 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7087 FETCH(r1, 1) @ r1<- field ref CCCC 7088 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7089 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7090 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7091 cmp r0, #0 @ is resolved entry null? 7092 bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved 7093 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7094 EXPORT_PC() @ resolve() could throw 7095 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7096 bl dvmResolveInstField @ r0<- resolved InstField ptr 7097 cmp r0, #0 7098 bne .LOP_IGET_OBJECT_VOLATILE_finish 7099 b common_exceptionThrown 7100 7101 7102 /* ------------------------------ */ 7103 .balign 64 7104 .L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 7105 /* File: armv5te/OP_IGET_WIDE_VOLATILE.S */ 7106 /* File: armv5te/OP_IGET_WIDE.S */ 7107 /* 7108 * Wide 32-bit instance field get. 7109 */ 7110 /* iget-wide vA, vB, field@CCCC */ 7111 mov r0, rINST, lsr #12 @ r0<- B 7112 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7113 FETCH(r1, 1) @ r1<- field ref CCCC 7114 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7115 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7116 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7117 cmp r0, #0 @ is resolved entry null? 7118 bne .LOP_IGET_WIDE_VOLATILE_finish @ no, already resolved 7119 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7120 EXPORT_PC() @ resolve() could throw 7121 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7122 bl dvmResolveInstField @ r0<- resolved InstField ptr 7123 cmp r0, #0 7124 bne .LOP_IGET_WIDE_VOLATILE_finish 7125 b common_exceptionThrown 7126 7127 7128 /* ------------------------------ */ 7129 .balign 64 7130 .L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 7131 /* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */ 7132 /* File: armv5te/OP_IPUT_WIDE.S */ 7133 /* iput-wide vA, vB, field@CCCC */ 7134 mov r0, rINST, lsr #12 @ r0<- B 7135 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7136 FETCH(r1, 1) @ r1<- field ref CCCC 7137 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7138 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7139 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7140 cmp r0, #0 @ is resolved entry null? 7141 bne .LOP_IPUT_WIDE_VOLATILE_finish @ no, already resolved 7142 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7143 EXPORT_PC() @ resolve() could throw 7144 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7145 bl dvmResolveInstField @ r0<- resolved InstField ptr 7146 cmp r0, #0 @ success? 7147 bne .LOP_IPUT_WIDE_VOLATILE_finish @ yes, finish up 7148 b common_exceptionThrown 7149 7150 7151 /* ------------------------------ */ 7152 .balign 64 7153 .L_OP_SGET_WIDE_VOLATILE: /* 0xea */ 7154 /* File: armv5te/OP_SGET_WIDE_VOLATILE.S */ 7155 /* File: armv5te/OP_SGET_WIDE.S */ 7156 /* 7157 * 64-bit SGET handler. 7158 */ 7159 /* sget-wide vAA, field@BBBB */ 7160 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7161 FETCH(r1, 1) @ r1<- field ref BBBB 7162 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7163 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7164 cmp r0, #0 @ is resolved entry null? 7165 beq .LOP_SGET_WIDE_VOLATILE_resolve @ yes, do resolve 7166 .LOP_SGET_WIDE_VOLATILE_finish: 7167 mov r9, rINST, lsr #8 @ r9<- AA 7168 .if 1 7169 add r0, r0, #offStaticField_value @ r0<- pointer to data 7170 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 7171 .else 7172 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 7173 .endif 7174 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7175 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7176 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 7177 GET_INST_OPCODE(ip) @ extract opcode from rINST 7178 GOTO_OPCODE(ip) @ jump to next instruction 7179 7180 7181 /* ------------------------------ */ 7182 .balign 64 7183 .L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 7184 /* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */ 7185 /* File: armv5te/OP_SPUT_WIDE.S */ 7186 /* 7187 * 64-bit SPUT handler. 7188 */ 7189 /* sput-wide vAA, field@BBBB */ 7190 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- DvmDex 7191 FETCH(r1, 1) @ r1<- field ref BBBB 7192 ldr r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7193 mov r9, rINST, lsr #8 @ r9<- AA 7194 ldr r2, [r10, r1, lsl #2] @ r2<- resolved StaticField ptr 7195 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7196 cmp r2, #0 @ is resolved entry null? 7197 beq .LOP_SPUT_WIDE_VOLATILE_resolve @ yes, do resolve 7198 .LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9 7199 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7200 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 7201 GET_INST_OPCODE(r10) @ extract opcode from rINST 7202 .if 1 7203 add r2, r2, #offStaticField_value @ r2<- pointer to data 7204 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 7205 .else 7206 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 7207 .endif 7208 GOTO_OPCODE(r10) @ jump to next instruction 7209 7210 7211 /* ------------------------------ */ 7212 .balign 64 7213 .L_OP_BREAKPOINT: /* 0xec */ 7214 /* File: armv5te/OP_BREAKPOINT.S */ 7215 /* 7216 * Breakpoint handler. 7217 * 7218 * Restart this instruction with the original opcode. By 7219 * the time we get here, the breakpoint will have already been 7220 * handled. 7221 */ 7222 mov r0, rPC 7223 bl dvmGetOriginalOpcode @ (rPC) 7224 FETCH(rINST, 0) @ reload OP_BREAKPOINT + rest of inst 7225 ldr r1, [rSELF, #offThread_mainHandlerTable] 7226 and rINST, #0xff00 7227 orr rINST, rINST, r0 7228 GOTO_OPCODE_BASE(r1, r0) 7229 7230 /* ------------------------------ */ 7231 .balign 64 7232 .L_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 7233 /* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */ 7234 /* 7235 * Handle a throw-verification-error instruction. This throws an 7236 * exception for an error discovered during verification. The 7237 * exception is indicated by AA, with some detail provided by BBBB. 7238 */ 7239 /* op AA, ref@BBBB */ 7240 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7241 FETCH(r2, 1) @ r2<- BBBB 7242 EXPORT_PC() @ export the PC 7243 mov r1, rINST, lsr #8 @ r1<- AA 7244 bl dvmThrowVerificationError @ always throws 7245 b common_exceptionThrown @ handle exception 7246 7247 /* ------------------------------ */ 7248 .balign 64 7249 .L_OP_EXECUTE_INLINE: /* 0xee */ 7250 /* File: armv5te/OP_EXECUTE_INLINE.S */ 7251 /* 7252 * Execute a "native inline" instruction. 7253 * 7254 * We need to call an InlineOp4Func: 7255 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7256 * 7257 * The first four args are in r0-r3, pointer to return value storage 7258 * is on the stack. The function's return value is a flag that tells 7259 * us if an exception was thrown. 7260 * 7261 * TUNING: could maintain two tables, pointer in Thread and 7262 * swap if profiler/debuggger active. 7263 */ 7264 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 7265 ldrh r2, [rSELF, #offThread_subMode] 7266 FETCH(r10, 1) @ r10<- BBBB 7267 EXPORT_PC() @ can throw 7268 ands r2, #kSubModeDebugProfile @ Any going on? 7269 bne .LOP_EXECUTE_INLINE_debugmode @ yes - take slow path 7270 .LOP_EXECUTE_INLINE_resume: 7271 add r1, rSELF, #offThread_retval @ r1<- &self->retval 7272 sub sp, sp, #8 @ make room for arg, +64 bit align 7273 mov r0, rINST, lsr #12 @ r0<- B 7274 str r1, [sp] @ push &self->retval 7275 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 7276 add sp, sp, #8 @ pop stack 7277 cmp r0, #0 @ test boolean result of inline 7278 beq common_exceptionThrown @ returned false, handle exception 7279 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7280 GET_INST_OPCODE(ip) @ extract opcode from rINST 7281 GOTO_OPCODE(ip) @ jump to next instruction 7282 7283 /* ------------------------------ */ 7284 .balign 64 7285 .L_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 7286 /* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */ 7287 /* 7288 * Execute a "native inline" instruction, using "/range" semantics. 7289 * Same idea as execute-inline, but we get the args differently. 7290 * 7291 * We need to call an InlineOp4Func: 7292 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7293 * 7294 * The first four args are in r0-r3, pointer to return value storage 7295 * is on the stack. The function's return value is a flag that tells 7296 * us if an exception was thrown. 7297 */ 7298 /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */ 7299 ldrh r2, [rSELF, #offThread_subMode] 7300 FETCH(r10, 1) @ r10<- BBBB 7301 EXPORT_PC() @ can throw 7302 ands r2, #kSubModeDebugProfile @ Any going on? 7303 bne .LOP_EXECUTE_INLINE_RANGE_debugmode @ yes - take slow path 7304 .LOP_EXECUTE_INLINE_RANGE_resume: 7305 add r1, rSELF, #offThread_retval @ r1<- &self->retval 7306 sub sp, sp, #8 @ make room for arg, +64 bit align 7307 mov r0, rINST, lsr #8 @ r0<- AA 7308 str r1, [sp] @ push &self->retval 7309 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 7310 add sp, sp, #8 @ pop stack 7311 cmp r0, #0 @ test boolean result of inline 7312 beq common_exceptionThrown @ returned false, handle exception 7313 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7314 GET_INST_OPCODE(ip) @ extract opcode from rINST 7315 GOTO_OPCODE(ip) @ jump to next instruction 7316 7317 /* ------------------------------ */ 7318 .balign 64 7319 .L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */ 7320 /* File: armv5te/OP_INVOKE_OBJECT_INIT_RANGE.S */ 7321 /* 7322 * Invoke Object.<init> on an object. In practice we know that 7323 * Object's nullary constructor doesn't do anything, so we just 7324 * skip it unless a debugger is active. 7325 */ 7326 FETCH(r1, 2) @ r1<- CCCC 7327 GET_VREG(r0, r1) @ r0<- "this" ptr 7328 cmp r0, #0 @ check for NULL 7329 beq common_errNullObject @ export PC and throw NPE 7330 ldr r1, [r0, #offObject_clazz] @ r1<- obj->clazz 7331 ldr r2, [r1, #offClassObject_accessFlags] @ r2<- clazz->accessFlags 7332 tst r2, #CLASS_ISFINALIZABLE @ is this class finalizable? 7333 bne .LOP_INVOKE_OBJECT_INIT_RANGE_setFinal @ yes, go 7334 .LOP_INVOKE_OBJECT_INIT_RANGE_finish: 7335 ldrh r1, [rSELF, #offThread_subMode] 7336 ands r1, #kSubModeDebuggerActive @ debugger active? 7337 bne .LOP_INVOKE_OBJECT_INIT_RANGE_debugger @ Yes - skip optimization 7338 FETCH_ADVANCE_INST(2+1) @ advance to next instr, load rINST 7339 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 7340 GOTO_OPCODE(ip) @ execute it 7341 7342 /* ------------------------------ */ 7343 .balign 64 7344 .L_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 7345 /* File: armv5te/OP_RETURN_VOID_BARRIER.S */ 7346 SMP_DMB_ST 7347 b common_returnFromMethod 7348 7349 /* ------------------------------ */ 7350 .balign 64 7351 .L_OP_IGET_QUICK: /* 0xf2 */ 7352 /* File: armv6t2/OP_IGET_QUICK.S */ 7353 /* For: iget-quick, iget-object-quick */ 7354 /* op vA, vB, offset@CCCC */ 7355 mov r2, rINST, lsr #12 @ r2<- B 7356 FETCH(r1, 1) @ r1<- field byte offset 7357 GET_VREG(r3, r2) @ r3<- object we're operating on 7358 ubfx r2, rINST, #8, #4 @ r2<- A 7359 cmp r3, #0 @ check object for null 7360 beq common_errNullObject @ object was null 7361 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7362 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7363 GET_INST_OPCODE(ip) @ extract opcode from rINST 7364 SET_VREG(r0, r2) @ fp[A]<- r0 7365 GOTO_OPCODE(ip) @ jump to next instruction 7366 7367 /* ------------------------------ */ 7368 .balign 64 7369 .L_OP_IGET_WIDE_QUICK: /* 0xf3 */ 7370 /* File: armv6t2/OP_IGET_WIDE_QUICK.S */ 7371 /* iget-wide-quick vA, vB, offset@CCCC */ 7372 mov r2, rINST, lsr #12 @ r2<- B 7373 FETCH(ip, 1) @ ip<- field byte offset 7374 GET_VREG(r3, r2) @ r3<- object we're operating on 7375 ubfx r2, rINST, #8, #4 @ r2<- A 7376 cmp r3, #0 @ check object for null 7377 beq common_errNullObject @ object was null 7378 ldrd r0, [r3, ip] @ r0<- obj.field (64 bits, aligned) 7379 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7380 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 7381 GET_INST_OPCODE(ip) @ extract opcode from rINST 7382 stmia r3, {r0-r1} @ fp[A]<- r0/r1 7383 GOTO_OPCODE(ip) @ jump to next instruction 7384 7385 /* ------------------------------ */ 7386 .balign 64 7387 .L_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 7388 /* File: armv5te/OP_IGET_OBJECT_QUICK.S */ 7389 /* File: armv5te/OP_IGET_QUICK.S */ 7390 /* For: iget-quick, iget-object-quick */ 7391 /* op vA, vB, offset@CCCC */ 7392 mov r2, rINST, lsr #12 @ r2<- B 7393 GET_VREG(r3, r2) @ r3<- object we're operating on 7394 FETCH(r1, 1) @ r1<- field byte offset 7395 cmp r3, #0 @ check object for null 7396 mov r2, rINST, lsr #8 @ r2<- A(+) 7397 beq common_errNullObject @ object was null 7398 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7399 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7400 and r2, r2, #15 7401 GET_INST_OPCODE(ip) @ extract opcode from rINST 7402 SET_VREG(r0, r2) @ fp[A]<- r0 7403 GOTO_OPCODE(ip) @ jump to next instruction 7404 7405 7406 /* ------------------------------ */ 7407 .balign 64 7408 .L_OP_IPUT_QUICK: /* 0xf5 */ 7409 /* File: armv6t2/OP_IPUT_QUICK.S */ 7410 /* For: iput-quick, iput-object-quick */ 7411 /* op vA, vB, offset@CCCC */ 7412 mov r2, rINST, lsr #12 @ r2<- B 7413 FETCH(r1, 1) @ r1<- field byte offset 7414 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7415 ubfx r2, rINST, #8, #4 @ r2<- A 7416 cmp r3, #0 @ check object for null 7417 beq common_errNullObject @ object was null 7418 GET_VREG(r0, r2) @ r0<- fp[A] 7419 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7420 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7421 GET_INST_OPCODE(ip) @ extract opcode from rINST 7422 GOTO_OPCODE(ip) @ jump to next instruction 7423 7424 /* ------------------------------ */ 7425 .balign 64 7426 .L_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 7427 /* File: armv6t2/OP_IPUT_WIDE_QUICK.S */ 7428 /* iput-wide-quick vA, vB, offset@CCCC */ 7429 mov r1, rINST, lsr #12 @ r1<- B 7430 ubfx r0, rINST, #8, #4 @ r0<- A 7431 GET_VREG(r2, r1) @ r2<- fp[B], the object pointer 7432 add r3, rFP, r0, lsl #2 @ r3<- &fp[A] 7433 cmp r2, #0 @ check object for null 7434 ldmia r3, {r0-r1} @ r0/r1<- fp[A] 7435 beq common_errNullObject @ object was null 7436 FETCH(r3, 1) @ r3<- field byte offset 7437 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7438 strd r0, [r2, r3] @ obj.field (64 bits, aligned)<- r0/r1 7439 GET_INST_OPCODE(ip) @ extract opcode from rINST 7440 GOTO_OPCODE(ip) @ jump to next instruction 7441 7442 /* ------------------------------ */ 7443 .balign 64 7444 .L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 7445 /* File: armv5te/OP_IPUT_OBJECT_QUICK.S */ 7446 /* For: iput-object-quick */ 7447 /* op vA, vB, offset@CCCC */ 7448 mov r2, rINST, lsr #12 @ r2<- B 7449 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7450 FETCH(r1, 1) @ r1<- field byte offset 7451 cmp r3, #0 @ check object for null 7452 mov r2, rINST, lsr #8 @ r2<- A(+) 7453 beq common_errNullObject @ object was null 7454 and r2, r2, #15 7455 GET_VREG(r0, r2) @ r0<- fp[A] 7456 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 7457 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7458 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7459 cmp r0, #0 7460 strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head 7461 GET_INST_OPCODE(ip) @ extract opcode from rINST 7462 GOTO_OPCODE(ip) @ jump to next instruction 7463 7464 /* ------------------------------ */ 7465 .balign 64 7466 .L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 7467 /* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7468 /* 7469 * Handle an optimized virtual method call. 7470 * 7471 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7472 */ 7473 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7474 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7475 FETCH(r3, 2) @ r3<- FEDC or CCCC 7476 FETCH(r1, 1) @ r1<- BBBB 7477 .if (!0) 7478 and r3, r3, #15 @ r3<- C (or stays CCCC) 7479 .endif 7480 GET_VREG(r9, r3) @ r9<- vC ("this" ptr) 7481 cmp r9, #0 @ is "this" null? 7482 beq common_errNullObject @ null "this", throw exception 7483 ldr r2, [r9, #offObject_clazz] @ r2<- thisPtr->clazz 7484 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7485 EXPORT_PC() @ invoke must export 7486 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7487 bl common_invokeMethodNoRange @ (r0=method, r9="this") 7488 7489 /* ------------------------------ */ 7490 .balign 64 7491 .L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 7492 /* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */ 7493 /* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7494 /* 7495 * Handle an optimized virtual method call. 7496 * 7497 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7498 */ 7499 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7500 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7501 FETCH(r3, 2) @ r3<- FEDC or CCCC 7502 FETCH(r1, 1) @ r1<- BBBB 7503 .if (!1) 7504 and r3, r3, #15 @ r3<- C (or stays CCCC) 7505 .endif 7506 GET_VREG(r9, r3) @ r9<- vC ("this" ptr) 7507 cmp r9, #0 @ is "this" null? 7508 beq common_errNullObject @ null "this", throw exception 7509 ldr r2, [r9, #offObject_clazz] @ r2<- thisPtr->clazz 7510 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7511 EXPORT_PC() @ invoke must export 7512 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7513 bl common_invokeMethodRange @ (r0=method, r9="this") 7514 7515 7516 /* ------------------------------ */ 7517 .balign 64 7518 .L_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 7519 /* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7520 /* 7521 * Handle an optimized "super" method call. 7522 * 7523 * for: [opt] invoke-super-quick, invoke-super-quick/range 7524 */ 7525 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7526 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7527 FETCH(r10, 2) @ r10<- GFED or CCCC 7528 ldr r2, [rSELF, #offThread_method] @ r2<- current method 7529 .if (!0) 7530 and r10, r10, #15 @ r10<- D (or stays CCCC) 7531 .endif 7532 FETCH(r1, 1) @ r1<- BBBB 7533 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7534 EXPORT_PC() @ must export for invoke 7535 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7536 GET_VREG(r9, r10) @ r9<- "this" 7537 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7538 cmp r9, #0 @ null "this" ref? 7539 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7540 beq common_errNullObject @ "this" is null, throw exception 7541 bl common_invokeMethodNoRange @ (r0=method, r9="this") 7542 7543 /* ------------------------------ */ 7544 .balign 64 7545 .L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 7546 /* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */ 7547 /* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7548 /* 7549 * Handle an optimized "super" method call. 7550 * 7551 * for: [opt] invoke-super-quick, invoke-super-quick/range 7552 */ 7553 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7554 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7555 FETCH(r10, 2) @ r10<- GFED or CCCC 7556 ldr r2, [rSELF, #offThread_method] @ r2<- current method 7557 .if (!1) 7558 and r10, r10, #15 @ r10<- D (or stays CCCC) 7559 .endif 7560 FETCH(r1, 1) @ r1<- BBBB 7561 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7562 EXPORT_PC() @ must export for invoke 7563 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7564 GET_VREG(r9, r10) @ r9<- "this" 7565 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7566 cmp r9, #0 @ null "this" ref? 7567 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7568 beq common_errNullObject @ "this" is null, throw exception 7569 bl common_invokeMethodRange @ (r0=method, r9="this") 7570 7571 7572 /* ------------------------------ */ 7573 .balign 64 7574 .L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 7575 /* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */ 7576 /* File: armv5te/OP_IPUT_OBJECT.S */ 7577 /* 7578 * 32-bit instance field put. 7579 * 7580 * for: iput-object, iput-object-volatile 7581 */ 7582 /* op vA, vB, field@CCCC */ 7583 mov r0, rINST, lsr #12 @ r0<- B 7584 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7585 FETCH(r1, 1) @ r1<- field ref CCCC 7586 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7587 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7588 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7589 cmp r0, #0 @ is resolved entry null? 7590 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved 7591 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7592 EXPORT_PC() @ resolve() could throw 7593 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7594 bl dvmResolveInstField @ r0<- resolved InstField ptr 7595 cmp r0, #0 @ success? 7596 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up 7597 b common_exceptionThrown 7598 7599 7600 /* ------------------------------ */ 7601 .balign 64 7602 .L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 7603 /* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */ 7604 /* File: armv5te/OP_SGET.S */ 7605 /* 7606 * General 32-bit SGET handler. 7607 * 7608 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7609 */ 7610 /* op vAA, field@BBBB */ 7611 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7612 FETCH(r1, 1) @ r1<- field ref BBBB 7613 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7614 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7615 cmp r0, #0 @ is resolved entry null? 7616 beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve 7617 .LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0 7618 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7619 SMP_DMB @ acquiring load 7620 mov r2, rINST, lsr #8 @ r2<- AA 7621 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7622 SET_VREG(r1, r2) @ fp[AA]<- r1 7623 GET_INST_OPCODE(ip) @ extract opcode from rINST 7624 GOTO_OPCODE(ip) @ jump to next instruction 7625 7626 7627 /* ------------------------------ */ 7628 .balign 64 7629 .L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 7630 /* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */ 7631 /* File: armv5te/OP_SPUT_OBJECT.S */ 7632 /* 7633 * 32-bit SPUT handler for objects 7634 * 7635 * for: sput-object, sput-object-volatile 7636 */ 7637 /* op vAA, field@BBBB */ 7638 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7639 FETCH(r1, 1) @ r1<- field ref BBBB 7640 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7641 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7642 cmp r0, #0 @ is resolved entry null? 7643 beq .LOP_SPUT_OBJECT_VOLATILE_resolve @ yes, do resolve 7644 .LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0 7645 mov r2, rINST, lsr #8 @ r2<- AA 7646 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7647 GET_VREG(r1, r2) @ r1<- fp[AA] 7648 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 7649 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 7650 GET_INST_OPCODE(ip) @ extract opcode from rINST 7651 SMP_DMB_ST @ releasing store 7652 b .LOP_SPUT_OBJECT_VOLATILE_end 7653 7654 7655 /* ------------------------------ */ 7656 .balign 64 7657 .L_OP_UNUSED_FF: /* 0xff */ 7658 /* File: armv5te/OP_UNUSED_FF.S */ 7659 /* File: armv5te/unused.S */ 7660 bl common_abort 7661 7662 7663 .balign 64 7664 .size dvmAsmInstructionStart, .-dvmAsmInstructionStart 7665 .global dvmAsmInstructionEnd 7666 dvmAsmInstructionEnd: 7667 7668 /* 7669 * =========================================================================== 7670 * Sister implementations 7671 * =========================================================================== 7672 */ 7673 .global dvmAsmSisterStart 7674 .type dvmAsmSisterStart, %function 7675 .text 7676 .balign 4 7677 dvmAsmSisterStart: 7678 7679 /* continuation for OP_CONST_STRING */ 7680 7681 /* 7682 * Continuation if the String has not yet been resolved. 7683 * r1: BBBB (String ref) 7684 * r9: target register 7685 */ 7686 .LOP_CONST_STRING_resolve: 7687 EXPORT_PC() 7688 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7689 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7690 bl dvmResolveString @ r0<- String reference 7691 cmp r0, #0 @ failed? 7692 beq common_exceptionThrown @ yup, handle the exception 7693 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7694 GET_INST_OPCODE(ip) @ extract opcode from rINST 7695 SET_VREG(r0, r9) @ vAA<- r0 7696 GOTO_OPCODE(ip) @ jump to next instruction 7697 7698 /* continuation for OP_CONST_STRING_JUMBO */ 7699 7700 /* 7701 * Continuation if the String has not yet been resolved. 7702 * r1: BBBBBBBB (String ref) 7703 * r9: target register 7704 */ 7705 .LOP_CONST_STRING_JUMBO_resolve: 7706 EXPORT_PC() 7707 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7708 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7709 bl dvmResolveString @ r0<- String reference 7710 cmp r0, #0 @ failed? 7711 beq common_exceptionThrown @ yup, handle the exception 7712 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7713 GET_INST_OPCODE(ip) @ extract opcode from rINST 7714 SET_VREG(r0, r9) @ vAA<- r0 7715 GOTO_OPCODE(ip) @ jump to next instruction 7716 7717 /* continuation for OP_CONST_CLASS */ 7718 7719 /* 7720 * Continuation if the Class has not yet been resolved. 7721 * r1: BBBB (Class ref) 7722 * r9: target register 7723 */ 7724 .LOP_CONST_CLASS_resolve: 7725 EXPORT_PC() 7726 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7727 mov r2, #1 @ r2<- true 7728 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7729 bl dvmResolveClass @ r0<- Class reference 7730 cmp r0, #0 @ failed? 7731 beq common_exceptionThrown @ yup, handle the exception 7732 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7733 GET_INST_OPCODE(ip) @ extract opcode from rINST 7734 SET_VREG(r0, r9) @ vAA<- r0 7735 GOTO_OPCODE(ip) @ jump to next instruction 7736 7737 /* continuation for OP_CHECK_CAST */ 7738 7739 /* 7740 * Trivial test failed, need to perform full check. This is common. 7741 * r0 holds obj->clazz 7742 * r1 holds desired class resolved from BBBB 7743 * r9 holds object 7744 */ 7745 .LOP_CHECK_CAST_fullcheck: 7746 mov r10, r1 @ avoid ClassObject getting clobbered 7747 bl dvmInstanceofNonTrivial @ r0<- boolean result 7748 cmp r0, #0 @ failed? 7749 bne .LOP_CHECK_CAST_okay @ no, success 7750 7751 @ A cast has failed. We need to throw a ClassCastException. 7752 EXPORT_PC() @ about to throw 7753 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 7754 mov r1, r10 @ r1<- desired class 7755 bl dvmThrowClassCastException 7756 b common_exceptionThrown 7757 7758 /* 7759 * Resolution required. This is the least-likely path. 7760 * 7761 * r2 holds BBBB 7762 * r9 holds object 7763 */ 7764 .LOP_CHECK_CAST_resolve: 7765 EXPORT_PC() @ resolve() could throw 7766 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 7767 mov r1, r2 @ r1<- BBBB 7768 mov r2, #0 @ r2<- false 7769 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7770 bl dvmResolveClass @ r0<- resolved ClassObject ptr 7771 cmp r0, #0 @ got null? 7772 beq common_exceptionThrown @ yes, handle exception 7773 mov r1, r0 @ r1<- class resolved from BBB 7774 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 7775 b .LOP_CHECK_CAST_resolved @ pick up where we left off 7776 7777 /* continuation for OP_INSTANCE_OF */ 7778 7779 /* 7780 * Trivial test failed, need to perform full check. This is common. 7781 * r0 holds obj->clazz 7782 * r1 holds class resolved from BBBB 7783 * r9 holds A 7784 */ 7785 .LOP_INSTANCE_OF_fullcheck: 7786 bl dvmInstanceofNonTrivial @ r0<- boolean result 7787 @ fall through to OP_INSTANCE_OF_store 7788 7789 /* 7790 * r0 holds boolean result 7791 * r9 holds A 7792 */ 7793 .LOP_INSTANCE_OF_store: 7794 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7795 SET_VREG(r0, r9) @ vA<- r0 7796 GET_INST_OPCODE(ip) @ extract opcode from rINST 7797 GOTO_OPCODE(ip) @ jump to next instruction 7798 7799 /* 7800 * Trivial test succeeded, save and bail. 7801 * r9 holds A 7802 */ 7803 .LOP_INSTANCE_OF_trivial: 7804 mov r0, #1 @ indicate success 7805 @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper 7806 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7807 SET_VREG(r0, r9) @ vA<- r0 7808 GET_INST_OPCODE(ip) @ extract opcode from rINST 7809 GOTO_OPCODE(ip) @ jump to next instruction 7810 7811 /* 7812 * Resolution required. This is the least-likely path. 7813 * 7814 * r3 holds BBBB 7815 * r9 holds A 7816 */ 7817 .LOP_INSTANCE_OF_resolve: 7818 EXPORT_PC() @ resolve() could throw 7819 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7820 mov r1, r3 @ r1<- BBBB 7821 mov r2, #1 @ r2<- true 7822 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7823 bl dvmResolveClass @ r0<- resolved ClassObject ptr 7824 cmp r0, #0 @ got null? 7825 beq common_exceptionThrown @ yes, handle exception 7826 mov r1, r0 @ r1<- class resolved from BBB 7827 mov r3, rINST, lsr #12 @ r3<- B 7828 GET_VREG(r0, r3) @ r0<- vB (object) 7829 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 7830 b .LOP_INSTANCE_OF_resolved @ pick up where we left off 7831 7832 /* continuation for OP_NEW_INSTANCE */ 7833 7834 .balign 32 @ minimize cache lines 7835 .LOP_NEW_INSTANCE_finish: @ r0=new object 7836 mov r3, rINST, lsr #8 @ r3<- AA 7837 cmp r0, #0 @ failed? 7838 #if defined(WITH_JIT) 7839 /* 7840 * The JIT needs the class to be fully resolved before it can 7841 * include this instruction in a trace. 7842 */ 7843 ldrh r1, [rSELF, #offThread_subMode] 7844 beq common_exceptionThrown @ yes, handle the exception 7845 ands r1, #kSubModeJitTraceBuild @ under construction? 7846 bne .LOP_NEW_INSTANCE_jitCheck 7847 #else 7848 beq common_exceptionThrown @ yes, handle the exception 7849 #endif 7850 .LOP_NEW_INSTANCE_end: 7851 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7852 GET_INST_OPCODE(ip) @ extract opcode from rINST 7853 SET_VREG(r0, r3) @ vAA<- r0 7854 GOTO_OPCODE(ip) @ jump to next instruction 7855 7856 #if defined(WITH_JIT) 7857 /* 7858 * Check to see if we need to stop the trace building early. 7859 * r0: new object 7860 * r3: vAA 7861 */ 7862 .LOP_NEW_INSTANCE_jitCheck: 7863 ldr r1, [r10] @ reload resolved class 7864 cmp r1, #0 @ okay? 7865 bne .LOP_NEW_INSTANCE_end @ yes, finish 7866 mov r9, r0 @ preserve new object 7867 mov r10, r3 @ preserve vAA 7868 mov r0, rSELF 7869 mov r1, rPC 7870 bl dvmJitEndTraceSelect @ (self, pc) 7871 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7872 GET_INST_OPCODE(ip) @ extract opcode from rINST 7873 SET_VREG(r9, r10) @ vAA<- new object 7874 GOTO_OPCODE(ip) @ jump to next instruction 7875 #endif 7876 7877 /* 7878 * Class initialization required. 7879 * 7880 * r0 holds class object 7881 */ 7882 .LOP_NEW_INSTANCE_needinit: 7883 mov r9, r0 @ save r0 7884 bl dvmInitClass @ initialize class 7885 cmp r0, #0 @ check boolean result 7886 mov r0, r9 @ restore r0 7887 bne .LOP_NEW_INSTANCE_initialized @ success, continue 7888 b common_exceptionThrown @ failed, deal with init exception 7889 7890 /* 7891 * Resolution required. This is the least-likely path. 7892 * 7893 * r1 holds BBBB 7894 */ 7895 .LOP_NEW_INSTANCE_resolve: 7896 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 7897 mov r2, #0 @ r2<- false 7898 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7899 bl dvmResolveClass @ r0<- resolved ClassObject ptr 7900 cmp r0, #0 @ got null? 7901 bne .LOP_NEW_INSTANCE_resolved @ no, continue 7902 b common_exceptionThrown @ yes, handle exception 7903 7904 /* continuation for OP_NEW_ARRAY */ 7905 7906 7907 /* 7908 * Resolve class. (This is an uncommon case.) 7909 * 7910 * r1 holds array length 7911 * r2 holds class ref CCCC 7912 */ 7913 .LOP_NEW_ARRAY_resolve: 7914 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 7915 mov r9, r1 @ r9<- length (save) 7916 mov r1, r2 @ r1<- CCCC 7917 mov r2, #0 @ r2<- false 7918 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7919 bl dvmResolveClass @ r0<- call(clazz, ref) 7920 cmp r0, #0 @ got null? 7921 mov r1, r9 @ r1<- length (restore) 7922 beq common_exceptionThrown @ yes, handle exception 7923 @ fall through to OP_NEW_ARRAY_finish 7924 7925 /* 7926 * Finish allocation. 7927 * 7928 * r0 holds class 7929 * r1 holds array length 7930 */ 7931 .LOP_NEW_ARRAY_finish: 7932 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 7933 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 7934 cmp r0, #0 @ failed? 7935 mov r2, rINST, lsr #8 @ r2<- A+ 7936 beq common_exceptionThrown @ yes, handle the exception 7937 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7938 and r2, r2, #15 @ r2<- A 7939 GET_INST_OPCODE(ip) @ extract opcode from rINST 7940 SET_VREG(r0, r2) @ vA<- r0 7941 GOTO_OPCODE(ip) @ jump to next instruction 7942 7943 /* continuation for OP_FILLED_NEW_ARRAY */ 7944 7945 /* 7946 * On entry: 7947 * r0 holds array class 7948 * r10 holds AA or BA 7949 */ 7950 .LOP_FILLED_NEW_ARRAY_continue: 7951 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 7952 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 7953 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 7954 .if 0 7955 mov r1, r10 @ r1<- AA (length) 7956 .else 7957 mov r1, r10, lsr #4 @ r1<- B (length) 7958 .endif 7959 cmp rINST, #'I' @ array of ints? 7960 cmpne rINST, #'L' @ array of objects? 7961 cmpne rINST, #'[' @ array of arrays? 7962 mov r9, r1 @ save length in r9 7963 bne .LOP_FILLED_NEW_ARRAY_notimpl @ no, not handled yet 7964 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 7965 cmp r0, #0 @ null return? 7966 beq common_exceptionThrown @ alloc failed, handle exception 7967 7968 FETCH(r1, 2) @ r1<- FEDC or CCCC 7969 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 7970 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 7971 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 7972 subs r9, r9, #1 @ length--, check for neg 7973 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 7974 bmi 2f @ was zero, bail 7975 7976 @ copy values from registers into the array 7977 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 7978 .if 0 7979 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 7980 1: ldr r3, [r2], #4 @ r3<- *r2++ 7981 subs r9, r9, #1 @ count-- 7982 str r3, [r0], #4 @ *contents++ = vX 7983 bpl 1b 7984 @ continue at 2 7985 .else 7986 cmp r9, #4 @ length was initially 5? 7987 and r2, r10, #15 @ r2<- A 7988 bne 1f @ <= 4 args, branch 7989 GET_VREG(r3, r2) @ r3<- vA 7990 sub r9, r9, #1 @ count-- 7991 str r3, [r0, #16] @ contents[4] = vA 7992 1: and r2, r1, #15 @ r2<- F/E/D/C 7993 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 7994 mov r1, r1, lsr #4 @ r1<- next reg in low 4 7995 subs r9, r9, #1 @ count-- 7996 str r3, [r0], #4 @ *contents++ = vX 7997 bpl 1b 7998 @ continue at 2 7999 .endif 8000 8001 2: 8002 ldr r0, [rSELF, #offThread_retval] @ r0<- object 8003 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 8004 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8005 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 8006 cmp r1, #'I' @ Is int array? 8007 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 8008 GOTO_OPCODE(ip) @ execute it 8009 8010 /* 8011 * Throw an exception indicating that we have not implemented this 8012 * mode of filled-new-array. 8013 */ 8014 .LOP_FILLED_NEW_ARRAY_notimpl: 8015 ldr r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY 8016 bl dvmThrowInternalError 8017 b common_exceptionThrown 8018 8019 /* 8020 * Ideally we'd only define this once, but depending on layout we can 8021 * exceed the range of the load above. 8022 */ 8023 8024 .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY: 8025 .word .LstrFilledNewArrayNotImpl 8026 8027 /* continuation for OP_FILLED_NEW_ARRAY_RANGE */ 8028 8029 /* 8030 * On entry: 8031 * r0 holds array class 8032 * r10 holds AA or BA 8033 */ 8034 .LOP_FILLED_NEW_ARRAY_RANGE_continue: 8035 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 8036 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 8037 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 8038 .if 1 8039 mov r1, r10 @ r1<- AA (length) 8040 .else 8041 mov r1, r10, lsr #4 @ r1<- B (length) 8042 .endif 8043 cmp rINST, #'I' @ array of ints? 8044 cmpne rINST, #'L' @ array of objects? 8045 cmpne rINST, #'[' @ array of arrays? 8046 mov r9, r1 @ save length in r9 8047 bne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl @ no, not handled yet 8048 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 8049 cmp r0, #0 @ null return? 8050 beq common_exceptionThrown @ alloc failed, handle exception 8051 8052 FETCH(r1, 2) @ r1<- FEDC or CCCC 8053 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 8054 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 8055 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 8056 subs r9, r9, #1 @ length--, check for neg 8057 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 8058 bmi 2f @ was zero, bail 8059 8060 @ copy values from registers into the array 8061 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 8062 .if 1 8063 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 8064 1: ldr r3, [r2], #4 @ r3<- *r2++ 8065 subs r9, r9, #1 @ count-- 8066 str r3, [r0], #4 @ *contents++ = vX 8067 bpl 1b 8068 @ continue at 2 8069 .else 8070 cmp r9, #4 @ length was initially 5? 8071 and r2, r10, #15 @ r2<- A 8072 bne 1f @ <= 4 args, branch 8073 GET_VREG(r3, r2) @ r3<- vA 8074 sub r9, r9, #1 @ count-- 8075 str r3, [r0, #16] @ contents[4] = vA 8076 1: and r2, r1, #15 @ r2<- F/E/D/C 8077 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 8078 mov r1, r1, lsr #4 @ r1<- next reg in low 4 8079 subs r9, r9, #1 @ count-- 8080 str r3, [r0], #4 @ *contents++ = vX 8081 bpl 1b 8082 @ continue at 2 8083 .endif 8084 8085 2: 8086 ldr r0, [rSELF, #offThread_retval] @ r0<- object 8087 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 8088 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8089 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 8090 cmp r1, #'I' @ Is int array? 8091 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 8092 GOTO_OPCODE(ip) @ execute it 8093 8094 /* 8095 * Throw an exception indicating that we have not implemented this 8096 * mode of filled-new-array. 8097 */ 8098 .LOP_FILLED_NEW_ARRAY_RANGE_notimpl: 8099 ldr r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE 8100 bl dvmThrowInternalError 8101 b common_exceptionThrown 8102 8103 /* 8104 * Ideally we'd only define this once, but depending on layout we can 8105 * exceed the range of the load above. 8106 */ 8107 8108 .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE: 8109 .word .LstrFilledNewArrayNotImpl 8110 8111 /* continuation for OP_CMPL_FLOAT */ 8112 .LOP_CMPL_FLOAT_finish: 8113 SET_VREG(r0, r9) @ vAA<- r0 8114 GOTO_OPCODE(ip) @ jump to next instruction 8115 8116 /* continuation for OP_CMPG_FLOAT */ 8117 .LOP_CMPG_FLOAT_finish: 8118 SET_VREG(r0, r9) @ vAA<- r0 8119 GOTO_OPCODE(ip) @ jump to next instruction 8120 8121 /* continuation for OP_CMPL_DOUBLE */ 8122 .LOP_CMPL_DOUBLE_finish: 8123 SET_VREG(r0, r9) @ vAA<- r0 8124 GOTO_OPCODE(ip) @ jump to next instruction 8125 8126 /* continuation for OP_CMPG_DOUBLE */ 8127 .LOP_CMPG_DOUBLE_finish: 8128 SET_VREG(r0, r9) @ vAA<- r0 8129 GOTO_OPCODE(ip) @ jump to next instruction 8130 8131 /* continuation for OP_CMP_LONG */ 8132 8133 .LOP_CMP_LONG_less: 8134 mvn r1, #0 @ r1<- -1 8135 @ Want to cond code the next mov so we can avoid branch, but don't see it; 8136 @ instead, we just replicate the tail end. 8137 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8138 SET_VREG(r1, r9) @ vAA<- r1 8139 GET_INST_OPCODE(ip) @ extract opcode from rINST 8140 GOTO_OPCODE(ip) @ jump to next instruction 8141 8142 .LOP_CMP_LONG_greater: 8143 mov r1, #1 @ r1<- 1 8144 @ fall through to _finish 8145 8146 .LOP_CMP_LONG_finish: 8147 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8148 SET_VREG(r1, r9) @ vAA<- r1 8149 GET_INST_OPCODE(ip) @ extract opcode from rINST 8150 GOTO_OPCODE(ip) @ jump to next instruction 8151 8152 /* continuation for OP_AGET_WIDE */ 8153 8154 .LOP_AGET_WIDE_finish: 8155 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8156 ldrd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 8157 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 8158 GET_INST_OPCODE(ip) @ extract opcode from rINST 8159 stmia r9, {r2-r3} @ vAA/vAA+1<- r2/r3 8160 GOTO_OPCODE(ip) @ jump to next instruction 8161 8162 /* continuation for OP_APUT_WIDE */ 8163 8164 .LOP_APUT_WIDE_finish: 8165 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8166 ldmia r9, {r2-r3} @ r2/r3<- vAA/vAA+1 8167 GET_INST_OPCODE(ip) @ extract opcode from rINST 8168 strd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 8169 GOTO_OPCODE(ip) @ jump to next instruction 8170 8171 /* continuation for OP_APUT_OBJECT */ 8172 /* 8173 * On entry: 8174 * rINST = vBB (arrayObj) 8175 * r9 = vAA (obj) 8176 * r10 = offset into array (vBB + vCC * width) 8177 */ 8178 .LOP_APUT_OBJECT_finish: 8179 cmp r9, #0 @ storing null reference? 8180 beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks 8181 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 8182 ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz 8183 bl dvmCanPutArrayElement @ test object type vs. array type 8184 cmp r0, #0 @ okay? 8185 beq .LOP_APUT_OBJECT_throw @ no 8186 mov r1, rINST @ r1<- arrayObj 8187 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8188 ldr r2, [rSELF, #offThread_cardTable] @ get biased CT base 8189 add r10, #offArrayObject_contents @ r0<- pointer to slot 8190 GET_INST_OPCODE(ip) @ extract opcode from rINST 8191 str r9, [r10] @ vBB[vCC]<- vAA 8192 strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head 8193 GOTO_OPCODE(ip) @ jump to next instruction 8194 .LOP_APUT_OBJECT_skip_check: 8195 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8196 GET_INST_OPCODE(ip) @ extract opcode from rINST 8197 str r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA 8198 GOTO_OPCODE(ip) @ jump to next instruction 8199 .LOP_APUT_OBJECT_throw: 8200 @ The types don't match. We need to throw an ArrayStoreException. 8201 ldr r0, [r9, #offObject_clazz] 8202 ldr r1, [rINST, #offObject_clazz] 8203 EXPORT_PC() 8204 bl dvmThrowArrayStoreExceptionIncompatibleElement 8205 b common_exceptionThrown 8206 8207 /* continuation for OP_IGET */ 8208 8209 /* 8210 * Currently: 8211 * r0 holds resolved field 8212 * r9 holds object 8213 */ 8214 .LOP_IGET_finish: 8215 @bl common_squeak0 8216 cmp r9, #0 @ check object for null 8217 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8218 beq common_errNullObject @ object was null 8219 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8220 ubfx r2, rINST, #8, #4 @ r2<- A 8221 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8222 GET_INST_OPCODE(ip) @ extract opcode from rINST 8223 SET_VREG(r0, r2) @ fp[A]<- r0 8224 GOTO_OPCODE(ip) @ jump to next instruction 8225 8226 /* continuation for OP_IGET_WIDE */ 8227 8228 /* 8229 * Currently: 8230 * r0 holds resolved field 8231 * r9 holds object 8232 */ 8233 .LOP_IGET_WIDE_finish: 8234 cmp r9, #0 @ check object for null 8235 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8236 beq common_errNullObject @ object was null 8237 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 8238 ubfx r2, rINST, #8, #4 @ r2<- A 8239 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8240 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 8241 GET_INST_OPCODE(ip) @ extract opcode from rINST 8242 stmia r3, {r0-r1} @ fp[A]<- r0/r1 8243 GOTO_OPCODE(ip) @ jump to next instruction 8244 8245 /* continuation for OP_IGET_OBJECT */ 8246 8247 /* 8248 * Currently: 8249 * r0 holds resolved field 8250 * r9 holds object 8251 */ 8252 .LOP_IGET_OBJECT_finish: 8253 @bl common_squeak0 8254 cmp r9, #0 @ check object for null 8255 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8256 beq common_errNullObject @ object was null 8257 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8258 @ no-op @ acquiring load 8259 mov r2, rINST, lsr #8 @ r2<- A+ 8260 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8261 and r2, r2, #15 @ r2<- A 8262 GET_INST_OPCODE(ip) @ extract opcode from rINST 8263 SET_VREG(r0, r2) @ fp[A]<- r0 8264 GOTO_OPCODE(ip) @ jump to next instruction 8265 8266 /* continuation for OP_IGET_BOOLEAN */ 8267 8268 /* 8269 * Currently: 8270 * r0 holds resolved field 8271 * r9 holds object 8272 */ 8273 .LOP_IGET_BOOLEAN_finish: 8274 @bl common_squeak1 8275 cmp r9, #0 @ check object for null 8276 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8277 beq common_errNullObject @ object was null 8278 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8279 @ no-op @ acquiring load 8280 mov r2, rINST, lsr #8 @ r2<- A+ 8281 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8282 and r2, r2, #15 @ r2<- A 8283 GET_INST_OPCODE(ip) @ extract opcode from rINST 8284 SET_VREG(r0, r2) @ fp[A]<- r0 8285 GOTO_OPCODE(ip) @ jump to next instruction 8286 8287 /* continuation for OP_IGET_BYTE */ 8288 8289 /* 8290 * Currently: 8291 * r0 holds resolved field 8292 * r9 holds object 8293 */ 8294 .LOP_IGET_BYTE_finish: 8295 @bl common_squeak2 8296 cmp r9, #0 @ check object for null 8297 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8298 beq common_errNullObject @ object was null 8299 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8300 @ no-op @ acquiring load 8301 mov r2, rINST, lsr #8 @ r2<- A+ 8302 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8303 and r2, r2, #15 @ r2<- A 8304 GET_INST_OPCODE(ip) @ extract opcode from rINST 8305 SET_VREG(r0, r2) @ fp[A]<- r0 8306 GOTO_OPCODE(ip) @ jump to next instruction 8307 8308 /* continuation for OP_IGET_CHAR */ 8309 8310 /* 8311 * Currently: 8312 * r0 holds resolved field 8313 * r9 holds object 8314 */ 8315 .LOP_IGET_CHAR_finish: 8316 @bl common_squeak3 8317 cmp r9, #0 @ check object for null 8318 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8319 beq common_errNullObject @ object was null 8320 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8321 @ no-op @ acquiring load 8322 mov r2, rINST, lsr #8 @ r2<- A+ 8323 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8324 and r2, r2, #15 @ r2<- A 8325 GET_INST_OPCODE(ip) @ extract opcode from rINST 8326 SET_VREG(r0, r2) @ fp[A]<- r0 8327 GOTO_OPCODE(ip) @ jump to next instruction 8328 8329 /* continuation for OP_IGET_SHORT */ 8330 8331 /* 8332 * Currently: 8333 * r0 holds resolved field 8334 * r9 holds object 8335 */ 8336 .LOP_IGET_SHORT_finish: 8337 @bl common_squeak4 8338 cmp r9, #0 @ check object for null 8339 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8340 beq common_errNullObject @ object was null 8341 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8342 @ no-op @ acquiring load 8343 mov r2, rINST, lsr #8 @ r2<- A+ 8344 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8345 and r2, r2, #15 @ r2<- A 8346 GET_INST_OPCODE(ip) @ extract opcode from rINST 8347 SET_VREG(r0, r2) @ fp[A]<- r0 8348 GOTO_OPCODE(ip) @ jump to next instruction 8349 8350 /* continuation for OP_IPUT */ 8351 8352 /* 8353 * Currently: 8354 * r0 holds resolved field 8355 * r9 holds object 8356 */ 8357 .LOP_IPUT_finish: 8358 @bl common_squeak0 8359 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8360 ubfx r1, rINST, #8, #4 @ r1<- A 8361 cmp r9, #0 @ check object for null 8362 GET_VREG(r0, r1) @ r0<- fp[A] 8363 beq common_errNullObject @ object was null 8364 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8365 GET_INST_OPCODE(ip) @ extract opcode from rINST 8366 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8367 GOTO_OPCODE(ip) @ jump to next instruction 8368 8369 /* continuation for OP_IPUT_WIDE */ 8370 8371 /* 8372 * Currently: 8373 * r0 holds resolved field 8374 * r9 holds object 8375 */ 8376 .LOP_IPUT_WIDE_finish: 8377 ubfx r2, rINST, #8, #4 @ r2<- A 8378 cmp r9, #0 @ check object for null 8379 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8380 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 8381 beq common_errNullObject @ object was null 8382 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8383 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 8384 GET_INST_OPCODE(ip) @ extract opcode from rINST 8385 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0 8386 GOTO_OPCODE(ip) @ jump to next instruction 8387 8388 /* continuation for OP_IPUT_OBJECT */ 8389 8390 /* 8391 * Currently: 8392 * r0 holds resolved field 8393 * r9 holds object 8394 */ 8395 .LOP_IPUT_OBJECT_finish: 8396 @bl common_squeak0 8397 mov r1, rINST, lsr #8 @ r1<- A+ 8398 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8399 and r1, r1, #15 @ r1<- A 8400 cmp r9, #0 @ check object for null 8401 GET_VREG(r0, r1) @ r0<- fp[A] 8402 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8403 beq common_errNullObject @ object was null 8404 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8405 GET_INST_OPCODE(ip) @ extract opcode from rINST 8406 @ no-op @ releasing store 8407 str r0, [r9, r3] @ obj.field (32 bits)<- r0 8408 @ no-op 8409 cmp r0, #0 @ stored a null reference? 8410 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 8411 GOTO_OPCODE(ip) @ jump to next instruction 8412 8413 /* continuation for OP_IPUT_BOOLEAN */ 8414 8415 /* 8416 * Currently: 8417 * r0 holds resolved field 8418 * r9 holds object 8419 */ 8420 .LOP_IPUT_BOOLEAN_finish: 8421 @bl common_squeak1 8422 mov r1, rINST, lsr #8 @ r1<- A+ 8423 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8424 and r1, r1, #15 @ r1<- A 8425 cmp r9, #0 @ check object for null 8426 GET_VREG(r0, r1) @ r0<- fp[A] 8427 beq common_errNullObject @ object was null 8428 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8429 GET_INST_OPCODE(ip) @ extract opcode from rINST 8430 @ no-op @ releasing store 8431 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8432 @ no-op 8433 GOTO_OPCODE(ip) @ jump to next instruction 8434 8435 /* continuation for OP_IPUT_BYTE */ 8436 8437 /* 8438 * Currently: 8439 * r0 holds resolved field 8440 * r9 holds object 8441 */ 8442 .LOP_IPUT_BYTE_finish: 8443 @bl common_squeak2 8444 mov r1, rINST, lsr #8 @ r1<- A+ 8445 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8446 and r1, r1, #15 @ r1<- A 8447 cmp r9, #0 @ check object for null 8448 GET_VREG(r0, r1) @ r0<- fp[A] 8449 beq common_errNullObject @ object was null 8450 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8451 GET_INST_OPCODE(ip) @ extract opcode from rINST 8452 @ no-op @ releasing store 8453 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8454 @ no-op 8455 GOTO_OPCODE(ip) @ jump to next instruction 8456 8457 /* continuation for OP_IPUT_CHAR */ 8458 8459 /* 8460 * Currently: 8461 * r0 holds resolved field 8462 * r9 holds object 8463 */ 8464 .LOP_IPUT_CHAR_finish: 8465 @bl common_squeak3 8466 mov r1, rINST, lsr #8 @ r1<- A+ 8467 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8468 and r1, r1, #15 @ r1<- A 8469 cmp r9, #0 @ check object for null 8470 GET_VREG(r0, r1) @ r0<- fp[A] 8471 beq common_errNullObject @ object was null 8472 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8473 GET_INST_OPCODE(ip) @ extract opcode from rINST 8474 @ no-op @ releasing store 8475 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8476 @ no-op 8477 GOTO_OPCODE(ip) @ jump to next instruction 8478 8479 /* continuation for OP_IPUT_SHORT */ 8480 8481 /* 8482 * Currently: 8483 * r0 holds resolved field 8484 * r9 holds object 8485 */ 8486 .LOP_IPUT_SHORT_finish: 8487 @bl common_squeak4 8488 mov r1, rINST, lsr #8 @ r1<- A+ 8489 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8490 and r1, r1, #15 @ r1<- A 8491 cmp r9, #0 @ check object for null 8492 GET_VREG(r0, r1) @ r0<- fp[A] 8493 beq common_errNullObject @ object was null 8494 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8495 GET_INST_OPCODE(ip) @ extract opcode from rINST 8496 @ no-op @ releasing store 8497 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8498 @ no-op 8499 GOTO_OPCODE(ip) @ jump to next instruction 8500 8501 /* continuation for OP_SGET */ 8502 8503 /* 8504 * Continuation if the field has not yet been resolved. 8505 * r1: BBBB field ref 8506 * r10: dvmDex->pResFields 8507 */ 8508 .LOP_SGET_resolve: 8509 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8510 #if defined(WITH_JIT) 8511 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8512 #endif 8513 EXPORT_PC() @ resolve() could throw, so export now 8514 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8515 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8516 cmp r0, #0 @ success? 8517 beq common_exceptionThrown @ no, handle exception 8518 #if defined(WITH_JIT) 8519 /* 8520 * If the JIT is actively building a trace we need to make sure 8521 * that the field is fully resolved before including this instruction. 8522 */ 8523 bl common_verifyField 8524 #endif 8525 b .LOP_SGET_finish 8526 8527 /* continuation for OP_SGET_WIDE */ 8528 8529 /* 8530 * Continuation if the field has not yet been resolved. 8531 * r1: BBBB field ref 8532 * r10: dvmDex->pResFields 8533 * 8534 * Returns StaticField pointer in r0. 8535 */ 8536 .LOP_SGET_WIDE_resolve: 8537 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8538 #if defined(WITH_JIT) 8539 add r10, r10, r1, lsl #2 @ r1<- &dvmDex->pResFields[field] 8540 #endif 8541 EXPORT_PC() @ resolve() could throw, so export now 8542 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8543 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8544 cmp r0, #0 @ success? 8545 beq common_exceptionThrown @ no, handle exception 8546 #if defined(WITH_JIT) 8547 /* 8548 * If the JIT is actively building a trace we need to make sure 8549 * that the field is fully resolved before including this instruction. 8550 */ 8551 bl common_verifyField 8552 #endif 8553 b .LOP_SGET_WIDE_finish @ resume 8554 8555 /* continuation for OP_SGET_OBJECT */ 8556 8557 /* 8558 * Continuation if the field has not yet been resolved. 8559 * r1: BBBB field ref 8560 * r10: dvmDex->pResFields 8561 */ 8562 .LOP_SGET_OBJECT_resolve: 8563 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8564 #if defined(WITH_JIT) 8565 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8566 #endif 8567 EXPORT_PC() @ resolve() could throw, so export now 8568 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8569 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8570 cmp r0, #0 @ success? 8571 beq common_exceptionThrown @ no, handle exception 8572 #if defined(WITH_JIT) 8573 /* 8574 * If the JIT is actively building a trace we need to make sure 8575 * that the field is fully resolved before including this instruction. 8576 */ 8577 bl common_verifyField 8578 #endif 8579 b .LOP_SGET_OBJECT_finish 8580 8581 /* continuation for OP_SGET_BOOLEAN */ 8582 8583 /* 8584 * Continuation if the field has not yet been resolved. 8585 * r1: BBBB field ref 8586 * r10: dvmDex->pResFields 8587 */ 8588 .LOP_SGET_BOOLEAN_resolve: 8589 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8590 #if defined(WITH_JIT) 8591 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8592 #endif 8593 EXPORT_PC() @ resolve() could throw, so export now 8594 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8595 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8596 cmp r0, #0 @ success? 8597 beq common_exceptionThrown @ no, handle exception 8598 #if defined(WITH_JIT) 8599 /* 8600 * If the JIT is actively building a trace we need to make sure 8601 * that the field is fully resolved before including this instruction. 8602 */ 8603 bl common_verifyField 8604 #endif 8605 b .LOP_SGET_BOOLEAN_finish 8606 8607 /* continuation for OP_SGET_BYTE */ 8608 8609 /* 8610 * Continuation if the field has not yet been resolved. 8611 * r1: BBBB field ref 8612 * r10: dvmDex->pResFields 8613 */ 8614 .LOP_SGET_BYTE_resolve: 8615 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8616 #if defined(WITH_JIT) 8617 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8618 #endif 8619 EXPORT_PC() @ resolve() could throw, so export now 8620 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8621 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8622 cmp r0, #0 @ success? 8623 beq common_exceptionThrown @ no, handle exception 8624 #if defined(WITH_JIT) 8625 /* 8626 * If the JIT is actively building a trace we need to make sure 8627 * that the field is fully resolved before including this instruction. 8628 */ 8629 bl common_verifyField 8630 #endif 8631 b .LOP_SGET_BYTE_finish 8632 8633 /* continuation for OP_SGET_CHAR */ 8634 8635 /* 8636 * Continuation if the field has not yet been resolved. 8637 * r1: BBBB field ref 8638 * r10: dvmDex->pResFields 8639 */ 8640 .LOP_SGET_CHAR_resolve: 8641 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8642 #if defined(WITH_JIT) 8643 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8644 #endif 8645 EXPORT_PC() @ resolve() could throw, so export now 8646 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8647 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8648 cmp r0, #0 @ success? 8649 beq common_exceptionThrown @ no, handle exception 8650 #if defined(WITH_JIT) 8651 /* 8652 * If the JIT is actively building a trace we need to make sure 8653 * that the field is fully resolved before including this instruction. 8654 */ 8655 bl common_verifyField 8656 #endif 8657 b .LOP_SGET_CHAR_finish 8658 8659 /* continuation for OP_SGET_SHORT */ 8660 8661 /* 8662 * Continuation if the field has not yet been resolved. 8663 * r1: BBBB field ref 8664 * r10: dvmDex->pResFields 8665 */ 8666 .LOP_SGET_SHORT_resolve: 8667 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8668 #if defined(WITH_JIT) 8669 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8670 #endif 8671 EXPORT_PC() @ resolve() could throw, so export now 8672 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8673 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8674 cmp r0, #0 @ success? 8675 beq common_exceptionThrown @ no, handle exception 8676 #if defined(WITH_JIT) 8677 /* 8678 * If the JIT is actively building a trace we need to make sure 8679 * that the field is fully resolved before including this instruction. 8680 */ 8681 bl common_verifyField 8682 #endif 8683 b .LOP_SGET_SHORT_finish 8684 8685 /* continuation for OP_SPUT */ 8686 8687 /* 8688 * Continuation if the field has not yet been resolved. 8689 * r1: BBBB field ref 8690 * r10: dvmDex->pResFields 8691 */ 8692 .LOP_SPUT_resolve: 8693 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8694 #if defined(WITH_JIT) 8695 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8696 #endif 8697 EXPORT_PC() @ resolve() could throw, so export now 8698 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8699 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8700 cmp r0, #0 @ success? 8701 beq common_exceptionThrown @ no, handle exception 8702 #if defined(WITH_JIT) 8703 /* 8704 * If the JIT is actively building a trace we need to make sure 8705 * that the field is fully resolved before including this instruction. 8706 */ 8707 bl common_verifyField 8708 #endif 8709 b .LOP_SPUT_finish @ resume 8710 8711 /* continuation for OP_SPUT_WIDE */ 8712 8713 /* 8714 * Continuation if the field has not yet been resolved. 8715 * r1: BBBB field ref 8716 * r9: &fp[AA] 8717 * r10: dvmDex->pResFields 8718 * 8719 * Returns StaticField pointer in r2. 8720 */ 8721 .LOP_SPUT_WIDE_resolve: 8722 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8723 #if defined(WITH_JIT) 8724 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8725 #endif 8726 EXPORT_PC() @ resolve() could throw, so export now 8727 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8728 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8729 cmp r0, #0 @ success? 8730 mov r2, r0 @ copy to r2 8731 beq common_exceptionThrown @ no, handle exception 8732 #if defined(WITH_JIT) 8733 /* 8734 * If the JIT is actively building a trace we need to make sure 8735 * that the field is fully resolved before including this instruction. 8736 */ 8737 bl common_verifyField 8738 #endif 8739 b .LOP_SPUT_WIDE_finish @ resume 8740 8741 /* continuation for OP_SPUT_OBJECT */ 8742 8743 8744 .LOP_SPUT_OBJECT_end: 8745 str r1, [r0, #offStaticField_value] @ field<- vAA 8746 @ no-op 8747 cmp r1, #0 @ stored a null object? 8748 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 8749 GOTO_OPCODE(ip) @ jump to next instruction 8750 8751 /* Continuation if the field has not yet been resolved. 8752 * r1: BBBB field ref 8753 * r10: dvmDex->pResFields 8754 */ 8755 .LOP_SPUT_OBJECT_resolve: 8756 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8757 #if defined(WITH_JIT) 8758 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8759 #endif 8760 EXPORT_PC() @ resolve() could throw, so export now 8761 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8762 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8763 cmp r0, #0 @ success? 8764 beq common_exceptionThrown @ no, handle exception 8765 #if defined(WITH_JIT) 8766 /* 8767 * If the JIT is actively building a trace we need to make sure 8768 * that the field is fully resolved before including this instruction. 8769 */ 8770 bl common_verifyField 8771 #endif 8772 b .LOP_SPUT_OBJECT_finish @ resume 8773 8774 8775 /* continuation for OP_SPUT_BOOLEAN */ 8776 8777 /* 8778 * Continuation if the field has not yet been resolved. 8779 * r1: BBBB field ref 8780 * r10: dvmDex->pResFields 8781 */ 8782 .LOP_SPUT_BOOLEAN_resolve: 8783 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8784 #if defined(WITH_JIT) 8785 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8786 #endif 8787 EXPORT_PC() @ resolve() could throw, so export now 8788 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8789 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8790 cmp r0, #0 @ success? 8791 beq common_exceptionThrown @ no, handle exception 8792 #if defined(WITH_JIT) 8793 /* 8794 * If the JIT is actively building a trace we need to make sure 8795 * that the field is fully resolved before including this instruction. 8796 */ 8797 bl common_verifyField 8798 #endif 8799 b .LOP_SPUT_BOOLEAN_finish @ resume 8800 8801 /* continuation for OP_SPUT_BYTE */ 8802 8803 /* 8804 * Continuation if the field has not yet been resolved. 8805 * r1: BBBB field ref 8806 * r10: dvmDex->pResFields 8807 */ 8808 .LOP_SPUT_BYTE_resolve: 8809 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8810 #if defined(WITH_JIT) 8811 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8812 #endif 8813 EXPORT_PC() @ resolve() could throw, so export now 8814 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8815 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8816 cmp r0, #0 @ success? 8817 beq common_exceptionThrown @ no, handle exception 8818 #if defined(WITH_JIT) 8819 /* 8820 * If the JIT is actively building a trace we need to make sure 8821 * that the field is fully resolved before including this instruction. 8822 */ 8823 bl common_verifyField 8824 #endif 8825 b .LOP_SPUT_BYTE_finish @ resume 8826 8827 /* continuation for OP_SPUT_CHAR */ 8828 8829 /* 8830 * Continuation if the field has not yet been resolved. 8831 * r1: BBBB field ref 8832 * r10: dvmDex->pResFields 8833 */ 8834 .LOP_SPUT_CHAR_resolve: 8835 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8836 #if defined(WITH_JIT) 8837 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8838 #endif 8839 EXPORT_PC() @ resolve() could throw, so export now 8840 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8841 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8842 cmp r0, #0 @ success? 8843 beq common_exceptionThrown @ no, handle exception 8844 #if defined(WITH_JIT) 8845 /* 8846 * If the JIT is actively building a trace we need to make sure 8847 * that the field is fully resolved before including this instruction. 8848 */ 8849 bl common_verifyField 8850 #endif 8851 b .LOP_SPUT_CHAR_finish @ resume 8852 8853 /* continuation for OP_SPUT_SHORT */ 8854 8855 /* 8856 * Continuation if the field has not yet been resolved. 8857 * r1: BBBB field ref 8858 * r10: dvmDex->pResFields 8859 */ 8860 .LOP_SPUT_SHORT_resolve: 8861 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8862 #if defined(WITH_JIT) 8863 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8864 #endif 8865 EXPORT_PC() @ resolve() could throw, so export now 8866 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8867 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8868 cmp r0, #0 @ success? 8869 beq common_exceptionThrown @ no, handle exception 8870 #if defined(WITH_JIT) 8871 /* 8872 * If the JIT is actively building a trace we need to make sure 8873 * that the field is fully resolved before including this instruction. 8874 */ 8875 bl common_verifyField 8876 #endif 8877 b .LOP_SPUT_SHORT_finish @ resume 8878 8879 /* continuation for OP_INVOKE_VIRTUAL */ 8880 8881 /* 8882 * At this point: 8883 * r0 = resolved base method 8884 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 8885 */ 8886 .LOP_INVOKE_VIRTUAL_continue: 8887 GET_VREG(r9, r10) @ r9<- "this" ptr 8888 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 8889 cmp r9, #0 @ is "this" null? 8890 beq common_errNullObject @ null "this", throw exception 8891 ldr r3, [r9, #offObject_clazz] @ r3<- thisPtr->clazz 8892 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 8893 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 8894 bl common_invokeMethodNoRange @ (r0=method, r9="this") 8895 8896 /* continuation for OP_INVOKE_SUPER */ 8897 8898 /* 8899 * At this point: 8900 * r0 = resolved base method 8901 * r10 = method->clazz 8902 */ 8903 .LOP_INVOKE_SUPER_continue: 8904 ldr r1, [r10, #offClassObject_super] @ r1<- method->clazz->super 8905 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 8906 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 8907 EXPORT_PC() @ must export for invoke 8908 cmp r2, r3 @ compare (methodIndex, vtableCount) 8909 bcs .LOP_INVOKE_SUPER_nsm @ method not present in superclass 8910 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 8911 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 8912 bl common_invokeMethodNoRange @ continue on 8913 8914 .LOP_INVOKE_SUPER_resolve: 8915 mov r0, r10 @ r0<- method->clazz 8916 mov r2, #METHOD_VIRTUAL @ resolver method type 8917 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8918 cmp r0, #0 @ got null? 8919 bne .LOP_INVOKE_SUPER_continue @ no, continue 8920 b common_exceptionThrown @ yes, handle exception 8921 8922 /* 8923 * Throw a NoSuchMethodError with the method name as the message. 8924 * r0 = resolved base method 8925 */ 8926 .LOP_INVOKE_SUPER_nsm: 8927 ldr r1, [r0, #offMethod_name] @ r1<- method name 8928 b common_errNoSuchMethod 8929 8930 /* continuation for OP_INVOKE_DIRECT */ 8931 8932 /* 8933 * On entry: 8934 * r1 = reference (BBBB or CCCC) 8935 * r10 = "this" register 8936 */ 8937 .LOP_INVOKE_DIRECT_resolve: 8938 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 8939 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8940 mov r2, #METHOD_DIRECT @ resolver method type 8941 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8942 cmp r0, #0 @ got null? 8943 bne .LOP_INVOKE_DIRECT_finish @ no, continue 8944 b common_exceptionThrown @ yes, handle exception 8945 8946 /* continuation for OP_INVOKE_STATIC */ 8947 8948 8949 .LOP_INVOKE_STATIC_resolve: 8950 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 8951 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8952 mov r2, #METHOD_STATIC @ resolver method type 8953 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8954 cmp r0, #0 @ got null? 8955 #if defined(WITH_JIT) 8956 /* 8957 * Check to see if we're actively building a trace. If so, 8958 * we need to keep this instruction out of it. 8959 * r10: &resolved_methodToCall 8960 */ 8961 ldrh r2, [rSELF, #offThread_subMode] 8962 beq common_exceptionThrown @ null, handle exception 8963 ands r2, #kSubModeJitTraceBuild @ trace under construction? 8964 beq common_invokeMethodNoRange @ no (r0=method, r9="this") 8965 ldr r1, [r10] @ reload resolved method 8966 cmp r1, #0 @ finished resolving? 8967 bne common_invokeMethodNoRange @ yes (r0=method, r9="this") 8968 mov r10, r0 @ preserve method 8969 mov r0, rSELF 8970 mov r1, rPC 8971 bl dvmJitEndTraceSelect @ (self, pc) 8972 mov r0, r10 8973 b common_invokeMethodNoRange @ whew, finally! 8974 #else 8975 bne common_invokeMethodNoRange @ (r0=method, r9="this") 8976 b common_exceptionThrown @ yes, handle exception 8977 #endif 8978 8979 /* continuation for OP_INVOKE_VIRTUAL_RANGE */ 8980 8981 /* 8982 * At this point: 8983 * r0 = resolved base method 8984 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 8985 */ 8986 .LOP_INVOKE_VIRTUAL_RANGE_continue: 8987 GET_VREG(r9, r10) @ r9<- "this" ptr 8988 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 8989 cmp r9, #0 @ is "this" null? 8990 beq common_errNullObject @ null "this", throw exception 8991 ldr r3, [r9, #offObject_clazz] @ r3<- thisPtr->clazz 8992 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 8993 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 8994 bl common_invokeMethodRange @ (r0=method, r9="this") 8995 8996 /* continuation for OP_INVOKE_SUPER_RANGE */ 8997 8998 /* 8999 * At this point: 9000 * r0 = resolved base method 9001 * r10 = method->clazz 9002 */ 9003 .LOP_INVOKE_SUPER_RANGE_continue: 9004 ldr r1, [r10, #offClassObject_super] @ r1<- method->clazz->super 9005 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 9006 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 9007 EXPORT_PC() @ must export for invoke 9008 cmp r2, r3 @ compare (methodIndex, vtableCount) 9009 bcs .LOP_INVOKE_SUPER_RANGE_nsm @ method not present in superclass 9010 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 9011 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 9012 bl common_invokeMethodRange @ continue on 9013 9014 .LOP_INVOKE_SUPER_RANGE_resolve: 9015 mov r0, r10 @ r0<- method->clazz 9016 mov r2, #METHOD_VIRTUAL @ resolver method type 9017 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9018 cmp r0, #0 @ got null? 9019 bne .LOP_INVOKE_SUPER_RANGE_continue @ no, continue 9020 b common_exceptionThrown @ yes, handle exception 9021 9022 /* 9023 * Throw a NoSuchMethodError with the method name as the message. 9024 * r0 = resolved base method 9025 */ 9026 .LOP_INVOKE_SUPER_RANGE_nsm: 9027 ldr r1, [r0, #offMethod_name] @ r1<- method name 9028 b common_errNoSuchMethod 9029 9030 /* continuation for OP_INVOKE_DIRECT_RANGE */ 9031 9032 /* 9033 * On entry: 9034 * r1 = reference (BBBB or CCCC) 9035 * r10 = "this" register 9036 */ 9037 .LOP_INVOKE_DIRECT_RANGE_resolve: 9038 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9039 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9040 mov r2, #METHOD_DIRECT @ resolver method type 9041 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9042 cmp r0, #0 @ got null? 9043 bne .LOP_INVOKE_DIRECT_RANGE_finish @ no, continue 9044 b common_exceptionThrown @ yes, handle exception 9045 9046 /* continuation for OP_INVOKE_STATIC_RANGE */ 9047 9048 9049 .LOP_INVOKE_STATIC_RANGE_resolve: 9050 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9051 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9052 mov r2, #METHOD_STATIC @ resolver method type 9053 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9054 cmp r0, #0 @ got null? 9055 #if defined(WITH_JIT) 9056 /* 9057 * Check to see if we're actively building a trace. If so, 9058 * we need to keep this instruction out of it. 9059 * r10: &resolved_methodToCall 9060 */ 9061 ldrh r2, [rSELF, #offThread_subMode] 9062 beq common_exceptionThrown @ null, handle exception 9063 ands r2, #kSubModeJitTraceBuild @ trace under construction? 9064 beq common_invokeMethodRange @ no (r0=method, r9="this") 9065 ldr r1, [r10] @ reload resolved method 9066 cmp r1, #0 @ finished resolving? 9067 bne common_invokeMethodRange @ yes (r0=method, r9="this") 9068 mov r10, r0 @ preserve method 9069 mov r0, rSELF 9070 mov r1, rPC 9071 bl dvmJitEndTraceSelect @ (self, pc) 9072 mov r0, r10 9073 b common_invokeMethodRange @ whew, finally! 9074 #else 9075 bne common_invokeMethodRange @ (r0=method, r9="this") 9076 b common_exceptionThrown @ yes, handle exception 9077 #endif 9078 9079 /* continuation for OP_FLOAT_TO_LONG */ 9080 /* 9081 * Convert the float in r0 to a long in r0/r1. 9082 * 9083 * We have to clip values to long min/max per the specification. The 9084 * expected common case is a "reasonable" value that converts directly 9085 * to modest integer. The EABI convert function isn't doing this for us. 9086 */ 9087 f2l_doconv: 9088 stmfd sp!, {r4, lr} 9089 mov r1, #0x5f000000 @ (float)maxlong 9090 mov r4, r0 9091 bl __aeabi_fcmpge @ is arg >= maxlong? 9092 cmp r0, #0 @ nonzero == yes 9093 mvnne r0, #0 @ return maxlong (7fffffff) 9094 mvnne r1, #0x80000000 9095 ldmnefd sp!, {r4, pc} 9096 9097 mov r0, r4 @ recover arg 9098 mov r1, #0xdf000000 @ (float)minlong 9099 bl __aeabi_fcmple @ is arg <= minlong? 9100 cmp r0, #0 @ nonzero == yes 9101 movne r0, #0 @ return minlong (80000000) 9102 movne r1, #0x80000000 9103 ldmnefd sp!, {r4, pc} 9104 9105 mov r0, r4 @ recover arg 9106 mov r1, r4 9107 bl __aeabi_fcmpeq @ is arg == self? 9108 cmp r0, #0 @ zero == no 9109 moveq r1, #0 @ return zero for NaN 9110 ldmeqfd sp!, {r4, pc} 9111 9112 mov r0, r4 @ recover arg 9113 bl __aeabi_f2lz @ convert float to long 9114 ldmfd sp!, {r4, pc} 9115 9116 /* continuation for OP_DOUBLE_TO_LONG */ 9117 /* 9118 * Convert the double in r0/r1 to a long in r0/r1. 9119 * 9120 * We have to clip values to long min/max per the specification. The 9121 * expected common case is a "reasonable" value that converts directly 9122 * to modest integer. The EABI convert function isn't doing this for us. 9123 */ 9124 d2l_doconv: 9125 stmfd sp!, {r4, r5, lr} @ save regs 9126 mov r3, #0x43000000 @ maxlong, as a double (high word) 9127 add r3, #0x00e00000 @ 0x43e00000 9128 mov r2, #0 @ maxlong, as a double (low word) 9129 sub sp, sp, #4 @ align for EABI 9130 mov r4, r0 @ save a copy of r0 9131 mov r5, r1 @ and r1 9132 bl __aeabi_dcmpge @ is arg >= maxlong? 9133 cmp r0, #0 @ nonzero == yes 9134 mvnne r0, #0 @ return maxlong (7fffffffffffffff) 9135 mvnne r1, #0x80000000 9136 bne 1f 9137 9138 mov r0, r4 @ recover arg 9139 mov r1, r5 9140 mov r3, #0xc3000000 @ minlong, as a double (high word) 9141 add r3, #0x00e00000 @ 0xc3e00000 9142 mov r2, #0 @ minlong, as a double (low word) 9143 bl __aeabi_dcmple @ is arg <= minlong? 9144 cmp r0, #0 @ nonzero == yes 9145 movne r0, #0 @ return minlong (8000000000000000) 9146 movne r1, #0x80000000 9147 bne 1f 9148 9149 mov r0, r4 @ recover arg 9150 mov r1, r5 9151 mov r2, r4 @ compare against self 9152 mov r3, r5 9153 bl __aeabi_dcmpeq @ is arg == self? 9154 cmp r0, #0 @ zero == no 9155 moveq r1, #0 @ return zero for NaN 9156 beq 1f 9157 9158 mov r0, r4 @ recover arg 9159 mov r1, r5 9160 bl __aeabi_d2lz @ convert double to long 9161 9162 1: 9163 add sp, sp, #4 9164 ldmfd sp!, {r4, r5, pc} 9165 9166 /* continuation for OP_MUL_LONG */ 9167 9168 .LOP_MUL_LONG_finish: 9169 GET_INST_OPCODE(ip) @ extract opcode from rINST 9170 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 9171 GOTO_OPCODE(ip) @ jump to next instruction 9172 9173 /* continuation for OP_SHL_LONG */ 9174 9175 .LOP_SHL_LONG_finish: 9176 mov r0, r0, asl r2 @ r0<- r0 << r2 9177 GET_INST_OPCODE(ip) @ extract opcode from rINST 9178 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9179 GOTO_OPCODE(ip) @ jump to next instruction 9180 9181 /* continuation for OP_SHR_LONG */ 9182 9183 .LOP_SHR_LONG_finish: 9184 mov r1, r1, asr r2 @ r1<- r1 >> r2 9185 GET_INST_OPCODE(ip) @ extract opcode from rINST 9186 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9187 GOTO_OPCODE(ip) @ jump to next instruction 9188 9189 /* continuation for OP_USHR_LONG */ 9190 9191 .LOP_USHR_LONG_finish: 9192 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 9193 GET_INST_OPCODE(ip) @ extract opcode from rINST 9194 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9195 GOTO_OPCODE(ip) @ jump to next instruction 9196 9197 /* continuation for OP_SHL_LONG_2ADDR */ 9198 9199 .LOP_SHL_LONG_2ADDR_finish: 9200 GET_INST_OPCODE(ip) @ extract opcode from rINST 9201 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9202 GOTO_OPCODE(ip) @ jump to next instruction 9203 9204 /* continuation for OP_SHR_LONG_2ADDR */ 9205 9206 .LOP_SHR_LONG_2ADDR_finish: 9207 GET_INST_OPCODE(ip) @ extract opcode from rINST 9208 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9209 GOTO_OPCODE(ip) @ jump to next instruction 9210 9211 /* continuation for OP_USHR_LONG_2ADDR */ 9212 9213 .LOP_USHR_LONG_2ADDR_finish: 9214 GET_INST_OPCODE(ip) @ extract opcode from rINST 9215 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9216 GOTO_OPCODE(ip) @ jump to next instruction 9217 9218 /* continuation for OP_IGET_VOLATILE */ 9219 9220 /* 9221 * Currently: 9222 * r0 holds resolved field 9223 * r9 holds object 9224 */ 9225 .LOP_IGET_VOLATILE_finish: 9226 @bl common_squeak0 9227 cmp r9, #0 @ check object for null 9228 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9229 beq common_errNullObject @ object was null 9230 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 9231 SMP_DMB @ acquiring load 9232 mov r2, rINST, lsr #8 @ r2<- A+ 9233 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9234 and r2, r2, #15 @ r2<- A 9235 GET_INST_OPCODE(ip) @ extract opcode from rINST 9236 SET_VREG(r0, r2) @ fp[A]<- r0 9237 GOTO_OPCODE(ip) @ jump to next instruction 9238 9239 /* continuation for OP_IPUT_VOLATILE */ 9240 9241 /* 9242 * Currently: 9243 * r0 holds resolved field 9244 * r9 holds object 9245 */ 9246 .LOP_IPUT_VOLATILE_finish: 9247 @bl common_squeak0 9248 mov r1, rINST, lsr #8 @ r1<- A+ 9249 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9250 and r1, r1, #15 @ r1<- A 9251 cmp r9, #0 @ check object for null 9252 GET_VREG(r0, r1) @ r0<- fp[A] 9253 beq common_errNullObject @ object was null 9254 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9255 GET_INST_OPCODE(ip) @ extract opcode from rINST 9256 SMP_DMB_ST @ releasing store 9257 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 9258 SMP_DMB 9259 GOTO_OPCODE(ip) @ jump to next instruction 9260 9261 /* continuation for OP_SGET_VOLATILE */ 9262 9263 /* 9264 * Continuation if the field has not yet been resolved. 9265 * r1: BBBB field ref 9266 * r10: dvmDex->pResFields 9267 */ 9268 .LOP_SGET_VOLATILE_resolve: 9269 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9270 #if defined(WITH_JIT) 9271 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9272 #endif 9273 EXPORT_PC() @ resolve() could throw, so export now 9274 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9275 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9276 cmp r0, #0 @ success? 9277 beq common_exceptionThrown @ no, handle exception 9278 #if defined(WITH_JIT) 9279 /* 9280 * If the JIT is actively building a trace we need to make sure 9281 * that the field is fully resolved before including this instruction. 9282 */ 9283 bl common_verifyField 9284 #endif 9285 b .LOP_SGET_VOLATILE_finish 9286 9287 /* continuation for OP_SPUT_VOLATILE */ 9288 9289 /* 9290 * Continuation if the field has not yet been resolved. 9291 * r1: BBBB field ref 9292 * r10: dvmDex->pResFields 9293 */ 9294 .LOP_SPUT_VOLATILE_resolve: 9295 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9296 #if defined(WITH_JIT) 9297 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9298 #endif 9299 EXPORT_PC() @ resolve() could throw, so export now 9300 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9301 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9302 cmp r0, #0 @ success? 9303 beq common_exceptionThrown @ no, handle exception 9304 #if defined(WITH_JIT) 9305 /* 9306 * If the JIT is actively building a trace we need to make sure 9307 * that the field is fully resolved before including this instruction. 9308 */ 9309 bl common_verifyField 9310 #endif 9311 b .LOP_SPUT_VOLATILE_finish @ resume 9312 9313 /* continuation for OP_IGET_OBJECT_VOLATILE */ 9314 9315 /* 9316 * Currently: 9317 * r0 holds resolved field 9318 * r9 holds object 9319 */ 9320 .LOP_IGET_OBJECT_VOLATILE_finish: 9321 @bl common_squeak0 9322 cmp r9, #0 @ check object for null 9323 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9324 beq common_errNullObject @ object was null 9325 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 9326 SMP_DMB @ acquiring load 9327 mov r2, rINST, lsr #8 @ r2<- A+ 9328 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9329 and r2, r2, #15 @ r2<- A 9330 GET_INST_OPCODE(ip) @ extract opcode from rINST 9331 SET_VREG(r0, r2) @ fp[A]<- r0 9332 GOTO_OPCODE(ip) @ jump to next instruction 9333 9334 /* continuation for OP_IGET_WIDE_VOLATILE */ 9335 9336 /* 9337 * Currently: 9338 * r0 holds resolved field 9339 * r9 holds object 9340 */ 9341 .LOP_IGET_WIDE_VOLATILE_finish: 9342 cmp r9, #0 @ check object for null 9343 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9344 beq common_errNullObject @ object was null 9345 .if 1 9346 add r0, r9, r3 @ r0<- address of field 9347 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 9348 .else 9349 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 9350 .endif 9351 mov r2, rINST, lsr #8 @ r2<- A+ 9352 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9353 and r2, r2, #15 @ r2<- A 9354 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 9355 GET_INST_OPCODE(ip) @ extract opcode from rINST 9356 stmia r3, {r0-r1} @ fp[A]<- r0/r1 9357 GOTO_OPCODE(ip) @ jump to next instruction 9358 9359 /* continuation for OP_IPUT_WIDE_VOLATILE */ 9360 9361 /* 9362 * Currently: 9363 * r0 holds resolved field 9364 * r9 holds object 9365 */ 9366 .LOP_IPUT_WIDE_VOLATILE_finish: 9367 mov r2, rINST, lsr #8 @ r2<- A+ 9368 cmp r9, #0 @ check object for null 9369 and r2, r2, #15 @ r2<- A 9370 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9371 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 9372 beq common_errNullObject @ object was null 9373 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9374 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 9375 GET_INST_OPCODE(r10) @ extract opcode from rINST 9376 .if 1 9377 add r2, r9, r3 @ r2<- target address 9378 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 9379 .else 9380 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 9381 .endif 9382 GOTO_OPCODE(r10) @ jump to next instruction 9383 9384 /* continuation for OP_SGET_WIDE_VOLATILE */ 9385 9386 /* 9387 * Continuation if the field has not yet been resolved. 9388 * r1: BBBB field ref 9389 * r10: dvmDex->pResFields 9390 * 9391 * Returns StaticField pointer in r0. 9392 */ 9393 .LOP_SGET_WIDE_VOLATILE_resolve: 9394 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9395 #if defined(WITH_JIT) 9396 add r10, r10, r1, lsl #2 @ r1<- &dvmDex->pResFields[field] 9397 #endif 9398 EXPORT_PC() @ resolve() could throw, so export now 9399 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9400 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9401 cmp r0, #0 @ success? 9402 beq common_exceptionThrown @ no, handle exception 9403 #if defined(WITH_JIT) 9404 /* 9405 * If the JIT is actively building a trace we need to make sure 9406 * that the field is fully resolved before including this instruction. 9407 */ 9408 bl common_verifyField 9409 #endif 9410 b .LOP_SGET_WIDE_VOLATILE_finish @ resume 9411 9412 /* continuation for OP_SPUT_WIDE_VOLATILE */ 9413 9414 /* 9415 * Continuation if the field has not yet been resolved. 9416 * r1: BBBB field ref 9417 * r9: &fp[AA] 9418 * r10: dvmDex->pResFields 9419 * 9420 * Returns StaticField pointer in r2. 9421 */ 9422 .LOP_SPUT_WIDE_VOLATILE_resolve: 9423 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9424 #if defined(WITH_JIT) 9425 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9426 #endif 9427 EXPORT_PC() @ resolve() could throw, so export now 9428 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9429 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9430 cmp r0, #0 @ success? 9431 mov r2, r0 @ copy to r2 9432 beq common_exceptionThrown @ no, handle exception 9433 #if defined(WITH_JIT) 9434 /* 9435 * If the JIT is actively building a trace we need to make sure 9436 * that the field is fully resolved before including this instruction. 9437 */ 9438 bl common_verifyField 9439 #endif 9440 b .LOP_SPUT_WIDE_VOLATILE_finish @ resume 9441 9442 /* continuation for OP_EXECUTE_INLINE */ 9443 9444 /* 9445 * Extract args, call function. 9446 * r0 = #of args (0-4) 9447 * r10 = call index 9448 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 9449 * 9450 * Other ideas: 9451 * - Use a jump table from the main piece to jump directly into the 9452 * AND/LDR pairs. Costs a data load, saves a branch. 9453 * - Have five separate pieces that do the loading, so we can work the 9454 * interleave a little better. Increases code size. 9455 */ 9456 .LOP_EXECUTE_INLINE_continue: 9457 rsb r0, r0, #4 @ r0<- 4-r0 9458 FETCH(rINST, 2) @ rINST<- FEDC 9459 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 9460 bl common_abort @ (skipped due to ARM prefetch) 9461 4: and ip, rINST, #0xf000 @ isolate F 9462 ldr r3, [rFP, ip, lsr #10] @ r3<- vF (shift right 12, left 2) 9463 3: and ip, rINST, #0x0f00 @ isolate E 9464 ldr r2, [rFP, ip, lsr #6] @ r2<- vE 9465 2: and ip, rINST, #0x00f0 @ isolate D 9466 ldr r1, [rFP, ip, lsr #2] @ r1<- vD 9467 1: and ip, rINST, #0x000f @ isolate C 9468 ldr r0, [rFP, ip, lsl #2] @ r0<- vC 9469 0: 9470 ldr rINST, .LOP_EXECUTE_INLINE_table @ table of InlineOperation 9471 ldr pc, [rINST, r10, lsl #4] @ sizeof=16, "func" is first entry 9472 @ (not reached) 9473 9474 /* 9475 * We're debugging or profiling. 9476 * r10: opIndex 9477 */ 9478 .LOP_EXECUTE_INLINE_debugmode: 9479 mov r0, r10 9480 bl dvmResolveInlineNative 9481 cmp r0, #0 @ did it resolve? 9482 beq .LOP_EXECUTE_INLINE_resume @ no, just move on 9483 mov r9, r0 @ remember method 9484 mov r1, rSELF 9485 bl dvmFastMethodTraceEnter @ (method, self) 9486 add r1, rSELF, #offThread_retval@ r1<- &self->retval 9487 sub sp, sp, #8 @ make room for arg, +64 bit align 9488 mov r0, rINST, lsr #12 @ r0<- B 9489 str r1, [sp] @ push &self->retval 9490 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 9491 mov rINST, r0 @ save result of inline 9492 add sp, sp, #8 @ pop stack 9493 mov r0, r9 @ r0<- method 9494 mov r1, rSELF 9495 bl dvmFastNativeMethodTraceExit @ (method, self) 9496 cmp rINST, #0 @ test boolean result of inline 9497 beq common_exceptionThrown @ returned false, handle exception 9498 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 9499 GET_INST_OPCODE(ip) @ extract opcode from rINST 9500 GOTO_OPCODE(ip) @ jump to next instruction 9501 9502 9503 9504 9505 .LOP_EXECUTE_INLINE_table: 9506 .word gDvmInlineOpsTable 9507 9508 /* continuation for OP_EXECUTE_INLINE_RANGE */ 9509 9510 /* 9511 * Extract args, call function. 9512 * r0 = #of args (0-4) 9513 * r10 = call index 9514 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 9515 */ 9516 .LOP_EXECUTE_INLINE_RANGE_continue: 9517 rsb r0, r0, #4 @ r0<- 4-r0 9518 FETCH(r9, 2) @ r9<- CCCC 9519 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 9520 bl common_abort @ (skipped due to ARM prefetch) 9521 4: add ip, r9, #3 @ base+3 9522 GET_VREG(r3, ip) @ r3<- vBase[3] 9523 3: add ip, r9, #2 @ base+2 9524 GET_VREG(r2, ip) @ r2<- vBase[2] 9525 2: add ip, r9, #1 @ base+1 9526 GET_VREG(r1, ip) @ r1<- vBase[1] 9527 1: add ip, r9, #0 @ (nop) 9528 GET_VREG(r0, ip) @ r0<- vBase[0] 9529 0: 9530 ldr r9, .LOP_EXECUTE_INLINE_RANGE_table @ table of InlineOperation 9531 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 9532 @ (not reached) 9533 9534 9535 /* 9536 * We're debugging or profiling. 9537 * r10: opIndex 9538 */ 9539 .LOP_EXECUTE_INLINE_RANGE_debugmode: 9540 mov r0, r10 9541 bl dvmResolveInlineNative 9542 cmp r0, #0 @ did it resolve? 9543 beq .LOP_EXECUTE_INLINE_RANGE_resume @ no, just move on 9544 mov r9, r0 @ remember method 9545 mov r1, rSELF 9546 bl dvmFastMethodTraceEnter @ (method, self) 9547 add r1, rSELF, #offThread_retval@ r1<- &self->retval 9548 sub sp, sp, #8 @ make room for arg, +64 bit align 9549 mov r0, rINST, lsr #8 @ r0<- B 9550 mov rINST, r9 @ rINST<- method 9551 str r1, [sp] @ push &self->retval 9552 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 9553 mov r9, r0 @ save result of inline 9554 add sp, sp, #8 @ pop stack 9555 mov r0, rINST @ r0<- method 9556 mov r1, rSELF 9557 bl dvmFastNativeMethodTraceExit @ (method, self) 9558 cmp r9, #0 @ test boolean result of inline 9559 beq common_exceptionThrown @ returned false, handle exception 9560 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 9561 GET_INST_OPCODE(ip) @ extract opcode from rINST 9562 GOTO_OPCODE(ip) @ jump to next instruction 9563 9564 9565 9566 9567 .LOP_EXECUTE_INLINE_RANGE_table: 9568 .word gDvmInlineOpsTable 9569 9570 9571 /* continuation for OP_INVOKE_OBJECT_INIT_RANGE */ 9572 9573 .LOP_INVOKE_OBJECT_INIT_RANGE_setFinal: 9574 EXPORT_PC() @ can throw 9575 bl dvmSetFinalizable @ call dvmSetFinalizable(obj) 9576 ldr r0, [rSELF, #offThread_exception] @ r0<- self->exception 9577 cmp r0, #0 @ exception pending? 9578 bne common_exceptionThrown @ yes, handle it 9579 b .LOP_INVOKE_OBJECT_INIT_RANGE_finish 9580 9581 /* 9582 * A debugger is attached, so we need to go ahead and do 9583 * this. For simplicity, we'll just jump directly to the 9584 * corresponding handler. Note that we can't use 9585 * rIBASE here because it may be in single-step mode. 9586 * Load the primary table base directly. 9587 */ 9588 .LOP_INVOKE_OBJECT_INIT_RANGE_debugger: 9589 ldr r1, [rSELF, #offThread_mainHandlerTable] 9590 mov ip, #OP_INVOKE_DIRECT_RANGE 9591 GOTO_OPCODE_BASE(r1,ip) @ execute it 9592 9593 /* continuation for OP_IPUT_OBJECT_VOLATILE */ 9594 9595 /* 9596 * Currently: 9597 * r0 holds resolved field 9598 * r9 holds object 9599 */ 9600 .LOP_IPUT_OBJECT_VOLATILE_finish: 9601 @bl common_squeak0 9602 mov r1, rINST, lsr #8 @ r1<- A+ 9603 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9604 and r1, r1, #15 @ r1<- A 9605 cmp r9, #0 @ check object for null 9606 GET_VREG(r0, r1) @ r0<- fp[A] 9607 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 9608 beq common_errNullObject @ object was null 9609 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9610 GET_INST_OPCODE(ip) @ extract opcode from rINST 9611 SMP_DMB_ST @ releasing store 9612 str r0, [r9, r3] @ obj.field (32 bits)<- r0 9613 SMP_DMB 9614 cmp r0, #0 @ stored a null reference? 9615 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 9616 GOTO_OPCODE(ip) @ jump to next instruction 9617 9618 /* continuation for OP_SGET_OBJECT_VOLATILE */ 9619 9620 /* 9621 * Continuation if the field has not yet been resolved. 9622 * r1: BBBB field ref 9623 * r10: dvmDex->pResFields 9624 */ 9625 .LOP_SGET_OBJECT_VOLATILE_resolve: 9626 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9627 #if defined(WITH_JIT) 9628 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9629 #endif 9630 EXPORT_PC() @ resolve() could throw, so export now 9631 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9632 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9633 cmp r0, #0 @ success? 9634 beq common_exceptionThrown @ no, handle exception 9635 #if defined(WITH_JIT) 9636 /* 9637 * If the JIT is actively building a trace we need to make sure 9638 * that the field is fully resolved before including this instruction. 9639 */ 9640 bl common_verifyField 9641 #endif 9642 b .LOP_SGET_OBJECT_VOLATILE_finish 9643 9644 /* continuation for OP_SPUT_OBJECT_VOLATILE */ 9645 9646 9647 .LOP_SPUT_OBJECT_VOLATILE_end: 9648 str r1, [r0, #offStaticField_value] @ field<- vAA 9649 SMP_DMB 9650 cmp r1, #0 @ stored a null object? 9651 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 9652 GOTO_OPCODE(ip) @ jump to next instruction 9653 9654 /* Continuation if the field has not yet been resolved. 9655 * r1: BBBB field ref 9656 * r10: dvmDex->pResFields 9657 */ 9658 .LOP_SPUT_OBJECT_VOLATILE_resolve: 9659 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9660 #if defined(WITH_JIT) 9661 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9662 #endif 9663 EXPORT_PC() @ resolve() could throw, so export now 9664 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9665 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9666 cmp r0, #0 @ success? 9667 beq common_exceptionThrown @ no, handle exception 9668 #if defined(WITH_JIT) 9669 /* 9670 * If the JIT is actively building a trace we need to make sure 9671 * that the field is fully resolved before including this instruction. 9672 */ 9673 bl common_verifyField 9674 #endif 9675 b .LOP_SPUT_OBJECT_VOLATILE_finish @ resume 9676 9677 9678 .size dvmAsmSisterStart, .-dvmAsmSisterStart 9679 .global dvmAsmSisterEnd 9680 dvmAsmSisterEnd: 9681 9682 9683 .global dvmAsmAltInstructionStart 9684 .type dvmAsmAltInstructionStart, %function 9685 .text 9686 9687 dvmAsmAltInstructionStart = .L_ALT_OP_NOP 9688 /* ------------------------------ */ 9689 .balign 64 9690 .L_ALT_OP_NOP: /* 0x00 */ 9691 /* File: armv5te/alt_stub.S */ 9692 /* 9693 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9694 * any interesting requests and then jump to the real instruction 9695 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9696 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9697 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9698 * bail to the real handler if breakFlags==0. 9699 */ 9700 ldrb r3, [rSELF, #offThread_breakFlags] 9701 adrl lr, dvmAsmInstructionStart + (0 * 64) 9702 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9703 cmp r3, #0 9704 bxeq lr @ nothing to do - jump to real handler 9705 EXPORT_PC() 9706 mov r0, rPC @ arg0 9707 mov r1, rFP @ arg1 9708 mov r2, rSELF @ arg2 9709 b dvmCheckBefore @ (dPC,dFP,self) tail call 9710 9711 /* ------------------------------ */ 9712 .balign 64 9713 .L_ALT_OP_MOVE: /* 0x01 */ 9714 /* File: armv5te/alt_stub.S */ 9715 /* 9716 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9717 * any interesting requests and then jump to the real instruction 9718 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9719 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9720 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9721 * bail to the real handler if breakFlags==0. 9722 */ 9723 ldrb r3, [rSELF, #offThread_breakFlags] 9724 adrl lr, dvmAsmInstructionStart + (1 * 64) 9725 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9726 cmp r3, #0 9727 bxeq lr @ nothing to do - jump to real handler 9728 EXPORT_PC() 9729 mov r0, rPC @ arg0 9730 mov r1, rFP @ arg1 9731 mov r2, rSELF @ arg2 9732 b dvmCheckBefore @ (dPC,dFP,self) tail call 9733 9734 /* ------------------------------ */ 9735 .balign 64 9736 .L_ALT_OP_MOVE_FROM16: /* 0x02 */ 9737 /* File: armv5te/alt_stub.S */ 9738 /* 9739 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9740 * any interesting requests and then jump to the real instruction 9741 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9742 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9743 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9744 * bail to the real handler if breakFlags==0. 9745 */ 9746 ldrb r3, [rSELF, #offThread_breakFlags] 9747 adrl lr, dvmAsmInstructionStart + (2 * 64) 9748 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9749 cmp r3, #0 9750 bxeq lr @ nothing to do - jump to real handler 9751 EXPORT_PC() 9752 mov r0, rPC @ arg0 9753 mov r1, rFP @ arg1 9754 mov r2, rSELF @ arg2 9755 b dvmCheckBefore @ (dPC,dFP,self) tail call 9756 9757 /* ------------------------------ */ 9758 .balign 64 9759 .L_ALT_OP_MOVE_16: /* 0x03 */ 9760 /* File: armv5te/alt_stub.S */ 9761 /* 9762 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9763 * any interesting requests and then jump to the real instruction 9764 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9765 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9766 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9767 * bail to the real handler if breakFlags==0. 9768 */ 9769 ldrb r3, [rSELF, #offThread_breakFlags] 9770 adrl lr, dvmAsmInstructionStart + (3 * 64) 9771 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9772 cmp r3, #0 9773 bxeq lr @ nothing to do - jump to real handler 9774 EXPORT_PC() 9775 mov r0, rPC @ arg0 9776 mov r1, rFP @ arg1 9777 mov r2, rSELF @ arg2 9778 b dvmCheckBefore @ (dPC,dFP,self) tail call 9779 9780 /* ------------------------------ */ 9781 .balign 64 9782 .L_ALT_OP_MOVE_WIDE: /* 0x04 */ 9783 /* File: armv5te/alt_stub.S */ 9784 /* 9785 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9786 * any interesting requests and then jump to the real instruction 9787 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9788 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9789 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9790 * bail to the real handler if breakFlags==0. 9791 */ 9792 ldrb r3, [rSELF, #offThread_breakFlags] 9793 adrl lr, dvmAsmInstructionStart + (4 * 64) 9794 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9795 cmp r3, #0 9796 bxeq lr @ nothing to do - jump to real handler 9797 EXPORT_PC() 9798 mov r0, rPC @ arg0 9799 mov r1, rFP @ arg1 9800 mov r2, rSELF @ arg2 9801 b dvmCheckBefore @ (dPC,dFP,self) tail call 9802 9803 /* ------------------------------ */ 9804 .balign 64 9805 .L_ALT_OP_MOVE_WIDE_FROM16: /* 0x05 */ 9806 /* File: armv5te/alt_stub.S */ 9807 /* 9808 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9809 * any interesting requests and then jump to the real instruction 9810 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9811 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9812 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9813 * bail to the real handler if breakFlags==0. 9814 */ 9815 ldrb r3, [rSELF, #offThread_breakFlags] 9816 adrl lr, dvmAsmInstructionStart + (5 * 64) 9817 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9818 cmp r3, #0 9819 bxeq lr @ nothing to do - jump to real handler 9820 EXPORT_PC() 9821 mov r0, rPC @ arg0 9822 mov r1, rFP @ arg1 9823 mov r2, rSELF @ arg2 9824 b dvmCheckBefore @ (dPC,dFP,self) tail call 9825 9826 /* ------------------------------ */ 9827 .balign 64 9828 .L_ALT_OP_MOVE_WIDE_16: /* 0x06 */ 9829 /* File: armv5te/alt_stub.S */ 9830 /* 9831 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9832 * any interesting requests and then jump to the real instruction 9833 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9834 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9835 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9836 * bail to the real handler if breakFlags==0. 9837 */ 9838 ldrb r3, [rSELF, #offThread_breakFlags] 9839 adrl lr, dvmAsmInstructionStart + (6 * 64) 9840 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9841 cmp r3, #0 9842 bxeq lr @ nothing to do - jump to real handler 9843 EXPORT_PC() 9844 mov r0, rPC @ arg0 9845 mov r1, rFP @ arg1 9846 mov r2, rSELF @ arg2 9847 b dvmCheckBefore @ (dPC,dFP,self) tail call 9848 9849 /* ------------------------------ */ 9850 .balign 64 9851 .L_ALT_OP_MOVE_OBJECT: /* 0x07 */ 9852 /* File: armv5te/alt_stub.S */ 9853 /* 9854 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9855 * any interesting requests and then jump to the real instruction 9856 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9857 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9858 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9859 * bail to the real handler if breakFlags==0. 9860 */ 9861 ldrb r3, [rSELF, #offThread_breakFlags] 9862 adrl lr, dvmAsmInstructionStart + (7 * 64) 9863 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9864 cmp r3, #0 9865 bxeq lr @ nothing to do - jump to real handler 9866 EXPORT_PC() 9867 mov r0, rPC @ arg0 9868 mov r1, rFP @ arg1 9869 mov r2, rSELF @ arg2 9870 b dvmCheckBefore @ (dPC,dFP,self) tail call 9871 9872 /* ------------------------------ */ 9873 .balign 64 9874 .L_ALT_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 9875 /* File: armv5te/alt_stub.S */ 9876 /* 9877 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9878 * any interesting requests and then jump to the real instruction 9879 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9880 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9881 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9882 * bail to the real handler if breakFlags==0. 9883 */ 9884 ldrb r3, [rSELF, #offThread_breakFlags] 9885 adrl lr, dvmAsmInstructionStart + (8 * 64) 9886 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9887 cmp r3, #0 9888 bxeq lr @ nothing to do - jump to real handler 9889 EXPORT_PC() 9890 mov r0, rPC @ arg0 9891 mov r1, rFP @ arg1 9892 mov r2, rSELF @ arg2 9893 b dvmCheckBefore @ (dPC,dFP,self) tail call 9894 9895 /* ------------------------------ */ 9896 .balign 64 9897 .L_ALT_OP_MOVE_OBJECT_16: /* 0x09 */ 9898 /* File: armv5te/alt_stub.S */ 9899 /* 9900 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9901 * any interesting requests and then jump to the real instruction 9902 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9903 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9904 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9905 * bail to the real handler if breakFlags==0. 9906 */ 9907 ldrb r3, [rSELF, #offThread_breakFlags] 9908 adrl lr, dvmAsmInstructionStart + (9 * 64) 9909 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9910 cmp r3, #0 9911 bxeq lr @ nothing to do - jump to real handler 9912 EXPORT_PC() 9913 mov r0, rPC @ arg0 9914 mov r1, rFP @ arg1 9915 mov r2, rSELF @ arg2 9916 b dvmCheckBefore @ (dPC,dFP,self) tail call 9917 9918 /* ------------------------------ */ 9919 .balign 64 9920 .L_ALT_OP_MOVE_RESULT: /* 0x0a */ 9921 /* File: armv5te/alt_stub.S */ 9922 /* 9923 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9924 * any interesting requests and then jump to the real instruction 9925 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9926 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9927 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9928 * bail to the real handler if breakFlags==0. 9929 */ 9930 ldrb r3, [rSELF, #offThread_breakFlags] 9931 adrl lr, dvmAsmInstructionStart + (10 * 64) 9932 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9933 cmp r3, #0 9934 bxeq lr @ nothing to do - jump to real handler 9935 EXPORT_PC() 9936 mov r0, rPC @ arg0 9937 mov r1, rFP @ arg1 9938 mov r2, rSELF @ arg2 9939 b dvmCheckBefore @ (dPC,dFP,self) tail call 9940 9941 /* ------------------------------ */ 9942 .balign 64 9943 .L_ALT_OP_MOVE_RESULT_WIDE: /* 0x0b */ 9944 /* File: armv5te/alt_stub.S */ 9945 /* 9946 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9947 * any interesting requests and then jump to the real instruction 9948 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9949 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9950 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9951 * bail to the real handler if breakFlags==0. 9952 */ 9953 ldrb r3, [rSELF, #offThread_breakFlags] 9954 adrl lr, dvmAsmInstructionStart + (11 * 64) 9955 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9956 cmp r3, #0 9957 bxeq lr @ nothing to do - jump to real handler 9958 EXPORT_PC() 9959 mov r0, rPC @ arg0 9960 mov r1, rFP @ arg1 9961 mov r2, rSELF @ arg2 9962 b dvmCheckBefore @ (dPC,dFP,self) tail call 9963 9964 /* ------------------------------ */ 9965 .balign 64 9966 .L_ALT_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 9967 /* File: armv5te/alt_stub.S */ 9968 /* 9969 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9970 * any interesting requests and then jump to the real instruction 9971 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9972 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9973 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9974 * bail to the real handler if breakFlags==0. 9975 */ 9976 ldrb r3, [rSELF, #offThread_breakFlags] 9977 adrl lr, dvmAsmInstructionStart + (12 * 64) 9978 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9979 cmp r3, #0 9980 bxeq lr @ nothing to do - jump to real handler 9981 EXPORT_PC() 9982 mov r0, rPC @ arg0 9983 mov r1, rFP @ arg1 9984 mov r2, rSELF @ arg2 9985 b dvmCheckBefore @ (dPC,dFP,self) tail call 9986 9987 /* ------------------------------ */ 9988 .balign 64 9989 .L_ALT_OP_MOVE_EXCEPTION: /* 0x0d */ 9990 /* File: armv5te/alt_stub.S */ 9991 /* 9992 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9993 * any interesting requests and then jump to the real instruction 9994 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9995 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9996 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9997 * bail to the real handler if breakFlags==0. 9998 */ 9999 ldrb r3, [rSELF, #offThread_breakFlags] 10000 adrl lr, dvmAsmInstructionStart + (13 * 64) 10001 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10002 cmp r3, #0 10003 bxeq lr @ nothing to do - jump to real handler 10004 EXPORT_PC() 10005 mov r0, rPC @ arg0 10006 mov r1, rFP @ arg1 10007 mov r2, rSELF @ arg2 10008 b dvmCheckBefore @ (dPC,dFP,self) tail call 10009 10010 /* ------------------------------ */ 10011 .balign 64 10012 .L_ALT_OP_RETURN_VOID: /* 0x0e */ 10013 /* File: armv5te/alt_stub.S */ 10014 /* 10015 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10016 * any interesting requests and then jump to the real instruction 10017 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10018 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10019 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10020 * bail to the real handler if breakFlags==0. 10021 */ 10022 ldrb r3, [rSELF, #offThread_breakFlags] 10023 adrl lr, dvmAsmInstructionStart + (14 * 64) 10024 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10025 cmp r3, #0 10026 bxeq lr @ nothing to do - jump to real handler 10027 EXPORT_PC() 10028 mov r0, rPC @ arg0 10029 mov r1, rFP @ arg1 10030 mov r2, rSELF @ arg2 10031 b dvmCheckBefore @ (dPC,dFP,self) tail call 10032 10033 /* ------------------------------ */ 10034 .balign 64 10035 .L_ALT_OP_RETURN: /* 0x0f */ 10036 /* File: armv5te/alt_stub.S */ 10037 /* 10038 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10039 * any interesting requests and then jump to the real instruction 10040 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10041 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10042 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10043 * bail to the real handler if breakFlags==0. 10044 */ 10045 ldrb r3, [rSELF, #offThread_breakFlags] 10046 adrl lr, dvmAsmInstructionStart + (15 * 64) 10047 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10048 cmp r3, #0 10049 bxeq lr @ nothing to do - jump to real handler 10050 EXPORT_PC() 10051 mov r0, rPC @ arg0 10052 mov r1, rFP @ arg1 10053 mov r2, rSELF @ arg2 10054 b dvmCheckBefore @ (dPC,dFP,self) tail call 10055 10056 /* ------------------------------ */ 10057 .balign 64 10058 .L_ALT_OP_RETURN_WIDE: /* 0x10 */ 10059 /* File: armv5te/alt_stub.S */ 10060 /* 10061 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10062 * any interesting requests and then jump to the real instruction 10063 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10064 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10065 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10066 * bail to the real handler if breakFlags==0. 10067 */ 10068 ldrb r3, [rSELF, #offThread_breakFlags] 10069 adrl lr, dvmAsmInstructionStart + (16 * 64) 10070 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10071 cmp r3, #0 10072 bxeq lr @ nothing to do - jump to real handler 10073 EXPORT_PC() 10074 mov r0, rPC @ arg0 10075 mov r1, rFP @ arg1 10076 mov r2, rSELF @ arg2 10077 b dvmCheckBefore @ (dPC,dFP,self) tail call 10078 10079 /* ------------------------------ */ 10080 .balign 64 10081 .L_ALT_OP_RETURN_OBJECT: /* 0x11 */ 10082 /* File: armv5te/alt_stub.S */ 10083 /* 10084 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10085 * any interesting requests and then jump to the real instruction 10086 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10087 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10088 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10089 * bail to the real handler if breakFlags==0. 10090 */ 10091 ldrb r3, [rSELF, #offThread_breakFlags] 10092 adrl lr, dvmAsmInstructionStart + (17 * 64) 10093 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10094 cmp r3, #0 10095 bxeq lr @ nothing to do - jump to real handler 10096 EXPORT_PC() 10097 mov r0, rPC @ arg0 10098 mov r1, rFP @ arg1 10099 mov r2, rSELF @ arg2 10100 b dvmCheckBefore @ (dPC,dFP,self) tail call 10101 10102 /* ------------------------------ */ 10103 .balign 64 10104 .L_ALT_OP_CONST_4: /* 0x12 */ 10105 /* File: armv5te/alt_stub.S */ 10106 /* 10107 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10108 * any interesting requests and then jump to the real instruction 10109 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10110 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10111 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10112 * bail to the real handler if breakFlags==0. 10113 */ 10114 ldrb r3, [rSELF, #offThread_breakFlags] 10115 adrl lr, dvmAsmInstructionStart + (18 * 64) 10116 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10117 cmp r3, #0 10118 bxeq lr @ nothing to do - jump to real handler 10119 EXPORT_PC() 10120 mov r0, rPC @ arg0 10121 mov r1, rFP @ arg1 10122 mov r2, rSELF @ arg2 10123 b dvmCheckBefore @ (dPC,dFP,self) tail call 10124 10125 /* ------------------------------ */ 10126 .balign 64 10127 .L_ALT_OP_CONST_16: /* 0x13 */ 10128 /* File: armv5te/alt_stub.S */ 10129 /* 10130 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10131 * any interesting requests and then jump to the real instruction 10132 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10133 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10134 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10135 * bail to the real handler if breakFlags==0. 10136 */ 10137 ldrb r3, [rSELF, #offThread_breakFlags] 10138 adrl lr, dvmAsmInstructionStart + (19 * 64) 10139 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10140 cmp r3, #0 10141 bxeq lr @ nothing to do - jump to real handler 10142 EXPORT_PC() 10143 mov r0, rPC @ arg0 10144 mov r1, rFP @ arg1 10145 mov r2, rSELF @ arg2 10146 b dvmCheckBefore @ (dPC,dFP,self) tail call 10147 10148 /* ------------------------------ */ 10149 .balign 64 10150 .L_ALT_OP_CONST: /* 0x14 */ 10151 /* File: armv5te/alt_stub.S */ 10152 /* 10153 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10154 * any interesting requests and then jump to the real instruction 10155 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10156 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10157 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10158 * bail to the real handler if breakFlags==0. 10159 */ 10160 ldrb r3, [rSELF, #offThread_breakFlags] 10161 adrl lr, dvmAsmInstructionStart + (20 * 64) 10162 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10163 cmp r3, #0 10164 bxeq lr @ nothing to do - jump to real handler 10165 EXPORT_PC() 10166 mov r0, rPC @ arg0 10167 mov r1, rFP @ arg1 10168 mov r2, rSELF @ arg2 10169 b dvmCheckBefore @ (dPC,dFP,self) tail call 10170 10171 /* ------------------------------ */ 10172 .balign 64 10173 .L_ALT_OP_CONST_HIGH16: /* 0x15 */ 10174 /* File: armv5te/alt_stub.S */ 10175 /* 10176 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10177 * any interesting requests and then jump to the real instruction 10178 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10179 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10180 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10181 * bail to the real handler if breakFlags==0. 10182 */ 10183 ldrb r3, [rSELF, #offThread_breakFlags] 10184 adrl lr, dvmAsmInstructionStart + (21 * 64) 10185 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10186 cmp r3, #0 10187 bxeq lr @ nothing to do - jump to real handler 10188 EXPORT_PC() 10189 mov r0, rPC @ arg0 10190 mov r1, rFP @ arg1 10191 mov r2, rSELF @ arg2 10192 b dvmCheckBefore @ (dPC,dFP,self) tail call 10193 10194 /* ------------------------------ */ 10195 .balign 64 10196 .L_ALT_OP_CONST_WIDE_16: /* 0x16 */ 10197 /* File: armv5te/alt_stub.S */ 10198 /* 10199 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10200 * any interesting requests and then jump to the real instruction 10201 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10202 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10203 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10204 * bail to the real handler if breakFlags==0. 10205 */ 10206 ldrb r3, [rSELF, #offThread_breakFlags] 10207 adrl lr, dvmAsmInstructionStart + (22 * 64) 10208 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10209 cmp r3, #0 10210 bxeq lr @ nothing to do - jump to real handler 10211 EXPORT_PC() 10212 mov r0, rPC @ arg0 10213 mov r1, rFP @ arg1 10214 mov r2, rSELF @ arg2 10215 b dvmCheckBefore @ (dPC,dFP,self) tail call 10216 10217 /* ------------------------------ */ 10218 .balign 64 10219 .L_ALT_OP_CONST_WIDE_32: /* 0x17 */ 10220 /* File: armv5te/alt_stub.S */ 10221 /* 10222 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10223 * any interesting requests and then jump to the real instruction 10224 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10225 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10226 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10227 * bail to the real handler if breakFlags==0. 10228 */ 10229 ldrb r3, [rSELF, #offThread_breakFlags] 10230 adrl lr, dvmAsmInstructionStart + (23 * 64) 10231 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10232 cmp r3, #0 10233 bxeq lr @ nothing to do - jump to real handler 10234 EXPORT_PC() 10235 mov r0, rPC @ arg0 10236 mov r1, rFP @ arg1 10237 mov r2, rSELF @ arg2 10238 b dvmCheckBefore @ (dPC,dFP,self) tail call 10239 10240 /* ------------------------------ */ 10241 .balign 64 10242 .L_ALT_OP_CONST_WIDE: /* 0x18 */ 10243 /* File: armv5te/alt_stub.S */ 10244 /* 10245 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10246 * any interesting requests and then jump to the real instruction 10247 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10248 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10249 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10250 * bail to the real handler if breakFlags==0. 10251 */ 10252 ldrb r3, [rSELF, #offThread_breakFlags] 10253 adrl lr, dvmAsmInstructionStart + (24 * 64) 10254 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10255 cmp r3, #0 10256 bxeq lr @ nothing to do - jump to real handler 10257 EXPORT_PC() 10258 mov r0, rPC @ arg0 10259 mov r1, rFP @ arg1 10260 mov r2, rSELF @ arg2 10261 b dvmCheckBefore @ (dPC,dFP,self) tail call 10262 10263 /* ------------------------------ */ 10264 .balign 64 10265 .L_ALT_OP_CONST_WIDE_HIGH16: /* 0x19 */ 10266 /* File: armv5te/alt_stub.S */ 10267 /* 10268 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10269 * any interesting requests and then jump to the real instruction 10270 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10271 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10272 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10273 * bail to the real handler if breakFlags==0. 10274 */ 10275 ldrb r3, [rSELF, #offThread_breakFlags] 10276 adrl lr, dvmAsmInstructionStart + (25 * 64) 10277 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10278 cmp r3, #0 10279 bxeq lr @ nothing to do - jump to real handler 10280 EXPORT_PC() 10281 mov r0, rPC @ arg0 10282 mov r1, rFP @ arg1 10283 mov r2, rSELF @ arg2 10284 b dvmCheckBefore @ (dPC,dFP,self) tail call 10285 10286 /* ------------------------------ */ 10287 .balign 64 10288 .L_ALT_OP_CONST_STRING: /* 0x1a */ 10289 /* File: armv5te/alt_stub.S */ 10290 /* 10291 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10292 * any interesting requests and then jump to the real instruction 10293 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10294 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10295 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10296 * bail to the real handler if breakFlags==0. 10297 */ 10298 ldrb r3, [rSELF, #offThread_breakFlags] 10299 adrl lr, dvmAsmInstructionStart + (26 * 64) 10300 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10301 cmp r3, #0 10302 bxeq lr @ nothing to do - jump to real handler 10303 EXPORT_PC() 10304 mov r0, rPC @ arg0 10305 mov r1, rFP @ arg1 10306 mov r2, rSELF @ arg2 10307 b dvmCheckBefore @ (dPC,dFP,self) tail call 10308 10309 /* ------------------------------ */ 10310 .balign 64 10311 .L_ALT_OP_CONST_STRING_JUMBO: /* 0x1b */ 10312 /* File: armv5te/alt_stub.S */ 10313 /* 10314 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10315 * any interesting requests and then jump to the real instruction 10316 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10317 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10318 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10319 * bail to the real handler if breakFlags==0. 10320 */ 10321 ldrb r3, [rSELF, #offThread_breakFlags] 10322 adrl lr, dvmAsmInstructionStart + (27 * 64) 10323 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10324 cmp r3, #0 10325 bxeq lr @ nothing to do - jump to real handler 10326 EXPORT_PC() 10327 mov r0, rPC @ arg0 10328 mov r1, rFP @ arg1 10329 mov r2, rSELF @ arg2 10330 b dvmCheckBefore @ (dPC,dFP,self) tail call 10331 10332 /* ------------------------------ */ 10333 .balign 64 10334 .L_ALT_OP_CONST_CLASS: /* 0x1c */ 10335 /* File: armv5te/alt_stub.S */ 10336 /* 10337 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10338 * any interesting requests and then jump to the real instruction 10339 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10340 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10341 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10342 * bail to the real handler if breakFlags==0. 10343 */ 10344 ldrb r3, [rSELF, #offThread_breakFlags] 10345 adrl lr, dvmAsmInstructionStart + (28 * 64) 10346 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10347 cmp r3, #0 10348 bxeq lr @ nothing to do - jump to real handler 10349 EXPORT_PC() 10350 mov r0, rPC @ arg0 10351 mov r1, rFP @ arg1 10352 mov r2, rSELF @ arg2 10353 b dvmCheckBefore @ (dPC,dFP,self) tail call 10354 10355 /* ------------------------------ */ 10356 .balign 64 10357 .L_ALT_OP_MONITOR_ENTER: /* 0x1d */ 10358 /* File: armv5te/alt_stub.S */ 10359 /* 10360 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10361 * any interesting requests and then jump to the real instruction 10362 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10363 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10364 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10365 * bail to the real handler if breakFlags==0. 10366 */ 10367 ldrb r3, [rSELF, #offThread_breakFlags] 10368 adrl lr, dvmAsmInstructionStart + (29 * 64) 10369 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10370 cmp r3, #0 10371 bxeq lr @ nothing to do - jump to real handler 10372 EXPORT_PC() 10373 mov r0, rPC @ arg0 10374 mov r1, rFP @ arg1 10375 mov r2, rSELF @ arg2 10376 b dvmCheckBefore @ (dPC,dFP,self) tail call 10377 10378 /* ------------------------------ */ 10379 .balign 64 10380 .L_ALT_OP_MONITOR_EXIT: /* 0x1e */ 10381 /* File: armv5te/alt_stub.S */ 10382 /* 10383 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10384 * any interesting requests and then jump to the real instruction 10385 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10386 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10387 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10388 * bail to the real handler if breakFlags==0. 10389 */ 10390 ldrb r3, [rSELF, #offThread_breakFlags] 10391 adrl lr, dvmAsmInstructionStart + (30 * 64) 10392 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10393 cmp r3, #0 10394 bxeq lr @ nothing to do - jump to real handler 10395 EXPORT_PC() 10396 mov r0, rPC @ arg0 10397 mov r1, rFP @ arg1 10398 mov r2, rSELF @ arg2 10399 b dvmCheckBefore @ (dPC,dFP,self) tail call 10400 10401 /* ------------------------------ */ 10402 .balign 64 10403 .L_ALT_OP_CHECK_CAST: /* 0x1f */ 10404 /* File: armv5te/alt_stub.S */ 10405 /* 10406 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10407 * any interesting requests and then jump to the real instruction 10408 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10409 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10410 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10411 * bail to the real handler if breakFlags==0. 10412 */ 10413 ldrb r3, [rSELF, #offThread_breakFlags] 10414 adrl lr, dvmAsmInstructionStart + (31 * 64) 10415 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10416 cmp r3, #0 10417 bxeq lr @ nothing to do - jump to real handler 10418 EXPORT_PC() 10419 mov r0, rPC @ arg0 10420 mov r1, rFP @ arg1 10421 mov r2, rSELF @ arg2 10422 b dvmCheckBefore @ (dPC,dFP,self) tail call 10423 10424 /* ------------------------------ */ 10425 .balign 64 10426 .L_ALT_OP_INSTANCE_OF: /* 0x20 */ 10427 /* File: armv5te/alt_stub.S */ 10428 /* 10429 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10430 * any interesting requests and then jump to the real instruction 10431 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10432 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10433 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10434 * bail to the real handler if breakFlags==0. 10435 */ 10436 ldrb r3, [rSELF, #offThread_breakFlags] 10437 adrl lr, dvmAsmInstructionStart + (32 * 64) 10438 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10439 cmp r3, #0 10440 bxeq lr @ nothing to do - jump to real handler 10441 EXPORT_PC() 10442 mov r0, rPC @ arg0 10443 mov r1, rFP @ arg1 10444 mov r2, rSELF @ arg2 10445 b dvmCheckBefore @ (dPC,dFP,self) tail call 10446 10447 /* ------------------------------ */ 10448 .balign 64 10449 .L_ALT_OP_ARRAY_LENGTH: /* 0x21 */ 10450 /* File: armv5te/alt_stub.S */ 10451 /* 10452 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10453 * any interesting requests and then jump to the real instruction 10454 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10455 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10456 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10457 * bail to the real handler if breakFlags==0. 10458 */ 10459 ldrb r3, [rSELF, #offThread_breakFlags] 10460 adrl lr, dvmAsmInstructionStart + (33 * 64) 10461 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10462 cmp r3, #0 10463 bxeq lr @ nothing to do - jump to real handler 10464 EXPORT_PC() 10465 mov r0, rPC @ arg0 10466 mov r1, rFP @ arg1 10467 mov r2, rSELF @ arg2 10468 b dvmCheckBefore @ (dPC,dFP,self) tail call 10469 10470 /* ------------------------------ */ 10471 .balign 64 10472 .L_ALT_OP_NEW_INSTANCE: /* 0x22 */ 10473 /* File: armv5te/alt_stub.S */ 10474 /* 10475 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10476 * any interesting requests and then jump to the real instruction 10477 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10478 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10479 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10480 * bail to the real handler if breakFlags==0. 10481 */ 10482 ldrb r3, [rSELF, #offThread_breakFlags] 10483 adrl lr, dvmAsmInstructionStart + (34 * 64) 10484 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10485 cmp r3, #0 10486 bxeq lr @ nothing to do - jump to real handler 10487 EXPORT_PC() 10488 mov r0, rPC @ arg0 10489 mov r1, rFP @ arg1 10490 mov r2, rSELF @ arg2 10491 b dvmCheckBefore @ (dPC,dFP,self) tail call 10492 10493 /* ------------------------------ */ 10494 .balign 64 10495 .L_ALT_OP_NEW_ARRAY: /* 0x23 */ 10496 /* File: armv5te/alt_stub.S */ 10497 /* 10498 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10499 * any interesting requests and then jump to the real instruction 10500 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10501 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10502 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10503 * bail to the real handler if breakFlags==0. 10504 */ 10505 ldrb r3, [rSELF, #offThread_breakFlags] 10506 adrl lr, dvmAsmInstructionStart + (35 * 64) 10507 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10508 cmp r3, #0 10509 bxeq lr @ nothing to do - jump to real handler 10510 EXPORT_PC() 10511 mov r0, rPC @ arg0 10512 mov r1, rFP @ arg1 10513 mov r2, rSELF @ arg2 10514 b dvmCheckBefore @ (dPC,dFP,self) tail call 10515 10516 /* ------------------------------ */ 10517 .balign 64 10518 .L_ALT_OP_FILLED_NEW_ARRAY: /* 0x24 */ 10519 /* File: armv5te/alt_stub.S */ 10520 /* 10521 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10522 * any interesting requests and then jump to the real instruction 10523 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10524 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10525 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10526 * bail to the real handler if breakFlags==0. 10527 */ 10528 ldrb r3, [rSELF, #offThread_breakFlags] 10529 adrl lr, dvmAsmInstructionStart + (36 * 64) 10530 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10531 cmp r3, #0 10532 bxeq lr @ nothing to do - jump to real handler 10533 EXPORT_PC() 10534 mov r0, rPC @ arg0 10535 mov r1, rFP @ arg1 10536 mov r2, rSELF @ arg2 10537 b dvmCheckBefore @ (dPC,dFP,self) tail call 10538 10539 /* ------------------------------ */ 10540 .balign 64 10541 .L_ALT_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 10542 /* File: armv5te/alt_stub.S */ 10543 /* 10544 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10545 * any interesting requests and then jump to the real instruction 10546 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10547 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10548 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10549 * bail to the real handler if breakFlags==0. 10550 */ 10551 ldrb r3, [rSELF, #offThread_breakFlags] 10552 adrl lr, dvmAsmInstructionStart + (37 * 64) 10553 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10554 cmp r3, #0 10555 bxeq lr @ nothing to do - jump to real handler 10556 EXPORT_PC() 10557 mov r0, rPC @ arg0 10558 mov r1, rFP @ arg1 10559 mov r2, rSELF @ arg2 10560 b dvmCheckBefore @ (dPC,dFP,self) tail call 10561 10562 /* ------------------------------ */ 10563 .balign 64 10564 .L_ALT_OP_FILL_ARRAY_DATA: /* 0x26 */ 10565 /* File: armv5te/alt_stub.S */ 10566 /* 10567 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10568 * any interesting requests and then jump to the real instruction 10569 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10570 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10571 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10572 * bail to the real handler if breakFlags==0. 10573 */ 10574 ldrb r3, [rSELF, #offThread_breakFlags] 10575 adrl lr, dvmAsmInstructionStart + (38 * 64) 10576 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10577 cmp r3, #0 10578 bxeq lr @ nothing to do - jump to real handler 10579 EXPORT_PC() 10580 mov r0, rPC @ arg0 10581 mov r1, rFP @ arg1 10582 mov r2, rSELF @ arg2 10583 b dvmCheckBefore @ (dPC,dFP,self) tail call 10584 10585 /* ------------------------------ */ 10586 .balign 64 10587 .L_ALT_OP_THROW: /* 0x27 */ 10588 /* File: armv5te/alt_stub.S */ 10589 /* 10590 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10591 * any interesting requests and then jump to the real instruction 10592 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10593 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10594 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10595 * bail to the real handler if breakFlags==0. 10596 */ 10597 ldrb r3, [rSELF, #offThread_breakFlags] 10598 adrl lr, dvmAsmInstructionStart + (39 * 64) 10599 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10600 cmp r3, #0 10601 bxeq lr @ nothing to do - jump to real handler 10602 EXPORT_PC() 10603 mov r0, rPC @ arg0 10604 mov r1, rFP @ arg1 10605 mov r2, rSELF @ arg2 10606 b dvmCheckBefore @ (dPC,dFP,self) tail call 10607 10608 /* ------------------------------ */ 10609 .balign 64 10610 .L_ALT_OP_GOTO: /* 0x28 */ 10611 /* File: armv5te/alt_stub.S */ 10612 /* 10613 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10614 * any interesting requests and then jump to the real instruction 10615 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10616 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10617 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10618 * bail to the real handler if breakFlags==0. 10619 */ 10620 ldrb r3, [rSELF, #offThread_breakFlags] 10621 adrl lr, dvmAsmInstructionStart + (40 * 64) 10622 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10623 cmp r3, #0 10624 bxeq lr @ nothing to do - jump to real handler 10625 EXPORT_PC() 10626 mov r0, rPC @ arg0 10627 mov r1, rFP @ arg1 10628 mov r2, rSELF @ arg2 10629 b dvmCheckBefore @ (dPC,dFP,self) tail call 10630 10631 /* ------------------------------ */ 10632 .balign 64 10633 .L_ALT_OP_GOTO_16: /* 0x29 */ 10634 /* File: armv5te/alt_stub.S */ 10635 /* 10636 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10637 * any interesting requests and then jump to the real instruction 10638 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10639 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10640 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10641 * bail to the real handler if breakFlags==0. 10642 */ 10643 ldrb r3, [rSELF, #offThread_breakFlags] 10644 adrl lr, dvmAsmInstructionStart + (41 * 64) 10645 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10646 cmp r3, #0 10647 bxeq lr @ nothing to do - jump to real handler 10648 EXPORT_PC() 10649 mov r0, rPC @ arg0 10650 mov r1, rFP @ arg1 10651 mov r2, rSELF @ arg2 10652 b dvmCheckBefore @ (dPC,dFP,self) tail call 10653 10654 /* ------------------------------ */ 10655 .balign 64 10656 .L_ALT_OP_GOTO_32: /* 0x2a */ 10657 /* File: armv5te/alt_stub.S */ 10658 /* 10659 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10660 * any interesting requests and then jump to the real instruction 10661 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10662 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10663 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10664 * bail to the real handler if breakFlags==0. 10665 */ 10666 ldrb r3, [rSELF, #offThread_breakFlags] 10667 adrl lr, dvmAsmInstructionStart + (42 * 64) 10668 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10669 cmp r3, #0 10670 bxeq lr @ nothing to do - jump to real handler 10671 EXPORT_PC() 10672 mov r0, rPC @ arg0 10673 mov r1, rFP @ arg1 10674 mov r2, rSELF @ arg2 10675 b dvmCheckBefore @ (dPC,dFP,self) tail call 10676 10677 /* ------------------------------ */ 10678 .balign 64 10679 .L_ALT_OP_PACKED_SWITCH: /* 0x2b */ 10680 /* File: armv5te/alt_stub.S */ 10681 /* 10682 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10683 * any interesting requests and then jump to the real instruction 10684 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10685 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10686 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10687 * bail to the real handler if breakFlags==0. 10688 */ 10689 ldrb r3, [rSELF, #offThread_breakFlags] 10690 adrl lr, dvmAsmInstructionStart + (43 * 64) 10691 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10692 cmp r3, #0 10693 bxeq lr @ nothing to do - jump to real handler 10694 EXPORT_PC() 10695 mov r0, rPC @ arg0 10696 mov r1, rFP @ arg1 10697 mov r2, rSELF @ arg2 10698 b dvmCheckBefore @ (dPC,dFP,self) tail call 10699 10700 /* ------------------------------ */ 10701 .balign 64 10702 .L_ALT_OP_SPARSE_SWITCH: /* 0x2c */ 10703 /* File: armv5te/alt_stub.S */ 10704 /* 10705 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10706 * any interesting requests and then jump to the real instruction 10707 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10708 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10709 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10710 * bail to the real handler if breakFlags==0. 10711 */ 10712 ldrb r3, [rSELF, #offThread_breakFlags] 10713 adrl lr, dvmAsmInstructionStart + (44 * 64) 10714 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10715 cmp r3, #0 10716 bxeq lr @ nothing to do - jump to real handler 10717 EXPORT_PC() 10718 mov r0, rPC @ arg0 10719 mov r1, rFP @ arg1 10720 mov r2, rSELF @ arg2 10721 b dvmCheckBefore @ (dPC,dFP,self) tail call 10722 10723 /* ------------------------------ */ 10724 .balign 64 10725 .L_ALT_OP_CMPL_FLOAT: /* 0x2d */ 10726 /* File: armv5te/alt_stub.S */ 10727 /* 10728 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10729 * any interesting requests and then jump to the real instruction 10730 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10731 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10732 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10733 * bail to the real handler if breakFlags==0. 10734 */ 10735 ldrb r3, [rSELF, #offThread_breakFlags] 10736 adrl lr, dvmAsmInstructionStart + (45 * 64) 10737 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10738 cmp r3, #0 10739 bxeq lr @ nothing to do - jump to real handler 10740 EXPORT_PC() 10741 mov r0, rPC @ arg0 10742 mov r1, rFP @ arg1 10743 mov r2, rSELF @ arg2 10744 b dvmCheckBefore @ (dPC,dFP,self) tail call 10745 10746 /* ------------------------------ */ 10747 .balign 64 10748 .L_ALT_OP_CMPG_FLOAT: /* 0x2e */ 10749 /* File: armv5te/alt_stub.S */ 10750 /* 10751 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10752 * any interesting requests and then jump to the real instruction 10753 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10754 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10755 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10756 * bail to the real handler if breakFlags==0. 10757 */ 10758 ldrb r3, [rSELF, #offThread_breakFlags] 10759 adrl lr, dvmAsmInstructionStart + (46 * 64) 10760 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10761 cmp r3, #0 10762 bxeq lr @ nothing to do - jump to real handler 10763 EXPORT_PC() 10764 mov r0, rPC @ arg0 10765 mov r1, rFP @ arg1 10766 mov r2, rSELF @ arg2 10767 b dvmCheckBefore @ (dPC,dFP,self) tail call 10768 10769 /* ------------------------------ */ 10770 .balign 64 10771 .L_ALT_OP_CMPL_DOUBLE: /* 0x2f */ 10772 /* File: armv5te/alt_stub.S */ 10773 /* 10774 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10775 * any interesting requests and then jump to the real instruction 10776 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10777 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10778 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10779 * bail to the real handler if breakFlags==0. 10780 */ 10781 ldrb r3, [rSELF, #offThread_breakFlags] 10782 adrl lr, dvmAsmInstructionStart + (47 * 64) 10783 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10784 cmp r3, #0 10785 bxeq lr @ nothing to do - jump to real handler 10786 EXPORT_PC() 10787 mov r0, rPC @ arg0 10788 mov r1, rFP @ arg1 10789 mov r2, rSELF @ arg2 10790 b dvmCheckBefore @ (dPC,dFP,self) tail call 10791 10792 /* ------------------------------ */ 10793 .balign 64 10794 .L_ALT_OP_CMPG_DOUBLE: /* 0x30 */ 10795 /* File: armv5te/alt_stub.S */ 10796 /* 10797 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10798 * any interesting requests and then jump to the real instruction 10799 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10800 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10801 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10802 * bail to the real handler if breakFlags==0. 10803 */ 10804 ldrb r3, [rSELF, #offThread_breakFlags] 10805 adrl lr, dvmAsmInstructionStart + (48 * 64) 10806 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10807 cmp r3, #0 10808 bxeq lr @ nothing to do - jump to real handler 10809 EXPORT_PC() 10810 mov r0, rPC @ arg0 10811 mov r1, rFP @ arg1 10812 mov r2, rSELF @ arg2 10813 b dvmCheckBefore @ (dPC,dFP,self) tail call 10814 10815 /* ------------------------------ */ 10816 .balign 64 10817 .L_ALT_OP_CMP_LONG: /* 0x31 */ 10818 /* File: armv5te/alt_stub.S */ 10819 /* 10820 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10821 * any interesting requests and then jump to the real instruction 10822 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10823 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10824 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10825 * bail to the real handler if breakFlags==0. 10826 */ 10827 ldrb r3, [rSELF, #offThread_breakFlags] 10828 adrl lr, dvmAsmInstructionStart + (49 * 64) 10829 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10830 cmp r3, #0 10831 bxeq lr @ nothing to do - jump to real handler 10832 EXPORT_PC() 10833 mov r0, rPC @ arg0 10834 mov r1, rFP @ arg1 10835 mov r2, rSELF @ arg2 10836 b dvmCheckBefore @ (dPC,dFP,self) tail call 10837 10838 /* ------------------------------ */ 10839 .balign 64 10840 .L_ALT_OP_IF_EQ: /* 0x32 */ 10841 /* File: armv5te/alt_stub.S */ 10842 /* 10843 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10844 * any interesting requests and then jump to the real instruction 10845 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10846 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10847 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10848 * bail to the real handler if breakFlags==0. 10849 */ 10850 ldrb r3, [rSELF, #offThread_breakFlags] 10851 adrl lr, dvmAsmInstructionStart + (50 * 64) 10852 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10853 cmp r3, #0 10854 bxeq lr @ nothing to do - jump to real handler 10855 EXPORT_PC() 10856 mov r0, rPC @ arg0 10857 mov r1, rFP @ arg1 10858 mov r2, rSELF @ arg2 10859 b dvmCheckBefore @ (dPC,dFP,self) tail call 10860 10861 /* ------------------------------ */ 10862 .balign 64 10863 .L_ALT_OP_IF_NE: /* 0x33 */ 10864 /* File: armv5te/alt_stub.S */ 10865 /* 10866 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10867 * any interesting requests and then jump to the real instruction 10868 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10869 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10870 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10871 * bail to the real handler if breakFlags==0. 10872 */ 10873 ldrb r3, [rSELF, #offThread_breakFlags] 10874 adrl lr, dvmAsmInstructionStart + (51 * 64) 10875 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10876 cmp r3, #0 10877 bxeq lr @ nothing to do - jump to real handler 10878 EXPORT_PC() 10879 mov r0, rPC @ arg0 10880 mov r1, rFP @ arg1 10881 mov r2, rSELF @ arg2 10882 b dvmCheckBefore @ (dPC,dFP,self) tail call 10883 10884 /* ------------------------------ */ 10885 .balign 64 10886 .L_ALT_OP_IF_LT: /* 0x34 */ 10887 /* File: armv5te/alt_stub.S */ 10888 /* 10889 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10890 * any interesting requests and then jump to the real instruction 10891 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10892 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10893 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10894 * bail to the real handler if breakFlags==0. 10895 */ 10896 ldrb r3, [rSELF, #offThread_breakFlags] 10897 adrl lr, dvmAsmInstructionStart + (52 * 64) 10898 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10899 cmp r3, #0 10900 bxeq lr @ nothing to do - jump to real handler 10901 EXPORT_PC() 10902 mov r0, rPC @ arg0 10903 mov r1, rFP @ arg1 10904 mov r2, rSELF @ arg2 10905 b dvmCheckBefore @ (dPC,dFP,self) tail call 10906 10907 /* ------------------------------ */ 10908 .balign 64 10909 .L_ALT_OP_IF_GE: /* 0x35 */ 10910 /* File: armv5te/alt_stub.S */ 10911 /* 10912 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10913 * any interesting requests and then jump to the real instruction 10914 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10915 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10916 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10917 * bail to the real handler if breakFlags==0. 10918 */ 10919 ldrb r3, [rSELF, #offThread_breakFlags] 10920 adrl lr, dvmAsmInstructionStart + (53 * 64) 10921 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10922 cmp r3, #0 10923 bxeq lr @ nothing to do - jump to real handler 10924 EXPORT_PC() 10925 mov r0, rPC @ arg0 10926 mov r1, rFP @ arg1 10927 mov r2, rSELF @ arg2 10928 b dvmCheckBefore @ (dPC,dFP,self) tail call 10929 10930 /* ------------------------------ */ 10931 .balign 64 10932 .L_ALT_OP_IF_GT: /* 0x36 */ 10933 /* File: armv5te/alt_stub.S */ 10934 /* 10935 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10936 * any interesting requests and then jump to the real instruction 10937 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10938 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10939 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10940 * bail to the real handler if breakFlags==0. 10941 */ 10942 ldrb r3, [rSELF, #offThread_breakFlags] 10943 adrl lr, dvmAsmInstructionStart + (54 * 64) 10944 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10945 cmp r3, #0 10946 bxeq lr @ nothing to do - jump to real handler 10947 EXPORT_PC() 10948 mov r0, rPC @ arg0 10949 mov r1, rFP @ arg1 10950 mov r2, rSELF @ arg2 10951 b dvmCheckBefore @ (dPC,dFP,self) tail call 10952 10953 /* ------------------------------ */ 10954 .balign 64 10955 .L_ALT_OP_IF_LE: /* 0x37 */ 10956 /* File: armv5te/alt_stub.S */ 10957 /* 10958 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10959 * any interesting requests and then jump to the real instruction 10960 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10961 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10962 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10963 * bail to the real handler if breakFlags==0. 10964 */ 10965 ldrb r3, [rSELF, #offThread_breakFlags] 10966 adrl lr, dvmAsmInstructionStart + (55 * 64) 10967 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10968 cmp r3, #0 10969 bxeq lr @ nothing to do - jump to real handler 10970 EXPORT_PC() 10971 mov r0, rPC @ arg0 10972 mov r1, rFP @ arg1 10973 mov r2, rSELF @ arg2 10974 b dvmCheckBefore @ (dPC,dFP,self) tail call 10975 10976 /* ------------------------------ */ 10977 .balign 64 10978 .L_ALT_OP_IF_EQZ: /* 0x38 */ 10979 /* File: armv5te/alt_stub.S */ 10980 /* 10981 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10982 * any interesting requests and then jump to the real instruction 10983 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10984 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10985 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10986 * bail to the real handler if breakFlags==0. 10987 */ 10988 ldrb r3, [rSELF, #offThread_breakFlags] 10989 adrl lr, dvmAsmInstructionStart + (56 * 64) 10990 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10991 cmp r3, #0 10992 bxeq lr @ nothing to do - jump to real handler 10993 EXPORT_PC() 10994 mov r0, rPC @ arg0 10995 mov r1, rFP @ arg1 10996 mov r2, rSELF @ arg2 10997 b dvmCheckBefore @ (dPC,dFP,self) tail call 10998 10999 /* ------------------------------ */ 11000 .balign 64 11001 .L_ALT_OP_IF_NEZ: /* 0x39 */ 11002 /* File: armv5te/alt_stub.S */ 11003 /* 11004 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11005 * any interesting requests and then jump to the real instruction 11006 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11007 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11008 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11009 * bail to the real handler if breakFlags==0. 11010 */ 11011 ldrb r3, [rSELF, #offThread_breakFlags] 11012 adrl lr, dvmAsmInstructionStart + (57 * 64) 11013 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11014 cmp r3, #0 11015 bxeq lr @ nothing to do - jump to real handler 11016 EXPORT_PC() 11017 mov r0, rPC @ arg0 11018 mov r1, rFP @ arg1 11019 mov r2, rSELF @ arg2 11020 b dvmCheckBefore @ (dPC,dFP,self) tail call 11021 11022 /* ------------------------------ */ 11023 .balign 64 11024 .L_ALT_OP_IF_LTZ: /* 0x3a */ 11025 /* File: armv5te/alt_stub.S */ 11026 /* 11027 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11028 * any interesting requests and then jump to the real instruction 11029 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11030 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11031 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11032 * bail to the real handler if breakFlags==0. 11033 */ 11034 ldrb r3, [rSELF, #offThread_breakFlags] 11035 adrl lr, dvmAsmInstructionStart + (58 * 64) 11036 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11037 cmp r3, #0 11038 bxeq lr @ nothing to do - jump to real handler 11039 EXPORT_PC() 11040 mov r0, rPC @ arg0 11041 mov r1, rFP @ arg1 11042 mov r2, rSELF @ arg2 11043 b dvmCheckBefore @ (dPC,dFP,self) tail call 11044 11045 /* ------------------------------ */ 11046 .balign 64 11047 .L_ALT_OP_IF_GEZ: /* 0x3b */ 11048 /* File: armv5te/alt_stub.S */ 11049 /* 11050 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11051 * any interesting requests and then jump to the real instruction 11052 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11053 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11054 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11055 * bail to the real handler if breakFlags==0. 11056 */ 11057 ldrb r3, [rSELF, #offThread_breakFlags] 11058 adrl lr, dvmAsmInstructionStart + (59 * 64) 11059 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11060 cmp r3, #0 11061 bxeq lr @ nothing to do - jump to real handler 11062 EXPORT_PC() 11063 mov r0, rPC @ arg0 11064 mov r1, rFP @ arg1 11065 mov r2, rSELF @ arg2 11066 b dvmCheckBefore @ (dPC,dFP,self) tail call 11067 11068 /* ------------------------------ */ 11069 .balign 64 11070 .L_ALT_OP_IF_GTZ: /* 0x3c */ 11071 /* File: armv5te/alt_stub.S */ 11072 /* 11073 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11074 * any interesting requests and then jump to the real instruction 11075 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11076 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11077 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11078 * bail to the real handler if breakFlags==0. 11079 */ 11080 ldrb r3, [rSELF, #offThread_breakFlags] 11081 adrl lr, dvmAsmInstructionStart + (60 * 64) 11082 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11083 cmp r3, #0 11084 bxeq lr @ nothing to do - jump to real handler 11085 EXPORT_PC() 11086 mov r0, rPC @ arg0 11087 mov r1, rFP @ arg1 11088 mov r2, rSELF @ arg2 11089 b dvmCheckBefore @ (dPC,dFP,self) tail call 11090 11091 /* ------------------------------ */ 11092 .balign 64 11093 .L_ALT_OP_IF_LEZ: /* 0x3d */ 11094 /* File: armv5te/alt_stub.S */ 11095 /* 11096 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11097 * any interesting requests and then jump to the real instruction 11098 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11099 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11100 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11101 * bail to the real handler if breakFlags==0. 11102 */ 11103 ldrb r3, [rSELF, #offThread_breakFlags] 11104 adrl lr, dvmAsmInstructionStart + (61 * 64) 11105 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11106 cmp r3, #0 11107 bxeq lr @ nothing to do - jump to real handler 11108 EXPORT_PC() 11109 mov r0, rPC @ arg0 11110 mov r1, rFP @ arg1 11111 mov r2, rSELF @ arg2 11112 b dvmCheckBefore @ (dPC,dFP,self) tail call 11113 11114 /* ------------------------------ */ 11115 .balign 64 11116 .L_ALT_OP_UNUSED_3E: /* 0x3e */ 11117 /* File: armv5te/alt_stub.S */ 11118 /* 11119 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11120 * any interesting requests and then jump to the real instruction 11121 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11122 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11123 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11124 * bail to the real handler if breakFlags==0. 11125 */ 11126 ldrb r3, [rSELF, #offThread_breakFlags] 11127 adrl lr, dvmAsmInstructionStart + (62 * 64) 11128 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11129 cmp r3, #0 11130 bxeq lr @ nothing to do - jump to real handler 11131 EXPORT_PC() 11132 mov r0, rPC @ arg0 11133 mov r1, rFP @ arg1 11134 mov r2, rSELF @ arg2 11135 b dvmCheckBefore @ (dPC,dFP,self) tail call 11136 11137 /* ------------------------------ */ 11138 .balign 64 11139 .L_ALT_OP_UNUSED_3F: /* 0x3f */ 11140 /* File: armv5te/alt_stub.S */ 11141 /* 11142 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11143 * any interesting requests and then jump to the real instruction 11144 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11145 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11146 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11147 * bail to the real handler if breakFlags==0. 11148 */ 11149 ldrb r3, [rSELF, #offThread_breakFlags] 11150 adrl lr, dvmAsmInstructionStart + (63 * 64) 11151 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11152 cmp r3, #0 11153 bxeq lr @ nothing to do - jump to real handler 11154 EXPORT_PC() 11155 mov r0, rPC @ arg0 11156 mov r1, rFP @ arg1 11157 mov r2, rSELF @ arg2 11158 b dvmCheckBefore @ (dPC,dFP,self) tail call 11159 11160 /* ------------------------------ */ 11161 .balign 64 11162 .L_ALT_OP_UNUSED_40: /* 0x40 */ 11163 /* File: armv5te/alt_stub.S */ 11164 /* 11165 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11166 * any interesting requests and then jump to the real instruction 11167 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11168 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11169 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11170 * bail to the real handler if breakFlags==0. 11171 */ 11172 ldrb r3, [rSELF, #offThread_breakFlags] 11173 adrl lr, dvmAsmInstructionStart + (64 * 64) 11174 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11175 cmp r3, #0 11176 bxeq lr @ nothing to do - jump to real handler 11177 EXPORT_PC() 11178 mov r0, rPC @ arg0 11179 mov r1, rFP @ arg1 11180 mov r2, rSELF @ arg2 11181 b dvmCheckBefore @ (dPC,dFP,self) tail call 11182 11183 /* ------------------------------ */ 11184 .balign 64 11185 .L_ALT_OP_UNUSED_41: /* 0x41 */ 11186 /* File: armv5te/alt_stub.S */ 11187 /* 11188 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11189 * any interesting requests and then jump to the real instruction 11190 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11191 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11192 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11193 * bail to the real handler if breakFlags==0. 11194 */ 11195 ldrb r3, [rSELF, #offThread_breakFlags] 11196 adrl lr, dvmAsmInstructionStart + (65 * 64) 11197 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11198 cmp r3, #0 11199 bxeq lr @ nothing to do - jump to real handler 11200 EXPORT_PC() 11201 mov r0, rPC @ arg0 11202 mov r1, rFP @ arg1 11203 mov r2, rSELF @ arg2 11204 b dvmCheckBefore @ (dPC,dFP,self) tail call 11205 11206 /* ------------------------------ */ 11207 .balign 64 11208 .L_ALT_OP_UNUSED_42: /* 0x42 */ 11209 /* File: armv5te/alt_stub.S */ 11210 /* 11211 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11212 * any interesting requests and then jump to the real instruction 11213 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11214 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11215 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11216 * bail to the real handler if breakFlags==0. 11217 */ 11218 ldrb r3, [rSELF, #offThread_breakFlags] 11219 adrl lr, dvmAsmInstructionStart + (66 * 64) 11220 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11221 cmp r3, #0 11222 bxeq lr @ nothing to do - jump to real handler 11223 EXPORT_PC() 11224 mov r0, rPC @ arg0 11225 mov r1, rFP @ arg1 11226 mov r2, rSELF @ arg2 11227 b dvmCheckBefore @ (dPC,dFP,self) tail call 11228 11229 /* ------------------------------ */ 11230 .balign 64 11231 .L_ALT_OP_UNUSED_43: /* 0x43 */ 11232 /* File: armv5te/alt_stub.S */ 11233 /* 11234 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11235 * any interesting requests and then jump to the real instruction 11236 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11237 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11238 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11239 * bail to the real handler if breakFlags==0. 11240 */ 11241 ldrb r3, [rSELF, #offThread_breakFlags] 11242 adrl lr, dvmAsmInstructionStart + (67 * 64) 11243 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11244 cmp r3, #0 11245 bxeq lr @ nothing to do - jump to real handler 11246 EXPORT_PC() 11247 mov r0, rPC @ arg0 11248 mov r1, rFP @ arg1 11249 mov r2, rSELF @ arg2 11250 b dvmCheckBefore @ (dPC,dFP,self) tail call 11251 11252 /* ------------------------------ */ 11253 .balign 64 11254 .L_ALT_OP_AGET: /* 0x44 */ 11255 /* File: armv5te/alt_stub.S */ 11256 /* 11257 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11258 * any interesting requests and then jump to the real instruction 11259 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11260 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11261 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11262 * bail to the real handler if breakFlags==0. 11263 */ 11264 ldrb r3, [rSELF, #offThread_breakFlags] 11265 adrl lr, dvmAsmInstructionStart + (68 * 64) 11266 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11267 cmp r3, #0 11268 bxeq lr @ nothing to do - jump to real handler 11269 EXPORT_PC() 11270 mov r0, rPC @ arg0 11271 mov r1, rFP @ arg1 11272 mov r2, rSELF @ arg2 11273 b dvmCheckBefore @ (dPC,dFP,self) tail call 11274 11275 /* ------------------------------ */ 11276 .balign 64 11277 .L_ALT_OP_AGET_WIDE: /* 0x45 */ 11278 /* File: armv5te/alt_stub.S */ 11279 /* 11280 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11281 * any interesting requests and then jump to the real instruction 11282 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11283 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11284 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11285 * bail to the real handler if breakFlags==0. 11286 */ 11287 ldrb r3, [rSELF, #offThread_breakFlags] 11288 adrl lr, dvmAsmInstructionStart + (69 * 64) 11289 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11290 cmp r3, #0 11291 bxeq lr @ nothing to do - jump to real handler 11292 EXPORT_PC() 11293 mov r0, rPC @ arg0 11294 mov r1, rFP @ arg1 11295 mov r2, rSELF @ arg2 11296 b dvmCheckBefore @ (dPC,dFP,self) tail call 11297 11298 /* ------------------------------ */ 11299 .balign 64 11300 .L_ALT_OP_AGET_OBJECT: /* 0x46 */ 11301 /* File: armv5te/alt_stub.S */ 11302 /* 11303 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11304 * any interesting requests and then jump to the real instruction 11305 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11306 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11307 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11308 * bail to the real handler if breakFlags==0. 11309 */ 11310 ldrb r3, [rSELF, #offThread_breakFlags] 11311 adrl lr, dvmAsmInstructionStart + (70 * 64) 11312 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11313 cmp r3, #0 11314 bxeq lr @ nothing to do - jump to real handler 11315 EXPORT_PC() 11316 mov r0, rPC @ arg0 11317 mov r1, rFP @ arg1 11318 mov r2, rSELF @ arg2 11319 b dvmCheckBefore @ (dPC,dFP,self) tail call 11320 11321 /* ------------------------------ */ 11322 .balign 64 11323 .L_ALT_OP_AGET_BOOLEAN: /* 0x47 */ 11324 /* File: armv5te/alt_stub.S */ 11325 /* 11326 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11327 * any interesting requests and then jump to the real instruction 11328 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11329 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11330 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11331 * bail to the real handler if breakFlags==0. 11332 */ 11333 ldrb r3, [rSELF, #offThread_breakFlags] 11334 adrl lr, dvmAsmInstructionStart + (71 * 64) 11335 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11336 cmp r3, #0 11337 bxeq lr @ nothing to do - jump to real handler 11338 EXPORT_PC() 11339 mov r0, rPC @ arg0 11340 mov r1, rFP @ arg1 11341 mov r2, rSELF @ arg2 11342 b dvmCheckBefore @ (dPC,dFP,self) tail call 11343 11344 /* ------------------------------ */ 11345 .balign 64 11346 .L_ALT_OP_AGET_BYTE: /* 0x48 */ 11347 /* File: armv5te/alt_stub.S */ 11348 /* 11349 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11350 * any interesting requests and then jump to the real instruction 11351 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11352 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11353 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11354 * bail to the real handler if breakFlags==0. 11355 */ 11356 ldrb r3, [rSELF, #offThread_breakFlags] 11357 adrl lr, dvmAsmInstructionStart + (72 * 64) 11358 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11359 cmp r3, #0 11360 bxeq lr @ nothing to do - jump to real handler 11361 EXPORT_PC() 11362 mov r0, rPC @ arg0 11363 mov r1, rFP @ arg1 11364 mov r2, rSELF @ arg2 11365 b dvmCheckBefore @ (dPC,dFP,self) tail call 11366 11367 /* ------------------------------ */ 11368 .balign 64 11369 .L_ALT_OP_AGET_CHAR: /* 0x49 */ 11370 /* File: armv5te/alt_stub.S */ 11371 /* 11372 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11373 * any interesting requests and then jump to the real instruction 11374 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11375 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11376 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11377 * bail to the real handler if breakFlags==0. 11378 */ 11379 ldrb r3, [rSELF, #offThread_breakFlags] 11380 adrl lr, dvmAsmInstructionStart + (73 * 64) 11381 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11382 cmp r3, #0 11383 bxeq lr @ nothing to do - jump to real handler 11384 EXPORT_PC() 11385 mov r0, rPC @ arg0 11386 mov r1, rFP @ arg1 11387 mov r2, rSELF @ arg2 11388 b dvmCheckBefore @ (dPC,dFP,self) tail call 11389 11390 /* ------------------------------ */ 11391 .balign 64 11392 .L_ALT_OP_AGET_SHORT: /* 0x4a */ 11393 /* File: armv5te/alt_stub.S */ 11394 /* 11395 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11396 * any interesting requests and then jump to the real instruction 11397 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11398 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11399 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11400 * bail to the real handler if breakFlags==0. 11401 */ 11402 ldrb r3, [rSELF, #offThread_breakFlags] 11403 adrl lr, dvmAsmInstructionStart + (74 * 64) 11404 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11405 cmp r3, #0 11406 bxeq lr @ nothing to do - jump to real handler 11407 EXPORT_PC() 11408 mov r0, rPC @ arg0 11409 mov r1, rFP @ arg1 11410 mov r2, rSELF @ arg2 11411 b dvmCheckBefore @ (dPC,dFP,self) tail call 11412 11413 /* ------------------------------ */ 11414 .balign 64 11415 .L_ALT_OP_APUT: /* 0x4b */ 11416 /* File: armv5te/alt_stub.S */ 11417 /* 11418 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11419 * any interesting requests and then jump to the real instruction 11420 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11421 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11422 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11423 * bail to the real handler if breakFlags==0. 11424 */ 11425 ldrb r3, [rSELF, #offThread_breakFlags] 11426 adrl lr, dvmAsmInstructionStart + (75 * 64) 11427 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11428 cmp r3, #0 11429 bxeq lr @ nothing to do - jump to real handler 11430 EXPORT_PC() 11431 mov r0, rPC @ arg0 11432 mov r1, rFP @ arg1 11433 mov r2, rSELF @ arg2 11434 b dvmCheckBefore @ (dPC,dFP,self) tail call 11435 11436 /* ------------------------------ */ 11437 .balign 64 11438 .L_ALT_OP_APUT_WIDE: /* 0x4c */ 11439 /* File: armv5te/alt_stub.S */ 11440 /* 11441 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11442 * any interesting requests and then jump to the real instruction 11443 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11444 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11445 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11446 * bail to the real handler if breakFlags==0. 11447 */ 11448 ldrb r3, [rSELF, #offThread_breakFlags] 11449 adrl lr, dvmAsmInstructionStart + (76 * 64) 11450 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11451 cmp r3, #0 11452 bxeq lr @ nothing to do - jump to real handler 11453 EXPORT_PC() 11454 mov r0, rPC @ arg0 11455 mov r1, rFP @ arg1 11456 mov r2, rSELF @ arg2 11457 b dvmCheckBefore @ (dPC,dFP,self) tail call 11458 11459 /* ------------------------------ */ 11460 .balign 64 11461 .L_ALT_OP_APUT_OBJECT: /* 0x4d */ 11462 /* File: armv5te/alt_stub.S */ 11463 /* 11464 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11465 * any interesting requests and then jump to the real instruction 11466 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11467 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11468 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11469 * bail to the real handler if breakFlags==0. 11470 */ 11471 ldrb r3, [rSELF, #offThread_breakFlags] 11472 adrl lr, dvmAsmInstructionStart + (77 * 64) 11473 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11474 cmp r3, #0 11475 bxeq lr @ nothing to do - jump to real handler 11476 EXPORT_PC() 11477 mov r0, rPC @ arg0 11478 mov r1, rFP @ arg1 11479 mov r2, rSELF @ arg2 11480 b dvmCheckBefore @ (dPC,dFP,self) tail call 11481 11482 /* ------------------------------ */ 11483 .balign 64 11484 .L_ALT_OP_APUT_BOOLEAN: /* 0x4e */ 11485 /* File: armv5te/alt_stub.S */ 11486 /* 11487 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11488 * any interesting requests and then jump to the real instruction 11489 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11490 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11491 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11492 * bail to the real handler if breakFlags==0. 11493 */ 11494 ldrb r3, [rSELF, #offThread_breakFlags] 11495 adrl lr, dvmAsmInstructionStart + (78 * 64) 11496 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11497 cmp r3, #0 11498 bxeq lr @ nothing to do - jump to real handler 11499 EXPORT_PC() 11500 mov r0, rPC @ arg0 11501 mov r1, rFP @ arg1 11502 mov r2, rSELF @ arg2 11503 b dvmCheckBefore @ (dPC,dFP,self) tail call 11504 11505 /* ------------------------------ */ 11506 .balign 64 11507 .L_ALT_OP_APUT_BYTE: /* 0x4f */ 11508 /* File: armv5te/alt_stub.S */ 11509 /* 11510 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11511 * any interesting requests and then jump to the real instruction 11512 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11513 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11514 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11515 * bail to the real handler if breakFlags==0. 11516 */ 11517 ldrb r3, [rSELF, #offThread_breakFlags] 11518 adrl lr, dvmAsmInstructionStart + (79 * 64) 11519 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11520 cmp r3, #0 11521 bxeq lr @ nothing to do - jump to real handler 11522 EXPORT_PC() 11523 mov r0, rPC @ arg0 11524 mov r1, rFP @ arg1 11525 mov r2, rSELF @ arg2 11526 b dvmCheckBefore @ (dPC,dFP,self) tail call 11527 11528 /* ------------------------------ */ 11529 .balign 64 11530 .L_ALT_OP_APUT_CHAR: /* 0x50 */ 11531 /* File: armv5te/alt_stub.S */ 11532 /* 11533 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11534 * any interesting requests and then jump to the real instruction 11535 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11536 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11537 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11538 * bail to the real handler if breakFlags==0. 11539 */ 11540 ldrb r3, [rSELF, #offThread_breakFlags] 11541 adrl lr, dvmAsmInstructionStart + (80 * 64) 11542 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11543 cmp r3, #0 11544 bxeq lr @ nothing to do - jump to real handler 11545 EXPORT_PC() 11546 mov r0, rPC @ arg0 11547 mov r1, rFP @ arg1 11548 mov r2, rSELF @ arg2 11549 b dvmCheckBefore @ (dPC,dFP,self) tail call 11550 11551 /* ------------------------------ */ 11552 .balign 64 11553 .L_ALT_OP_APUT_SHORT: /* 0x51 */ 11554 /* File: armv5te/alt_stub.S */ 11555 /* 11556 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11557 * any interesting requests and then jump to the real instruction 11558 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11559 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11560 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11561 * bail to the real handler if breakFlags==0. 11562 */ 11563 ldrb r3, [rSELF, #offThread_breakFlags] 11564 adrl lr, dvmAsmInstructionStart + (81 * 64) 11565 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11566 cmp r3, #0 11567 bxeq lr @ nothing to do - jump to real handler 11568 EXPORT_PC() 11569 mov r0, rPC @ arg0 11570 mov r1, rFP @ arg1 11571 mov r2, rSELF @ arg2 11572 b dvmCheckBefore @ (dPC,dFP,self) tail call 11573 11574 /* ------------------------------ */ 11575 .balign 64 11576 .L_ALT_OP_IGET: /* 0x52 */ 11577 /* File: armv5te/alt_stub.S */ 11578 /* 11579 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11580 * any interesting requests and then jump to the real instruction 11581 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11582 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11583 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11584 * bail to the real handler if breakFlags==0. 11585 */ 11586 ldrb r3, [rSELF, #offThread_breakFlags] 11587 adrl lr, dvmAsmInstructionStart + (82 * 64) 11588 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11589 cmp r3, #0 11590 bxeq lr @ nothing to do - jump to real handler 11591 EXPORT_PC() 11592 mov r0, rPC @ arg0 11593 mov r1, rFP @ arg1 11594 mov r2, rSELF @ arg2 11595 b dvmCheckBefore @ (dPC,dFP,self) tail call 11596 11597 /* ------------------------------ */ 11598 .balign 64 11599 .L_ALT_OP_IGET_WIDE: /* 0x53 */ 11600 /* File: armv5te/alt_stub.S */ 11601 /* 11602 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11603 * any interesting requests and then jump to the real instruction 11604 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11605 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11606 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11607 * bail to the real handler if breakFlags==0. 11608 */ 11609 ldrb r3, [rSELF, #offThread_breakFlags] 11610 adrl lr, dvmAsmInstructionStart + (83 * 64) 11611 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11612 cmp r3, #0 11613 bxeq lr @ nothing to do - jump to real handler 11614 EXPORT_PC() 11615 mov r0, rPC @ arg0 11616 mov r1, rFP @ arg1 11617 mov r2, rSELF @ arg2 11618 b dvmCheckBefore @ (dPC,dFP,self) tail call 11619 11620 /* ------------------------------ */ 11621 .balign 64 11622 .L_ALT_OP_IGET_OBJECT: /* 0x54 */ 11623 /* File: armv5te/alt_stub.S */ 11624 /* 11625 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11626 * any interesting requests and then jump to the real instruction 11627 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11628 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11629 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11630 * bail to the real handler if breakFlags==0. 11631 */ 11632 ldrb r3, [rSELF, #offThread_breakFlags] 11633 adrl lr, dvmAsmInstructionStart + (84 * 64) 11634 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11635 cmp r3, #0 11636 bxeq lr @ nothing to do - jump to real handler 11637 EXPORT_PC() 11638 mov r0, rPC @ arg0 11639 mov r1, rFP @ arg1 11640 mov r2, rSELF @ arg2 11641 b dvmCheckBefore @ (dPC,dFP,self) tail call 11642 11643 /* ------------------------------ */ 11644 .balign 64 11645 .L_ALT_OP_IGET_BOOLEAN: /* 0x55 */ 11646 /* File: armv5te/alt_stub.S */ 11647 /* 11648 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11649 * any interesting requests and then jump to the real instruction 11650 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11651 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11652 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11653 * bail to the real handler if breakFlags==0. 11654 */ 11655 ldrb r3, [rSELF, #offThread_breakFlags] 11656 adrl lr, dvmAsmInstructionStart + (85 * 64) 11657 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11658 cmp r3, #0 11659 bxeq lr @ nothing to do - jump to real handler 11660 EXPORT_PC() 11661 mov r0, rPC @ arg0 11662 mov r1, rFP @ arg1 11663 mov r2, rSELF @ arg2 11664 b dvmCheckBefore @ (dPC,dFP,self) tail call 11665 11666 /* ------------------------------ */ 11667 .balign 64 11668 .L_ALT_OP_IGET_BYTE: /* 0x56 */ 11669 /* File: armv5te/alt_stub.S */ 11670 /* 11671 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11672 * any interesting requests and then jump to the real instruction 11673 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11674 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11675 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11676 * bail to the real handler if breakFlags==0. 11677 */ 11678 ldrb r3, [rSELF, #offThread_breakFlags] 11679 adrl lr, dvmAsmInstructionStart + (86 * 64) 11680 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11681 cmp r3, #0 11682 bxeq lr @ nothing to do - jump to real handler 11683 EXPORT_PC() 11684 mov r0, rPC @ arg0 11685 mov r1, rFP @ arg1 11686 mov r2, rSELF @ arg2 11687 b dvmCheckBefore @ (dPC,dFP,self) tail call 11688 11689 /* ------------------------------ */ 11690 .balign 64 11691 .L_ALT_OP_IGET_CHAR: /* 0x57 */ 11692 /* File: armv5te/alt_stub.S */ 11693 /* 11694 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11695 * any interesting requests and then jump to the real instruction 11696 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11697 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11698 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11699 * bail to the real handler if breakFlags==0. 11700 */ 11701 ldrb r3, [rSELF, #offThread_breakFlags] 11702 adrl lr, dvmAsmInstructionStart + (87 * 64) 11703 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11704 cmp r3, #0 11705 bxeq lr @ nothing to do - jump to real handler 11706 EXPORT_PC() 11707 mov r0, rPC @ arg0 11708 mov r1, rFP @ arg1 11709 mov r2, rSELF @ arg2 11710 b dvmCheckBefore @ (dPC,dFP,self) tail call 11711 11712 /* ------------------------------ */ 11713 .balign 64 11714 .L_ALT_OP_IGET_SHORT: /* 0x58 */ 11715 /* File: armv5te/alt_stub.S */ 11716 /* 11717 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11718 * any interesting requests and then jump to the real instruction 11719 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11720 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11721 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11722 * bail to the real handler if breakFlags==0. 11723 */ 11724 ldrb r3, [rSELF, #offThread_breakFlags] 11725 adrl lr, dvmAsmInstructionStart + (88 * 64) 11726 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11727 cmp r3, #0 11728 bxeq lr @ nothing to do - jump to real handler 11729 EXPORT_PC() 11730 mov r0, rPC @ arg0 11731 mov r1, rFP @ arg1 11732 mov r2, rSELF @ arg2 11733 b dvmCheckBefore @ (dPC,dFP,self) tail call 11734 11735 /* ------------------------------ */ 11736 .balign 64 11737 .L_ALT_OP_IPUT: /* 0x59 */ 11738 /* File: armv5te/alt_stub.S */ 11739 /* 11740 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11741 * any interesting requests and then jump to the real instruction 11742 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11743 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11744 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11745 * bail to the real handler if breakFlags==0. 11746 */ 11747 ldrb r3, [rSELF, #offThread_breakFlags] 11748 adrl lr, dvmAsmInstructionStart + (89 * 64) 11749 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11750 cmp r3, #0 11751 bxeq lr @ nothing to do - jump to real handler 11752 EXPORT_PC() 11753 mov r0, rPC @ arg0 11754 mov r1, rFP @ arg1 11755 mov r2, rSELF @ arg2 11756 b dvmCheckBefore @ (dPC,dFP,self) tail call 11757 11758 /* ------------------------------ */ 11759 .balign 64 11760 .L_ALT_OP_IPUT_WIDE: /* 0x5a */ 11761 /* File: armv5te/alt_stub.S */ 11762 /* 11763 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11764 * any interesting requests and then jump to the real instruction 11765 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11766 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11767 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11768 * bail to the real handler if breakFlags==0. 11769 */ 11770 ldrb r3, [rSELF, #offThread_breakFlags] 11771 adrl lr, dvmAsmInstructionStart + (90 * 64) 11772 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11773 cmp r3, #0 11774 bxeq lr @ nothing to do - jump to real handler 11775 EXPORT_PC() 11776 mov r0, rPC @ arg0 11777 mov r1, rFP @ arg1 11778 mov r2, rSELF @ arg2 11779 b dvmCheckBefore @ (dPC,dFP,self) tail call 11780 11781 /* ------------------------------ */ 11782 .balign 64 11783 .L_ALT_OP_IPUT_OBJECT: /* 0x5b */ 11784 /* File: armv5te/alt_stub.S */ 11785 /* 11786 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11787 * any interesting requests and then jump to the real instruction 11788 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11789 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11790 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11791 * bail to the real handler if breakFlags==0. 11792 */ 11793 ldrb r3, [rSELF, #offThread_breakFlags] 11794 adrl lr, dvmAsmInstructionStart + (91 * 64) 11795 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11796 cmp r3, #0 11797 bxeq lr @ nothing to do - jump to real handler 11798 EXPORT_PC() 11799 mov r0, rPC @ arg0 11800 mov r1, rFP @ arg1 11801 mov r2, rSELF @ arg2 11802 b dvmCheckBefore @ (dPC,dFP,self) tail call 11803 11804 /* ------------------------------ */ 11805 .balign 64 11806 .L_ALT_OP_IPUT_BOOLEAN: /* 0x5c */ 11807 /* File: armv5te/alt_stub.S */ 11808 /* 11809 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11810 * any interesting requests and then jump to the real instruction 11811 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11812 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11813 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11814 * bail to the real handler if breakFlags==0. 11815 */ 11816 ldrb r3, [rSELF, #offThread_breakFlags] 11817 adrl lr, dvmAsmInstructionStart + (92 * 64) 11818 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11819 cmp r3, #0 11820 bxeq lr @ nothing to do - jump to real handler 11821 EXPORT_PC() 11822 mov r0, rPC @ arg0 11823 mov r1, rFP @ arg1 11824 mov r2, rSELF @ arg2 11825 b dvmCheckBefore @ (dPC,dFP,self) tail call 11826 11827 /* ------------------------------ */ 11828 .balign 64 11829 .L_ALT_OP_IPUT_BYTE: /* 0x5d */ 11830 /* File: armv5te/alt_stub.S */ 11831 /* 11832 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11833 * any interesting requests and then jump to the real instruction 11834 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11835 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11836 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11837 * bail to the real handler if breakFlags==0. 11838 */ 11839 ldrb r3, [rSELF, #offThread_breakFlags] 11840 adrl lr, dvmAsmInstructionStart + (93 * 64) 11841 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11842 cmp r3, #0 11843 bxeq lr @ nothing to do - jump to real handler 11844 EXPORT_PC() 11845 mov r0, rPC @ arg0 11846 mov r1, rFP @ arg1 11847 mov r2, rSELF @ arg2 11848 b dvmCheckBefore @ (dPC,dFP,self) tail call 11849 11850 /* ------------------------------ */ 11851 .balign 64 11852 .L_ALT_OP_IPUT_CHAR: /* 0x5e */ 11853 /* File: armv5te/alt_stub.S */ 11854 /* 11855 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11856 * any interesting requests and then jump to the real instruction 11857 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11858 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11859 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11860 * bail to the real handler if breakFlags==0. 11861 */ 11862 ldrb r3, [rSELF, #offThread_breakFlags] 11863 adrl lr, dvmAsmInstructionStart + (94 * 64) 11864 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11865 cmp r3, #0 11866 bxeq lr @ nothing to do - jump to real handler 11867 EXPORT_PC() 11868 mov r0, rPC @ arg0 11869 mov r1, rFP @ arg1 11870 mov r2, rSELF @ arg2 11871 b dvmCheckBefore @ (dPC,dFP,self) tail call 11872 11873 /* ------------------------------ */ 11874 .balign 64 11875 .L_ALT_OP_IPUT_SHORT: /* 0x5f */ 11876 /* File: armv5te/alt_stub.S */ 11877 /* 11878 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11879 * any interesting requests and then jump to the real instruction 11880 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11881 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11882 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11883 * bail to the real handler if breakFlags==0. 11884 */ 11885 ldrb r3, [rSELF, #offThread_breakFlags] 11886 adrl lr, dvmAsmInstructionStart + (95 * 64) 11887 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11888 cmp r3, #0 11889 bxeq lr @ nothing to do - jump to real handler 11890 EXPORT_PC() 11891 mov r0, rPC @ arg0 11892 mov r1, rFP @ arg1 11893 mov r2, rSELF @ arg2 11894 b dvmCheckBefore @ (dPC,dFP,self) tail call 11895 11896 /* ------------------------------ */ 11897 .balign 64 11898 .L_ALT_OP_SGET: /* 0x60 */ 11899 /* File: armv5te/alt_stub.S */ 11900 /* 11901 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11902 * any interesting requests and then jump to the real instruction 11903 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11904 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11905 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11906 * bail to the real handler if breakFlags==0. 11907 */ 11908 ldrb r3, [rSELF, #offThread_breakFlags] 11909 adrl lr, dvmAsmInstructionStart + (96 * 64) 11910 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11911 cmp r3, #0 11912 bxeq lr @ nothing to do - jump to real handler 11913 EXPORT_PC() 11914 mov r0, rPC @ arg0 11915 mov r1, rFP @ arg1 11916 mov r2, rSELF @ arg2 11917 b dvmCheckBefore @ (dPC,dFP,self) tail call 11918 11919 /* ------------------------------ */ 11920 .balign 64 11921 .L_ALT_OP_SGET_WIDE: /* 0x61 */ 11922 /* File: armv5te/alt_stub.S */ 11923 /* 11924 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11925 * any interesting requests and then jump to the real instruction 11926 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11927 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11928 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11929 * bail to the real handler if breakFlags==0. 11930 */ 11931 ldrb r3, [rSELF, #offThread_breakFlags] 11932 adrl lr, dvmAsmInstructionStart + (97 * 64) 11933 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11934 cmp r3, #0 11935 bxeq lr @ nothing to do - jump to real handler 11936 EXPORT_PC() 11937 mov r0, rPC @ arg0 11938 mov r1, rFP @ arg1 11939 mov r2, rSELF @ arg2 11940 b dvmCheckBefore @ (dPC,dFP,self) tail call 11941 11942 /* ------------------------------ */ 11943 .balign 64 11944 .L_ALT_OP_SGET_OBJECT: /* 0x62 */ 11945 /* File: armv5te/alt_stub.S */ 11946 /* 11947 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11948 * any interesting requests and then jump to the real instruction 11949 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11950 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11951 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11952 * bail to the real handler if breakFlags==0. 11953 */ 11954 ldrb r3, [rSELF, #offThread_breakFlags] 11955 adrl lr, dvmAsmInstructionStart + (98 * 64) 11956 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11957 cmp r3, #0 11958 bxeq lr @ nothing to do - jump to real handler 11959 EXPORT_PC() 11960 mov r0, rPC @ arg0 11961 mov r1, rFP @ arg1 11962 mov r2, rSELF @ arg2 11963 b dvmCheckBefore @ (dPC,dFP,self) tail call 11964 11965 /* ------------------------------ */ 11966 .balign 64 11967 .L_ALT_OP_SGET_BOOLEAN: /* 0x63 */ 11968 /* File: armv5te/alt_stub.S */ 11969 /* 11970 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11971 * any interesting requests and then jump to the real instruction 11972 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11973 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11974 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11975 * bail to the real handler if breakFlags==0. 11976 */ 11977 ldrb r3, [rSELF, #offThread_breakFlags] 11978 adrl lr, dvmAsmInstructionStart + (99 * 64) 11979 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11980 cmp r3, #0 11981 bxeq lr @ nothing to do - jump to real handler 11982 EXPORT_PC() 11983 mov r0, rPC @ arg0 11984 mov r1, rFP @ arg1 11985 mov r2, rSELF @ arg2 11986 b dvmCheckBefore @ (dPC,dFP,self) tail call 11987 11988 /* ------------------------------ */ 11989 .balign 64 11990 .L_ALT_OP_SGET_BYTE: /* 0x64 */ 11991 /* File: armv5te/alt_stub.S */ 11992 /* 11993 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11994 * any interesting requests and then jump to the real instruction 11995 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11996 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11997 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11998 * bail to the real handler if breakFlags==0. 11999 */ 12000 ldrb r3, [rSELF, #offThread_breakFlags] 12001 adrl lr, dvmAsmInstructionStart + (100 * 64) 12002 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12003 cmp r3, #0 12004 bxeq lr @ nothing to do - jump to real handler 12005 EXPORT_PC() 12006 mov r0, rPC @ arg0 12007 mov r1, rFP @ arg1 12008 mov r2, rSELF @ arg2 12009 b dvmCheckBefore @ (dPC,dFP,self) tail call 12010 12011 /* ------------------------------ */ 12012 .balign 64 12013 .L_ALT_OP_SGET_CHAR: /* 0x65 */ 12014 /* File: armv5te/alt_stub.S */ 12015 /* 12016 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12017 * any interesting requests and then jump to the real instruction 12018 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12019 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12020 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12021 * bail to the real handler if breakFlags==0. 12022 */ 12023 ldrb r3, [rSELF, #offThread_breakFlags] 12024 adrl lr, dvmAsmInstructionStart + (101 * 64) 12025 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12026 cmp r3, #0 12027 bxeq lr @ nothing to do - jump to real handler 12028 EXPORT_PC() 12029 mov r0, rPC @ arg0 12030 mov r1, rFP @ arg1 12031 mov r2, rSELF @ arg2 12032 b dvmCheckBefore @ (dPC,dFP,self) tail call 12033 12034 /* ------------------------------ */ 12035 .balign 64 12036 .L_ALT_OP_SGET_SHORT: /* 0x66 */ 12037 /* File: armv5te/alt_stub.S */ 12038 /* 12039 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12040 * any interesting requests and then jump to the real instruction 12041 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12042 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12043 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12044 * bail to the real handler if breakFlags==0. 12045 */ 12046 ldrb r3, [rSELF, #offThread_breakFlags] 12047 adrl lr, dvmAsmInstructionStart + (102 * 64) 12048 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12049 cmp r3, #0 12050 bxeq lr @ nothing to do - jump to real handler 12051 EXPORT_PC() 12052 mov r0, rPC @ arg0 12053 mov r1, rFP @ arg1 12054 mov r2, rSELF @ arg2 12055 b dvmCheckBefore @ (dPC,dFP,self) tail call 12056 12057 /* ------------------------------ */ 12058 .balign 64 12059 .L_ALT_OP_SPUT: /* 0x67 */ 12060 /* File: armv5te/alt_stub.S */ 12061 /* 12062 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12063 * any interesting requests and then jump to the real instruction 12064 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12065 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12066 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12067 * bail to the real handler if breakFlags==0. 12068 */ 12069 ldrb r3, [rSELF, #offThread_breakFlags] 12070 adrl lr, dvmAsmInstructionStart + (103 * 64) 12071 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12072 cmp r3, #0 12073 bxeq lr @ nothing to do - jump to real handler 12074 EXPORT_PC() 12075 mov r0, rPC @ arg0 12076 mov r1, rFP @ arg1 12077 mov r2, rSELF @ arg2 12078 b dvmCheckBefore @ (dPC,dFP,self) tail call 12079 12080 /* ------------------------------ */ 12081 .balign 64 12082 .L_ALT_OP_SPUT_WIDE: /* 0x68 */ 12083 /* File: armv5te/alt_stub.S */ 12084 /* 12085 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12086 * any interesting requests and then jump to the real instruction 12087 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12088 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12089 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12090 * bail to the real handler if breakFlags==0. 12091 */ 12092 ldrb r3, [rSELF, #offThread_breakFlags] 12093 adrl lr, dvmAsmInstructionStart + (104 * 64) 12094 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12095 cmp r3, #0 12096 bxeq lr @ nothing to do - jump to real handler 12097 EXPORT_PC() 12098 mov r0, rPC @ arg0 12099 mov r1, rFP @ arg1 12100 mov r2, rSELF @ arg2 12101 b dvmCheckBefore @ (dPC,dFP,self) tail call 12102 12103 /* ------------------------------ */ 12104 .balign 64 12105 .L_ALT_OP_SPUT_OBJECT: /* 0x69 */ 12106 /* File: armv5te/alt_stub.S */ 12107 /* 12108 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12109 * any interesting requests and then jump to the real instruction 12110 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12111 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12112 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12113 * bail to the real handler if breakFlags==0. 12114 */ 12115 ldrb r3, [rSELF, #offThread_breakFlags] 12116 adrl lr, dvmAsmInstructionStart + (105 * 64) 12117 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12118 cmp r3, #0 12119 bxeq lr @ nothing to do - jump to real handler 12120 EXPORT_PC() 12121 mov r0, rPC @ arg0 12122 mov r1, rFP @ arg1 12123 mov r2, rSELF @ arg2 12124 b dvmCheckBefore @ (dPC,dFP,self) tail call 12125 12126 /* ------------------------------ */ 12127 .balign 64 12128 .L_ALT_OP_SPUT_BOOLEAN: /* 0x6a */ 12129 /* File: armv5te/alt_stub.S */ 12130 /* 12131 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12132 * any interesting requests and then jump to the real instruction 12133 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12134 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12135 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12136 * bail to the real handler if breakFlags==0. 12137 */ 12138 ldrb r3, [rSELF, #offThread_breakFlags] 12139 adrl lr, dvmAsmInstructionStart + (106 * 64) 12140 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12141 cmp r3, #0 12142 bxeq lr @ nothing to do - jump to real handler 12143 EXPORT_PC() 12144 mov r0, rPC @ arg0 12145 mov r1, rFP @ arg1 12146 mov r2, rSELF @ arg2 12147 b dvmCheckBefore @ (dPC,dFP,self) tail call 12148 12149 /* ------------------------------ */ 12150 .balign 64 12151 .L_ALT_OP_SPUT_BYTE: /* 0x6b */ 12152 /* File: armv5te/alt_stub.S */ 12153 /* 12154 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12155 * any interesting requests and then jump to the real instruction 12156 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12157 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12158 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12159 * bail to the real handler if breakFlags==0. 12160 */ 12161 ldrb r3, [rSELF, #offThread_breakFlags] 12162 adrl lr, dvmAsmInstructionStart + (107 * 64) 12163 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12164 cmp r3, #0 12165 bxeq lr @ nothing to do - jump to real handler 12166 EXPORT_PC() 12167 mov r0, rPC @ arg0 12168 mov r1, rFP @ arg1 12169 mov r2, rSELF @ arg2 12170 b dvmCheckBefore @ (dPC,dFP,self) tail call 12171 12172 /* ------------------------------ */ 12173 .balign 64 12174 .L_ALT_OP_SPUT_CHAR: /* 0x6c */ 12175 /* File: armv5te/alt_stub.S */ 12176 /* 12177 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12178 * any interesting requests and then jump to the real instruction 12179 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12180 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12181 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12182 * bail to the real handler if breakFlags==0. 12183 */ 12184 ldrb r3, [rSELF, #offThread_breakFlags] 12185 adrl lr, dvmAsmInstructionStart + (108 * 64) 12186 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12187 cmp r3, #0 12188 bxeq lr @ nothing to do - jump to real handler 12189 EXPORT_PC() 12190 mov r0, rPC @ arg0 12191 mov r1, rFP @ arg1 12192 mov r2, rSELF @ arg2 12193 b dvmCheckBefore @ (dPC,dFP,self) tail call 12194 12195 /* ------------------------------ */ 12196 .balign 64 12197 .L_ALT_OP_SPUT_SHORT: /* 0x6d */ 12198 /* File: armv5te/alt_stub.S */ 12199 /* 12200 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12201 * any interesting requests and then jump to the real instruction 12202 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12203 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12204 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12205 * bail to the real handler if breakFlags==0. 12206 */ 12207 ldrb r3, [rSELF, #offThread_breakFlags] 12208 adrl lr, dvmAsmInstructionStart + (109 * 64) 12209 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12210 cmp r3, #0 12211 bxeq lr @ nothing to do - jump to real handler 12212 EXPORT_PC() 12213 mov r0, rPC @ arg0 12214 mov r1, rFP @ arg1 12215 mov r2, rSELF @ arg2 12216 b dvmCheckBefore @ (dPC,dFP,self) tail call 12217 12218 /* ------------------------------ */ 12219 .balign 64 12220 .L_ALT_OP_INVOKE_VIRTUAL: /* 0x6e */ 12221 /* File: armv5te/alt_stub.S */ 12222 /* 12223 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12224 * any interesting requests and then jump to the real instruction 12225 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12226 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12227 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12228 * bail to the real handler if breakFlags==0. 12229 */ 12230 ldrb r3, [rSELF, #offThread_breakFlags] 12231 adrl lr, dvmAsmInstructionStart + (110 * 64) 12232 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12233 cmp r3, #0 12234 bxeq lr @ nothing to do - jump to real handler 12235 EXPORT_PC() 12236 mov r0, rPC @ arg0 12237 mov r1, rFP @ arg1 12238 mov r2, rSELF @ arg2 12239 b dvmCheckBefore @ (dPC,dFP,self) tail call 12240 12241 /* ------------------------------ */ 12242 .balign 64 12243 .L_ALT_OP_INVOKE_SUPER: /* 0x6f */ 12244 /* File: armv5te/alt_stub.S */ 12245 /* 12246 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12247 * any interesting requests and then jump to the real instruction 12248 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12249 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12250 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12251 * bail to the real handler if breakFlags==0. 12252 */ 12253 ldrb r3, [rSELF, #offThread_breakFlags] 12254 adrl lr, dvmAsmInstructionStart + (111 * 64) 12255 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12256 cmp r3, #0 12257 bxeq lr @ nothing to do - jump to real handler 12258 EXPORT_PC() 12259 mov r0, rPC @ arg0 12260 mov r1, rFP @ arg1 12261 mov r2, rSELF @ arg2 12262 b dvmCheckBefore @ (dPC,dFP,self) tail call 12263 12264 /* ------------------------------ */ 12265 .balign 64 12266 .L_ALT_OP_INVOKE_DIRECT: /* 0x70 */ 12267 /* File: armv5te/alt_stub.S */ 12268 /* 12269 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12270 * any interesting requests and then jump to the real instruction 12271 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12272 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12273 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12274 * bail to the real handler if breakFlags==0. 12275 */ 12276 ldrb r3, [rSELF, #offThread_breakFlags] 12277 adrl lr, dvmAsmInstructionStart + (112 * 64) 12278 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12279 cmp r3, #0 12280 bxeq lr @ nothing to do - jump to real handler 12281 EXPORT_PC() 12282 mov r0, rPC @ arg0 12283 mov r1, rFP @ arg1 12284 mov r2, rSELF @ arg2 12285 b dvmCheckBefore @ (dPC,dFP,self) tail call 12286 12287 /* ------------------------------ */ 12288 .balign 64 12289 .L_ALT_OP_INVOKE_STATIC: /* 0x71 */ 12290 /* File: armv5te/alt_stub.S */ 12291 /* 12292 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12293 * any interesting requests and then jump to the real instruction 12294 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12295 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12296 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12297 * bail to the real handler if breakFlags==0. 12298 */ 12299 ldrb r3, [rSELF, #offThread_breakFlags] 12300 adrl lr, dvmAsmInstructionStart + (113 * 64) 12301 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12302 cmp r3, #0 12303 bxeq lr @ nothing to do - jump to real handler 12304 EXPORT_PC() 12305 mov r0, rPC @ arg0 12306 mov r1, rFP @ arg1 12307 mov r2, rSELF @ arg2 12308 b dvmCheckBefore @ (dPC,dFP,self) tail call 12309 12310 /* ------------------------------ */ 12311 .balign 64 12312 .L_ALT_OP_INVOKE_INTERFACE: /* 0x72 */ 12313 /* File: armv5te/alt_stub.S */ 12314 /* 12315 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12316 * any interesting requests and then jump to the real instruction 12317 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12318 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12319 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12320 * bail to the real handler if breakFlags==0. 12321 */ 12322 ldrb r3, [rSELF, #offThread_breakFlags] 12323 adrl lr, dvmAsmInstructionStart + (114 * 64) 12324 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12325 cmp r3, #0 12326 bxeq lr @ nothing to do - jump to real handler 12327 EXPORT_PC() 12328 mov r0, rPC @ arg0 12329 mov r1, rFP @ arg1 12330 mov r2, rSELF @ arg2 12331 b dvmCheckBefore @ (dPC,dFP,self) tail call 12332 12333 /* ------------------------------ */ 12334 .balign 64 12335 .L_ALT_OP_UNUSED_73: /* 0x73 */ 12336 /* File: armv5te/alt_stub.S */ 12337 /* 12338 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12339 * any interesting requests and then jump to the real instruction 12340 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12341 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12342 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12343 * bail to the real handler if breakFlags==0. 12344 */ 12345 ldrb r3, [rSELF, #offThread_breakFlags] 12346 adrl lr, dvmAsmInstructionStart + (115 * 64) 12347 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12348 cmp r3, #0 12349 bxeq lr @ nothing to do - jump to real handler 12350 EXPORT_PC() 12351 mov r0, rPC @ arg0 12352 mov r1, rFP @ arg1 12353 mov r2, rSELF @ arg2 12354 b dvmCheckBefore @ (dPC,dFP,self) tail call 12355 12356 /* ------------------------------ */ 12357 .balign 64 12358 .L_ALT_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 12359 /* File: armv5te/alt_stub.S */ 12360 /* 12361 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12362 * any interesting requests and then jump to the real instruction 12363 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12364 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12365 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12366 * bail to the real handler if breakFlags==0. 12367 */ 12368 ldrb r3, [rSELF, #offThread_breakFlags] 12369 adrl lr, dvmAsmInstructionStart + (116 * 64) 12370 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12371 cmp r3, #0 12372 bxeq lr @ nothing to do - jump to real handler 12373 EXPORT_PC() 12374 mov r0, rPC @ arg0 12375 mov r1, rFP @ arg1 12376 mov r2, rSELF @ arg2 12377 b dvmCheckBefore @ (dPC,dFP,self) tail call 12378 12379 /* ------------------------------ */ 12380 .balign 64 12381 .L_ALT_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 12382 /* File: armv5te/alt_stub.S */ 12383 /* 12384 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12385 * any interesting requests and then jump to the real instruction 12386 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12387 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12388 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12389 * bail to the real handler if breakFlags==0. 12390 */ 12391 ldrb r3, [rSELF, #offThread_breakFlags] 12392 adrl lr, dvmAsmInstructionStart + (117 * 64) 12393 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12394 cmp r3, #0 12395 bxeq lr @ nothing to do - jump to real handler 12396 EXPORT_PC() 12397 mov r0, rPC @ arg0 12398 mov r1, rFP @ arg1 12399 mov r2, rSELF @ arg2 12400 b dvmCheckBefore @ (dPC,dFP,self) tail call 12401 12402 /* ------------------------------ */ 12403 .balign 64 12404 .L_ALT_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 12405 /* File: armv5te/alt_stub.S */ 12406 /* 12407 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12408 * any interesting requests and then jump to the real instruction 12409 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12410 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12411 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12412 * bail to the real handler if breakFlags==0. 12413 */ 12414 ldrb r3, [rSELF, #offThread_breakFlags] 12415 adrl lr, dvmAsmInstructionStart + (118 * 64) 12416 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12417 cmp r3, #0 12418 bxeq lr @ nothing to do - jump to real handler 12419 EXPORT_PC() 12420 mov r0, rPC @ arg0 12421 mov r1, rFP @ arg1 12422 mov r2, rSELF @ arg2 12423 b dvmCheckBefore @ (dPC,dFP,self) tail call 12424 12425 /* ------------------------------ */ 12426 .balign 64 12427 .L_ALT_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 12428 /* File: armv5te/alt_stub.S */ 12429 /* 12430 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12431 * any interesting requests and then jump to the real instruction 12432 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12433 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12434 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12435 * bail to the real handler if breakFlags==0. 12436 */ 12437 ldrb r3, [rSELF, #offThread_breakFlags] 12438 adrl lr, dvmAsmInstructionStart + (119 * 64) 12439 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12440 cmp r3, #0 12441 bxeq lr @ nothing to do - jump to real handler 12442 EXPORT_PC() 12443 mov r0, rPC @ arg0 12444 mov r1, rFP @ arg1 12445 mov r2, rSELF @ arg2 12446 b dvmCheckBefore @ (dPC,dFP,self) tail call 12447 12448 /* ------------------------------ */ 12449 .balign 64 12450 .L_ALT_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 12451 /* File: armv5te/alt_stub.S */ 12452 /* 12453 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12454 * any interesting requests and then jump to the real instruction 12455 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12456 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12457 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12458 * bail to the real handler if breakFlags==0. 12459 */ 12460 ldrb r3, [rSELF, #offThread_breakFlags] 12461 adrl lr, dvmAsmInstructionStart + (120 * 64) 12462 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12463 cmp r3, #0 12464 bxeq lr @ nothing to do - jump to real handler 12465 EXPORT_PC() 12466 mov r0, rPC @ arg0 12467 mov r1, rFP @ arg1 12468 mov r2, rSELF @ arg2 12469 b dvmCheckBefore @ (dPC,dFP,self) tail call 12470 12471 /* ------------------------------ */ 12472 .balign 64 12473 .L_ALT_OP_UNUSED_79: /* 0x79 */ 12474 /* File: armv5te/alt_stub.S */ 12475 /* 12476 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12477 * any interesting requests and then jump to the real instruction 12478 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12479 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12480 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12481 * bail to the real handler if breakFlags==0. 12482 */ 12483 ldrb r3, [rSELF, #offThread_breakFlags] 12484 adrl lr, dvmAsmInstructionStart + (121 * 64) 12485 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12486 cmp r3, #0 12487 bxeq lr @ nothing to do - jump to real handler 12488 EXPORT_PC() 12489 mov r0, rPC @ arg0 12490 mov r1, rFP @ arg1 12491 mov r2, rSELF @ arg2 12492 b dvmCheckBefore @ (dPC,dFP,self) tail call 12493 12494 /* ------------------------------ */ 12495 .balign 64 12496 .L_ALT_OP_UNUSED_7A: /* 0x7a */ 12497 /* File: armv5te/alt_stub.S */ 12498 /* 12499 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12500 * any interesting requests and then jump to the real instruction 12501 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12502 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12503 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12504 * bail to the real handler if breakFlags==0. 12505 */ 12506 ldrb r3, [rSELF, #offThread_breakFlags] 12507 adrl lr, dvmAsmInstructionStart + (122 * 64) 12508 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12509 cmp r3, #0 12510 bxeq lr @ nothing to do - jump to real handler 12511 EXPORT_PC() 12512 mov r0, rPC @ arg0 12513 mov r1, rFP @ arg1 12514 mov r2, rSELF @ arg2 12515 b dvmCheckBefore @ (dPC,dFP,self) tail call 12516 12517 /* ------------------------------ */ 12518 .balign 64 12519 .L_ALT_OP_NEG_INT: /* 0x7b */ 12520 /* File: armv5te/alt_stub.S */ 12521 /* 12522 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12523 * any interesting requests and then jump to the real instruction 12524 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12525 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12526 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12527 * bail to the real handler if breakFlags==0. 12528 */ 12529 ldrb r3, [rSELF, #offThread_breakFlags] 12530 adrl lr, dvmAsmInstructionStart + (123 * 64) 12531 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12532 cmp r3, #0 12533 bxeq lr @ nothing to do - jump to real handler 12534 EXPORT_PC() 12535 mov r0, rPC @ arg0 12536 mov r1, rFP @ arg1 12537 mov r2, rSELF @ arg2 12538 b dvmCheckBefore @ (dPC,dFP,self) tail call 12539 12540 /* ------------------------------ */ 12541 .balign 64 12542 .L_ALT_OP_NOT_INT: /* 0x7c */ 12543 /* File: armv5te/alt_stub.S */ 12544 /* 12545 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12546 * any interesting requests and then jump to the real instruction 12547 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12548 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12549 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12550 * bail to the real handler if breakFlags==0. 12551 */ 12552 ldrb r3, [rSELF, #offThread_breakFlags] 12553 adrl lr, dvmAsmInstructionStart + (124 * 64) 12554 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12555 cmp r3, #0 12556 bxeq lr @ nothing to do - jump to real handler 12557 EXPORT_PC() 12558 mov r0, rPC @ arg0 12559 mov r1, rFP @ arg1 12560 mov r2, rSELF @ arg2 12561 b dvmCheckBefore @ (dPC,dFP,self) tail call 12562 12563 /* ------------------------------ */ 12564 .balign 64 12565 .L_ALT_OP_NEG_LONG: /* 0x7d */ 12566 /* File: armv5te/alt_stub.S */ 12567 /* 12568 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12569 * any interesting requests and then jump to the real instruction 12570 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12571 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12572 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12573 * bail to the real handler if breakFlags==0. 12574 */ 12575 ldrb r3, [rSELF, #offThread_breakFlags] 12576 adrl lr, dvmAsmInstructionStart + (125 * 64) 12577 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12578 cmp r3, #0 12579 bxeq lr @ nothing to do - jump to real handler 12580 EXPORT_PC() 12581 mov r0, rPC @ arg0 12582 mov r1, rFP @ arg1 12583 mov r2, rSELF @ arg2 12584 b dvmCheckBefore @ (dPC,dFP,self) tail call 12585 12586 /* ------------------------------ */ 12587 .balign 64 12588 .L_ALT_OP_NOT_LONG: /* 0x7e */ 12589 /* File: armv5te/alt_stub.S */ 12590 /* 12591 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12592 * any interesting requests and then jump to the real instruction 12593 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12594 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12595 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12596 * bail to the real handler if breakFlags==0. 12597 */ 12598 ldrb r3, [rSELF, #offThread_breakFlags] 12599 adrl lr, dvmAsmInstructionStart + (126 * 64) 12600 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12601 cmp r3, #0 12602 bxeq lr @ nothing to do - jump to real handler 12603 EXPORT_PC() 12604 mov r0, rPC @ arg0 12605 mov r1, rFP @ arg1 12606 mov r2, rSELF @ arg2 12607 b dvmCheckBefore @ (dPC,dFP,self) tail call 12608 12609 /* ------------------------------ */ 12610 .balign 64 12611 .L_ALT_OP_NEG_FLOAT: /* 0x7f */ 12612 /* File: armv5te/alt_stub.S */ 12613 /* 12614 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12615 * any interesting requests and then jump to the real instruction 12616 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12617 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12618 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12619 * bail to the real handler if breakFlags==0. 12620 */ 12621 ldrb r3, [rSELF, #offThread_breakFlags] 12622 adrl lr, dvmAsmInstructionStart + (127 * 64) 12623 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12624 cmp r3, #0 12625 bxeq lr @ nothing to do - jump to real handler 12626 EXPORT_PC() 12627 mov r0, rPC @ arg0 12628 mov r1, rFP @ arg1 12629 mov r2, rSELF @ arg2 12630 b dvmCheckBefore @ (dPC,dFP,self) tail call 12631 12632 /* ------------------------------ */ 12633 .balign 64 12634 .L_ALT_OP_NEG_DOUBLE: /* 0x80 */ 12635 /* File: armv5te/alt_stub.S */ 12636 /* 12637 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12638 * any interesting requests and then jump to the real instruction 12639 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12640 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12641 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12642 * bail to the real handler if breakFlags==0. 12643 */ 12644 ldrb r3, [rSELF, #offThread_breakFlags] 12645 adrl lr, dvmAsmInstructionStart + (128 * 64) 12646 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12647 cmp r3, #0 12648 bxeq lr @ nothing to do - jump to real handler 12649 EXPORT_PC() 12650 mov r0, rPC @ arg0 12651 mov r1, rFP @ arg1 12652 mov r2, rSELF @ arg2 12653 b dvmCheckBefore @ (dPC,dFP,self) tail call 12654 12655 /* ------------------------------ */ 12656 .balign 64 12657 .L_ALT_OP_INT_TO_LONG: /* 0x81 */ 12658 /* File: armv5te/alt_stub.S */ 12659 /* 12660 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12661 * any interesting requests and then jump to the real instruction 12662 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12663 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12664 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12665 * bail to the real handler if breakFlags==0. 12666 */ 12667 ldrb r3, [rSELF, #offThread_breakFlags] 12668 adrl lr, dvmAsmInstructionStart + (129 * 64) 12669 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12670 cmp r3, #0 12671 bxeq lr @ nothing to do - jump to real handler 12672 EXPORT_PC() 12673 mov r0, rPC @ arg0 12674 mov r1, rFP @ arg1 12675 mov r2, rSELF @ arg2 12676 b dvmCheckBefore @ (dPC,dFP,self) tail call 12677 12678 /* ------------------------------ */ 12679 .balign 64 12680 .L_ALT_OP_INT_TO_FLOAT: /* 0x82 */ 12681 /* File: armv5te/alt_stub.S */ 12682 /* 12683 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12684 * any interesting requests and then jump to the real instruction 12685 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12686 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12687 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12688 * bail to the real handler if breakFlags==0. 12689 */ 12690 ldrb r3, [rSELF, #offThread_breakFlags] 12691 adrl lr, dvmAsmInstructionStart + (130 * 64) 12692 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12693 cmp r3, #0 12694 bxeq lr @ nothing to do - jump to real handler 12695 EXPORT_PC() 12696 mov r0, rPC @ arg0 12697 mov r1, rFP @ arg1 12698 mov r2, rSELF @ arg2 12699 b dvmCheckBefore @ (dPC,dFP,self) tail call 12700 12701 /* ------------------------------ */ 12702 .balign 64 12703 .L_ALT_OP_INT_TO_DOUBLE: /* 0x83 */ 12704 /* File: armv5te/alt_stub.S */ 12705 /* 12706 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12707 * any interesting requests and then jump to the real instruction 12708 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12709 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12710 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12711 * bail to the real handler if breakFlags==0. 12712 */ 12713 ldrb r3, [rSELF, #offThread_breakFlags] 12714 adrl lr, dvmAsmInstructionStart + (131 * 64) 12715 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12716 cmp r3, #0 12717 bxeq lr @ nothing to do - jump to real handler 12718 EXPORT_PC() 12719 mov r0, rPC @ arg0 12720 mov r1, rFP @ arg1 12721 mov r2, rSELF @ arg2 12722 b dvmCheckBefore @ (dPC,dFP,self) tail call 12723 12724 /* ------------------------------ */ 12725 .balign 64 12726 .L_ALT_OP_LONG_TO_INT: /* 0x84 */ 12727 /* File: armv5te/alt_stub.S */ 12728 /* 12729 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12730 * any interesting requests and then jump to the real instruction 12731 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12732 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12733 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12734 * bail to the real handler if breakFlags==0. 12735 */ 12736 ldrb r3, [rSELF, #offThread_breakFlags] 12737 adrl lr, dvmAsmInstructionStart + (132 * 64) 12738 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12739 cmp r3, #0 12740 bxeq lr @ nothing to do - jump to real handler 12741 EXPORT_PC() 12742 mov r0, rPC @ arg0 12743 mov r1, rFP @ arg1 12744 mov r2, rSELF @ arg2 12745 b dvmCheckBefore @ (dPC,dFP,self) tail call 12746 12747 /* ------------------------------ */ 12748 .balign 64 12749 .L_ALT_OP_LONG_TO_FLOAT: /* 0x85 */ 12750 /* File: armv5te/alt_stub.S */ 12751 /* 12752 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12753 * any interesting requests and then jump to the real instruction 12754 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12755 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12756 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12757 * bail to the real handler if breakFlags==0. 12758 */ 12759 ldrb r3, [rSELF, #offThread_breakFlags] 12760 adrl lr, dvmAsmInstructionStart + (133 * 64) 12761 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12762 cmp r3, #0 12763 bxeq lr @ nothing to do - jump to real handler 12764 EXPORT_PC() 12765 mov r0, rPC @ arg0 12766 mov r1, rFP @ arg1 12767 mov r2, rSELF @ arg2 12768 b dvmCheckBefore @ (dPC,dFP,self) tail call 12769 12770 /* ------------------------------ */ 12771 .balign 64 12772 .L_ALT_OP_LONG_TO_DOUBLE: /* 0x86 */ 12773 /* File: armv5te/alt_stub.S */ 12774 /* 12775 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12776 * any interesting requests and then jump to the real instruction 12777 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12778 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12779 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12780 * bail to the real handler if breakFlags==0. 12781 */ 12782 ldrb r3, [rSELF, #offThread_breakFlags] 12783 adrl lr, dvmAsmInstructionStart + (134 * 64) 12784 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12785 cmp r3, #0 12786 bxeq lr @ nothing to do - jump to real handler 12787 EXPORT_PC() 12788 mov r0, rPC @ arg0 12789 mov r1, rFP @ arg1 12790 mov r2, rSELF @ arg2 12791 b dvmCheckBefore @ (dPC,dFP,self) tail call 12792 12793 /* ------------------------------ */ 12794 .balign 64 12795 .L_ALT_OP_FLOAT_TO_INT: /* 0x87 */ 12796 /* File: armv5te/alt_stub.S */ 12797 /* 12798 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12799 * any interesting requests and then jump to the real instruction 12800 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12801 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12802 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12803 * bail to the real handler if breakFlags==0. 12804 */ 12805 ldrb r3, [rSELF, #offThread_breakFlags] 12806 adrl lr, dvmAsmInstructionStart + (135 * 64) 12807 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12808 cmp r3, #0 12809 bxeq lr @ nothing to do - jump to real handler 12810 EXPORT_PC() 12811 mov r0, rPC @ arg0 12812 mov r1, rFP @ arg1 12813 mov r2, rSELF @ arg2 12814 b dvmCheckBefore @ (dPC,dFP,self) tail call 12815 12816 /* ------------------------------ */ 12817 .balign 64 12818 .L_ALT_OP_FLOAT_TO_LONG: /* 0x88 */ 12819 /* File: armv5te/alt_stub.S */ 12820 /* 12821 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12822 * any interesting requests and then jump to the real instruction 12823 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12824 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12825 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12826 * bail to the real handler if breakFlags==0. 12827 */ 12828 ldrb r3, [rSELF, #offThread_breakFlags] 12829 adrl lr, dvmAsmInstructionStart + (136 * 64) 12830 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12831 cmp r3, #0 12832 bxeq lr @ nothing to do - jump to real handler 12833 EXPORT_PC() 12834 mov r0, rPC @ arg0 12835 mov r1, rFP @ arg1 12836 mov r2, rSELF @ arg2 12837 b dvmCheckBefore @ (dPC,dFP,self) tail call 12838 12839 /* ------------------------------ */ 12840 .balign 64 12841 .L_ALT_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 12842 /* File: armv5te/alt_stub.S */ 12843 /* 12844 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12845 * any interesting requests and then jump to the real instruction 12846 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12847 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12848 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12849 * bail to the real handler if breakFlags==0. 12850 */ 12851 ldrb r3, [rSELF, #offThread_breakFlags] 12852 adrl lr, dvmAsmInstructionStart + (137 * 64) 12853 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12854 cmp r3, #0 12855 bxeq lr @ nothing to do - jump to real handler 12856 EXPORT_PC() 12857 mov r0, rPC @ arg0 12858 mov r1, rFP @ arg1 12859 mov r2, rSELF @ arg2 12860 b dvmCheckBefore @ (dPC,dFP,self) tail call 12861 12862 /* ------------------------------ */ 12863 .balign 64 12864 .L_ALT_OP_DOUBLE_TO_INT: /* 0x8a */ 12865 /* File: armv5te/alt_stub.S */ 12866 /* 12867 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12868 * any interesting requests and then jump to the real instruction 12869 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12870 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12871 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12872 * bail to the real handler if breakFlags==0. 12873 */ 12874 ldrb r3, [rSELF, #offThread_breakFlags] 12875 adrl lr, dvmAsmInstructionStart + (138 * 64) 12876 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12877 cmp r3, #0 12878 bxeq lr @ nothing to do - jump to real handler 12879 EXPORT_PC() 12880 mov r0, rPC @ arg0 12881 mov r1, rFP @ arg1 12882 mov r2, rSELF @ arg2 12883 b dvmCheckBefore @ (dPC,dFP,self) tail call 12884 12885 /* ------------------------------ */ 12886 .balign 64 12887 .L_ALT_OP_DOUBLE_TO_LONG: /* 0x8b */ 12888 /* File: armv5te/alt_stub.S */ 12889 /* 12890 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12891 * any interesting requests and then jump to the real instruction 12892 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12893 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12894 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12895 * bail to the real handler if breakFlags==0. 12896 */ 12897 ldrb r3, [rSELF, #offThread_breakFlags] 12898 adrl lr, dvmAsmInstructionStart + (139 * 64) 12899 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12900 cmp r3, #0 12901 bxeq lr @ nothing to do - jump to real handler 12902 EXPORT_PC() 12903 mov r0, rPC @ arg0 12904 mov r1, rFP @ arg1 12905 mov r2, rSELF @ arg2 12906 b dvmCheckBefore @ (dPC,dFP,self) tail call 12907 12908 /* ------------------------------ */ 12909 .balign 64 12910 .L_ALT_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 12911 /* File: armv5te/alt_stub.S */ 12912 /* 12913 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12914 * any interesting requests and then jump to the real instruction 12915 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12916 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12917 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12918 * bail to the real handler if breakFlags==0. 12919 */ 12920 ldrb r3, [rSELF, #offThread_breakFlags] 12921 adrl lr, dvmAsmInstructionStart + (140 * 64) 12922 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12923 cmp r3, #0 12924 bxeq lr @ nothing to do - jump to real handler 12925 EXPORT_PC() 12926 mov r0, rPC @ arg0 12927 mov r1, rFP @ arg1 12928 mov r2, rSELF @ arg2 12929 b dvmCheckBefore @ (dPC,dFP,self) tail call 12930 12931 /* ------------------------------ */ 12932 .balign 64 12933 .L_ALT_OP_INT_TO_BYTE: /* 0x8d */ 12934 /* File: armv5te/alt_stub.S */ 12935 /* 12936 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12937 * any interesting requests and then jump to the real instruction 12938 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12939 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12940 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12941 * bail to the real handler if breakFlags==0. 12942 */ 12943 ldrb r3, [rSELF, #offThread_breakFlags] 12944 adrl lr, dvmAsmInstructionStart + (141 * 64) 12945 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12946 cmp r3, #0 12947 bxeq lr @ nothing to do - jump to real handler 12948 EXPORT_PC() 12949 mov r0, rPC @ arg0 12950 mov r1, rFP @ arg1 12951 mov r2, rSELF @ arg2 12952 b dvmCheckBefore @ (dPC,dFP,self) tail call 12953 12954 /* ------------------------------ */ 12955 .balign 64 12956 .L_ALT_OP_INT_TO_CHAR: /* 0x8e */ 12957 /* File: armv5te/alt_stub.S */ 12958 /* 12959 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12960 * any interesting requests and then jump to the real instruction 12961 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12962 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12963 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12964 * bail to the real handler if breakFlags==0. 12965 */ 12966 ldrb r3, [rSELF, #offThread_breakFlags] 12967 adrl lr, dvmAsmInstructionStart + (142 * 64) 12968 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12969 cmp r3, #0 12970 bxeq lr @ nothing to do - jump to real handler 12971 EXPORT_PC() 12972 mov r0, rPC @ arg0 12973 mov r1, rFP @ arg1 12974 mov r2, rSELF @ arg2 12975 b dvmCheckBefore @ (dPC,dFP,self) tail call 12976 12977 /* ------------------------------ */ 12978 .balign 64 12979 .L_ALT_OP_INT_TO_SHORT: /* 0x8f */ 12980 /* File: armv5te/alt_stub.S */ 12981 /* 12982 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12983 * any interesting requests and then jump to the real instruction 12984 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12985 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12986 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12987 * bail to the real handler if breakFlags==0. 12988 */ 12989 ldrb r3, [rSELF, #offThread_breakFlags] 12990 adrl lr, dvmAsmInstructionStart + (143 * 64) 12991 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12992 cmp r3, #0 12993 bxeq lr @ nothing to do - jump to real handler 12994 EXPORT_PC() 12995 mov r0, rPC @ arg0 12996 mov r1, rFP @ arg1 12997 mov r2, rSELF @ arg2 12998 b dvmCheckBefore @ (dPC,dFP,self) tail call 12999 13000 /* ------------------------------ */ 13001 .balign 64 13002 .L_ALT_OP_ADD_INT: /* 0x90 */ 13003 /* File: armv5te/alt_stub.S */ 13004 /* 13005 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13006 * any interesting requests and then jump to the real instruction 13007 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13008 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13009 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13010 * bail to the real handler if breakFlags==0. 13011 */ 13012 ldrb r3, [rSELF, #offThread_breakFlags] 13013 adrl lr, dvmAsmInstructionStart + (144 * 64) 13014 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13015 cmp r3, #0 13016 bxeq lr @ nothing to do - jump to real handler 13017 EXPORT_PC() 13018 mov r0, rPC @ arg0 13019 mov r1, rFP @ arg1 13020 mov r2, rSELF @ arg2 13021 b dvmCheckBefore @ (dPC,dFP,self) tail call 13022 13023 /* ------------------------------ */ 13024 .balign 64 13025 .L_ALT_OP_SUB_INT: /* 0x91 */ 13026 /* File: armv5te/alt_stub.S */ 13027 /* 13028 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13029 * any interesting requests and then jump to the real instruction 13030 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13031 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13032 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13033 * bail to the real handler if breakFlags==0. 13034 */ 13035 ldrb r3, [rSELF, #offThread_breakFlags] 13036 adrl lr, dvmAsmInstructionStart + (145 * 64) 13037 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13038 cmp r3, #0 13039 bxeq lr @ nothing to do - jump to real handler 13040 EXPORT_PC() 13041 mov r0, rPC @ arg0 13042 mov r1, rFP @ arg1 13043 mov r2, rSELF @ arg2 13044 b dvmCheckBefore @ (dPC,dFP,self) tail call 13045 13046 /* ------------------------------ */ 13047 .balign 64 13048 .L_ALT_OP_MUL_INT: /* 0x92 */ 13049 /* File: armv5te/alt_stub.S */ 13050 /* 13051 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13052 * any interesting requests and then jump to the real instruction 13053 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13054 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13055 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13056 * bail to the real handler if breakFlags==0. 13057 */ 13058 ldrb r3, [rSELF, #offThread_breakFlags] 13059 adrl lr, dvmAsmInstructionStart + (146 * 64) 13060 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13061 cmp r3, #0 13062 bxeq lr @ nothing to do - jump to real handler 13063 EXPORT_PC() 13064 mov r0, rPC @ arg0 13065 mov r1, rFP @ arg1 13066 mov r2, rSELF @ arg2 13067 b dvmCheckBefore @ (dPC,dFP,self) tail call 13068 13069 /* ------------------------------ */ 13070 .balign 64 13071 .L_ALT_OP_DIV_INT: /* 0x93 */ 13072 /* File: armv5te/alt_stub.S */ 13073 /* 13074 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13075 * any interesting requests and then jump to the real instruction 13076 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13077 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13078 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13079 * bail to the real handler if breakFlags==0. 13080 */ 13081 ldrb r3, [rSELF, #offThread_breakFlags] 13082 adrl lr, dvmAsmInstructionStart + (147 * 64) 13083 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13084 cmp r3, #0 13085 bxeq lr @ nothing to do - jump to real handler 13086 EXPORT_PC() 13087 mov r0, rPC @ arg0 13088 mov r1, rFP @ arg1 13089 mov r2, rSELF @ arg2 13090 b dvmCheckBefore @ (dPC,dFP,self) tail call 13091 13092 /* ------------------------------ */ 13093 .balign 64 13094 .L_ALT_OP_REM_INT: /* 0x94 */ 13095 /* File: armv5te/alt_stub.S */ 13096 /* 13097 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13098 * any interesting requests and then jump to the real instruction 13099 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13100 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13101 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13102 * bail to the real handler if breakFlags==0. 13103 */ 13104 ldrb r3, [rSELF, #offThread_breakFlags] 13105 adrl lr, dvmAsmInstructionStart + (148 * 64) 13106 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13107 cmp r3, #0 13108 bxeq lr @ nothing to do - jump to real handler 13109 EXPORT_PC() 13110 mov r0, rPC @ arg0 13111 mov r1, rFP @ arg1 13112 mov r2, rSELF @ arg2 13113 b dvmCheckBefore @ (dPC,dFP,self) tail call 13114 13115 /* ------------------------------ */ 13116 .balign 64 13117 .L_ALT_OP_AND_INT: /* 0x95 */ 13118 /* File: armv5te/alt_stub.S */ 13119 /* 13120 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13121 * any interesting requests and then jump to the real instruction 13122 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13123 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13124 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13125 * bail to the real handler if breakFlags==0. 13126 */ 13127 ldrb r3, [rSELF, #offThread_breakFlags] 13128 adrl lr, dvmAsmInstructionStart + (149 * 64) 13129 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13130 cmp r3, #0 13131 bxeq lr @ nothing to do - jump to real handler 13132 EXPORT_PC() 13133 mov r0, rPC @ arg0 13134 mov r1, rFP @ arg1 13135 mov r2, rSELF @ arg2 13136 b dvmCheckBefore @ (dPC,dFP,self) tail call 13137 13138 /* ------------------------------ */ 13139 .balign 64 13140 .L_ALT_OP_OR_INT: /* 0x96 */ 13141 /* File: armv5te/alt_stub.S */ 13142 /* 13143 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13144 * any interesting requests and then jump to the real instruction 13145 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13146 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13147 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13148 * bail to the real handler if breakFlags==0. 13149 */ 13150 ldrb r3, [rSELF, #offThread_breakFlags] 13151 adrl lr, dvmAsmInstructionStart + (150 * 64) 13152 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13153 cmp r3, #0 13154 bxeq lr @ nothing to do - jump to real handler 13155 EXPORT_PC() 13156 mov r0, rPC @ arg0 13157 mov r1, rFP @ arg1 13158 mov r2, rSELF @ arg2 13159 b dvmCheckBefore @ (dPC,dFP,self) tail call 13160 13161 /* ------------------------------ */ 13162 .balign 64 13163 .L_ALT_OP_XOR_INT: /* 0x97 */ 13164 /* File: armv5te/alt_stub.S */ 13165 /* 13166 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13167 * any interesting requests and then jump to the real instruction 13168 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13169 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13170 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13171 * bail to the real handler if breakFlags==0. 13172 */ 13173 ldrb r3, [rSELF, #offThread_breakFlags] 13174 adrl lr, dvmAsmInstructionStart + (151 * 64) 13175 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13176 cmp r3, #0 13177 bxeq lr @ nothing to do - jump to real handler 13178 EXPORT_PC() 13179 mov r0, rPC @ arg0 13180 mov r1, rFP @ arg1 13181 mov r2, rSELF @ arg2 13182 b dvmCheckBefore @ (dPC,dFP,self) tail call 13183 13184 /* ------------------------------ */ 13185 .balign 64 13186 .L_ALT_OP_SHL_INT: /* 0x98 */ 13187 /* File: armv5te/alt_stub.S */ 13188 /* 13189 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13190 * any interesting requests and then jump to the real instruction 13191 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13192 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13193 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13194 * bail to the real handler if breakFlags==0. 13195 */ 13196 ldrb r3, [rSELF, #offThread_breakFlags] 13197 adrl lr, dvmAsmInstructionStart + (152 * 64) 13198 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13199 cmp r3, #0 13200 bxeq lr @ nothing to do - jump to real handler 13201 EXPORT_PC() 13202 mov r0, rPC @ arg0 13203 mov r1, rFP @ arg1 13204 mov r2, rSELF @ arg2 13205 b dvmCheckBefore @ (dPC,dFP,self) tail call 13206 13207 /* ------------------------------ */ 13208 .balign 64 13209 .L_ALT_OP_SHR_INT: /* 0x99 */ 13210 /* File: armv5te/alt_stub.S */ 13211 /* 13212 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13213 * any interesting requests and then jump to the real instruction 13214 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13215 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13216 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13217 * bail to the real handler if breakFlags==0. 13218 */ 13219 ldrb r3, [rSELF, #offThread_breakFlags] 13220 adrl lr, dvmAsmInstructionStart + (153 * 64) 13221 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13222 cmp r3, #0 13223 bxeq lr @ nothing to do - jump to real handler 13224 EXPORT_PC() 13225 mov r0, rPC @ arg0 13226 mov r1, rFP @ arg1 13227 mov r2, rSELF @ arg2 13228 b dvmCheckBefore @ (dPC,dFP,self) tail call 13229 13230 /* ------------------------------ */ 13231 .balign 64 13232 .L_ALT_OP_USHR_INT: /* 0x9a */ 13233 /* File: armv5te/alt_stub.S */ 13234 /* 13235 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13236 * any interesting requests and then jump to the real instruction 13237 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13238 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13239 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13240 * bail to the real handler if breakFlags==0. 13241 */ 13242 ldrb r3, [rSELF, #offThread_breakFlags] 13243 adrl lr, dvmAsmInstructionStart + (154 * 64) 13244 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13245 cmp r3, #0 13246 bxeq lr @ nothing to do - jump to real handler 13247 EXPORT_PC() 13248 mov r0, rPC @ arg0 13249 mov r1, rFP @ arg1 13250 mov r2, rSELF @ arg2 13251 b dvmCheckBefore @ (dPC,dFP,self) tail call 13252 13253 /* ------------------------------ */ 13254 .balign 64 13255 .L_ALT_OP_ADD_LONG: /* 0x9b */ 13256 /* File: armv5te/alt_stub.S */ 13257 /* 13258 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13259 * any interesting requests and then jump to the real instruction 13260 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13261 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13262 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13263 * bail to the real handler if breakFlags==0. 13264 */ 13265 ldrb r3, [rSELF, #offThread_breakFlags] 13266 adrl lr, dvmAsmInstructionStart + (155 * 64) 13267 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13268 cmp r3, #0 13269 bxeq lr @ nothing to do - jump to real handler 13270 EXPORT_PC() 13271 mov r0, rPC @ arg0 13272 mov r1, rFP @ arg1 13273 mov r2, rSELF @ arg2 13274 b dvmCheckBefore @ (dPC,dFP,self) tail call 13275 13276 /* ------------------------------ */ 13277 .balign 64 13278 .L_ALT_OP_SUB_LONG: /* 0x9c */ 13279 /* File: armv5te/alt_stub.S */ 13280 /* 13281 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13282 * any interesting requests and then jump to the real instruction 13283 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13284 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13285 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13286 * bail to the real handler if breakFlags==0. 13287 */ 13288 ldrb r3, [rSELF, #offThread_breakFlags] 13289 adrl lr, dvmAsmInstructionStart + (156 * 64) 13290 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13291 cmp r3, #0 13292 bxeq lr @ nothing to do - jump to real handler 13293 EXPORT_PC() 13294 mov r0, rPC @ arg0 13295 mov r1, rFP @ arg1 13296 mov r2, rSELF @ arg2 13297 b dvmCheckBefore @ (dPC,dFP,self) tail call 13298 13299 /* ------------------------------ */ 13300 .balign 64 13301 .L_ALT_OP_MUL_LONG: /* 0x9d */ 13302 /* File: armv5te/alt_stub.S */ 13303 /* 13304 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13305 * any interesting requests and then jump to the real instruction 13306 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13307 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13308 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13309 * bail to the real handler if breakFlags==0. 13310 */ 13311 ldrb r3, [rSELF, #offThread_breakFlags] 13312 adrl lr, dvmAsmInstructionStart + (157 * 64) 13313 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13314 cmp r3, #0 13315 bxeq lr @ nothing to do - jump to real handler 13316 EXPORT_PC() 13317 mov r0, rPC @ arg0 13318 mov r1, rFP @ arg1 13319 mov r2, rSELF @ arg2 13320 b dvmCheckBefore @ (dPC,dFP,self) tail call 13321 13322 /* ------------------------------ */ 13323 .balign 64 13324 .L_ALT_OP_DIV_LONG: /* 0x9e */ 13325 /* File: armv5te/alt_stub.S */ 13326 /* 13327 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13328 * any interesting requests and then jump to the real instruction 13329 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13330 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13331 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13332 * bail to the real handler if breakFlags==0. 13333 */ 13334 ldrb r3, [rSELF, #offThread_breakFlags] 13335 adrl lr, dvmAsmInstructionStart + (158 * 64) 13336 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13337 cmp r3, #0 13338 bxeq lr @ nothing to do - jump to real handler 13339 EXPORT_PC() 13340 mov r0, rPC @ arg0 13341 mov r1, rFP @ arg1 13342 mov r2, rSELF @ arg2 13343 b dvmCheckBefore @ (dPC,dFP,self) tail call 13344 13345 /* ------------------------------ */ 13346 .balign 64 13347 .L_ALT_OP_REM_LONG: /* 0x9f */ 13348 /* File: armv5te/alt_stub.S */ 13349 /* 13350 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13351 * any interesting requests and then jump to the real instruction 13352 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13353 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13354 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13355 * bail to the real handler if breakFlags==0. 13356 */ 13357 ldrb r3, [rSELF, #offThread_breakFlags] 13358 adrl lr, dvmAsmInstructionStart + (159 * 64) 13359 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13360 cmp r3, #0 13361 bxeq lr @ nothing to do - jump to real handler 13362 EXPORT_PC() 13363 mov r0, rPC @ arg0 13364 mov r1, rFP @ arg1 13365 mov r2, rSELF @ arg2 13366 b dvmCheckBefore @ (dPC,dFP,self) tail call 13367 13368 /* ------------------------------ */ 13369 .balign 64 13370 .L_ALT_OP_AND_LONG: /* 0xa0 */ 13371 /* File: armv5te/alt_stub.S */ 13372 /* 13373 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13374 * any interesting requests and then jump to the real instruction 13375 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13376 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13377 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13378 * bail to the real handler if breakFlags==0. 13379 */ 13380 ldrb r3, [rSELF, #offThread_breakFlags] 13381 adrl lr, dvmAsmInstructionStart + (160 * 64) 13382 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13383 cmp r3, #0 13384 bxeq lr @ nothing to do - jump to real handler 13385 EXPORT_PC() 13386 mov r0, rPC @ arg0 13387 mov r1, rFP @ arg1 13388 mov r2, rSELF @ arg2 13389 b dvmCheckBefore @ (dPC,dFP,self) tail call 13390 13391 /* ------------------------------ */ 13392 .balign 64 13393 .L_ALT_OP_OR_LONG: /* 0xa1 */ 13394 /* File: armv5te/alt_stub.S */ 13395 /* 13396 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13397 * any interesting requests and then jump to the real instruction 13398 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13399 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13400 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13401 * bail to the real handler if breakFlags==0. 13402 */ 13403 ldrb r3, [rSELF, #offThread_breakFlags] 13404 adrl lr, dvmAsmInstructionStart + (161 * 64) 13405 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13406 cmp r3, #0 13407 bxeq lr @ nothing to do - jump to real handler 13408 EXPORT_PC() 13409 mov r0, rPC @ arg0 13410 mov r1, rFP @ arg1 13411 mov r2, rSELF @ arg2 13412 b dvmCheckBefore @ (dPC,dFP,self) tail call 13413 13414 /* ------------------------------ */ 13415 .balign 64 13416 .L_ALT_OP_XOR_LONG: /* 0xa2 */ 13417 /* File: armv5te/alt_stub.S */ 13418 /* 13419 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13420 * any interesting requests and then jump to the real instruction 13421 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13422 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13423 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13424 * bail to the real handler if breakFlags==0. 13425 */ 13426 ldrb r3, [rSELF, #offThread_breakFlags] 13427 adrl lr, dvmAsmInstructionStart + (162 * 64) 13428 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13429 cmp r3, #0 13430 bxeq lr @ nothing to do - jump to real handler 13431 EXPORT_PC() 13432 mov r0, rPC @ arg0 13433 mov r1, rFP @ arg1 13434 mov r2, rSELF @ arg2 13435 b dvmCheckBefore @ (dPC,dFP,self) tail call 13436 13437 /* ------------------------------ */ 13438 .balign 64 13439 .L_ALT_OP_SHL_LONG: /* 0xa3 */ 13440 /* File: armv5te/alt_stub.S */ 13441 /* 13442 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13443 * any interesting requests and then jump to the real instruction 13444 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13445 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13446 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13447 * bail to the real handler if breakFlags==0. 13448 */ 13449 ldrb r3, [rSELF, #offThread_breakFlags] 13450 adrl lr, dvmAsmInstructionStart + (163 * 64) 13451 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13452 cmp r3, #0 13453 bxeq lr @ nothing to do - jump to real handler 13454 EXPORT_PC() 13455 mov r0, rPC @ arg0 13456 mov r1, rFP @ arg1 13457 mov r2, rSELF @ arg2 13458 b dvmCheckBefore @ (dPC,dFP,self) tail call 13459 13460 /* ------------------------------ */ 13461 .balign 64 13462 .L_ALT_OP_SHR_LONG: /* 0xa4 */ 13463 /* File: armv5te/alt_stub.S */ 13464 /* 13465 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13466 * any interesting requests and then jump to the real instruction 13467 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13468 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13469 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13470 * bail to the real handler if breakFlags==0. 13471 */ 13472 ldrb r3, [rSELF, #offThread_breakFlags] 13473 adrl lr, dvmAsmInstructionStart + (164 * 64) 13474 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13475 cmp r3, #0 13476 bxeq lr @ nothing to do - jump to real handler 13477 EXPORT_PC() 13478 mov r0, rPC @ arg0 13479 mov r1, rFP @ arg1 13480 mov r2, rSELF @ arg2 13481 b dvmCheckBefore @ (dPC,dFP,self) tail call 13482 13483 /* ------------------------------ */ 13484 .balign 64 13485 .L_ALT_OP_USHR_LONG: /* 0xa5 */ 13486 /* File: armv5te/alt_stub.S */ 13487 /* 13488 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13489 * any interesting requests and then jump to the real instruction 13490 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13491 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13492 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13493 * bail to the real handler if breakFlags==0. 13494 */ 13495 ldrb r3, [rSELF, #offThread_breakFlags] 13496 adrl lr, dvmAsmInstructionStart + (165 * 64) 13497 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13498 cmp r3, #0 13499 bxeq lr @ nothing to do - jump to real handler 13500 EXPORT_PC() 13501 mov r0, rPC @ arg0 13502 mov r1, rFP @ arg1 13503 mov r2, rSELF @ arg2 13504 b dvmCheckBefore @ (dPC,dFP,self) tail call 13505 13506 /* ------------------------------ */ 13507 .balign 64 13508 .L_ALT_OP_ADD_FLOAT: /* 0xa6 */ 13509 /* File: armv5te/alt_stub.S */ 13510 /* 13511 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13512 * any interesting requests and then jump to the real instruction 13513 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13514 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13515 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13516 * bail to the real handler if breakFlags==0. 13517 */ 13518 ldrb r3, [rSELF, #offThread_breakFlags] 13519 adrl lr, dvmAsmInstructionStart + (166 * 64) 13520 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13521 cmp r3, #0 13522 bxeq lr @ nothing to do - jump to real handler 13523 EXPORT_PC() 13524 mov r0, rPC @ arg0 13525 mov r1, rFP @ arg1 13526 mov r2, rSELF @ arg2 13527 b dvmCheckBefore @ (dPC,dFP,self) tail call 13528 13529 /* ------------------------------ */ 13530 .balign 64 13531 .L_ALT_OP_SUB_FLOAT: /* 0xa7 */ 13532 /* File: armv5te/alt_stub.S */ 13533 /* 13534 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13535 * any interesting requests and then jump to the real instruction 13536 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13537 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13538 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13539 * bail to the real handler if breakFlags==0. 13540 */ 13541 ldrb r3, [rSELF, #offThread_breakFlags] 13542 adrl lr, dvmAsmInstructionStart + (167 * 64) 13543 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13544 cmp r3, #0 13545 bxeq lr @ nothing to do - jump to real handler 13546 EXPORT_PC() 13547 mov r0, rPC @ arg0 13548 mov r1, rFP @ arg1 13549 mov r2, rSELF @ arg2 13550 b dvmCheckBefore @ (dPC,dFP,self) tail call 13551 13552 /* ------------------------------ */ 13553 .balign 64 13554 .L_ALT_OP_MUL_FLOAT: /* 0xa8 */ 13555 /* File: armv5te/alt_stub.S */ 13556 /* 13557 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13558 * any interesting requests and then jump to the real instruction 13559 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13560 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13561 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13562 * bail to the real handler if breakFlags==0. 13563 */ 13564 ldrb r3, [rSELF, #offThread_breakFlags] 13565 adrl lr, dvmAsmInstructionStart + (168 * 64) 13566 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13567 cmp r3, #0 13568 bxeq lr @ nothing to do - jump to real handler 13569 EXPORT_PC() 13570 mov r0, rPC @ arg0 13571 mov r1, rFP @ arg1 13572 mov r2, rSELF @ arg2 13573 b dvmCheckBefore @ (dPC,dFP,self) tail call 13574 13575 /* ------------------------------ */ 13576 .balign 64 13577 .L_ALT_OP_DIV_FLOAT: /* 0xa9 */ 13578 /* File: armv5te/alt_stub.S */ 13579 /* 13580 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13581 * any interesting requests and then jump to the real instruction 13582 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13583 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13584 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13585 * bail to the real handler if breakFlags==0. 13586 */ 13587 ldrb r3, [rSELF, #offThread_breakFlags] 13588 adrl lr, dvmAsmInstructionStart + (169 * 64) 13589 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13590 cmp r3, #0 13591 bxeq lr @ nothing to do - jump to real handler 13592 EXPORT_PC() 13593 mov r0, rPC @ arg0 13594 mov r1, rFP @ arg1 13595 mov r2, rSELF @ arg2 13596 b dvmCheckBefore @ (dPC,dFP,self) tail call 13597 13598 /* ------------------------------ */ 13599 .balign 64 13600 .L_ALT_OP_REM_FLOAT: /* 0xaa */ 13601 /* File: armv5te/alt_stub.S */ 13602 /* 13603 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13604 * any interesting requests and then jump to the real instruction 13605 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13606 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13607 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13608 * bail to the real handler if breakFlags==0. 13609 */ 13610 ldrb r3, [rSELF, #offThread_breakFlags] 13611 adrl lr, dvmAsmInstructionStart + (170 * 64) 13612 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13613 cmp r3, #0 13614 bxeq lr @ nothing to do - jump to real handler 13615 EXPORT_PC() 13616 mov r0, rPC @ arg0 13617 mov r1, rFP @ arg1 13618 mov r2, rSELF @ arg2 13619 b dvmCheckBefore @ (dPC,dFP,self) tail call 13620 13621 /* ------------------------------ */ 13622 .balign 64 13623 .L_ALT_OP_ADD_DOUBLE: /* 0xab */ 13624 /* File: armv5te/alt_stub.S */ 13625 /* 13626 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13627 * any interesting requests and then jump to the real instruction 13628 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13629 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13630 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13631 * bail to the real handler if breakFlags==0. 13632 */ 13633 ldrb r3, [rSELF, #offThread_breakFlags] 13634 adrl lr, dvmAsmInstructionStart + (171 * 64) 13635 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13636 cmp r3, #0 13637 bxeq lr @ nothing to do - jump to real handler 13638 EXPORT_PC() 13639 mov r0, rPC @ arg0 13640 mov r1, rFP @ arg1 13641 mov r2, rSELF @ arg2 13642 b dvmCheckBefore @ (dPC,dFP,self) tail call 13643 13644 /* ------------------------------ */ 13645 .balign 64 13646 .L_ALT_OP_SUB_DOUBLE: /* 0xac */ 13647 /* File: armv5te/alt_stub.S */ 13648 /* 13649 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13650 * any interesting requests and then jump to the real instruction 13651 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13652 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13653 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13654 * bail to the real handler if breakFlags==0. 13655 */ 13656 ldrb r3, [rSELF, #offThread_breakFlags] 13657 adrl lr, dvmAsmInstructionStart + (172 * 64) 13658 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13659 cmp r3, #0 13660 bxeq lr @ nothing to do - jump to real handler 13661 EXPORT_PC() 13662 mov r0, rPC @ arg0 13663 mov r1, rFP @ arg1 13664 mov r2, rSELF @ arg2 13665 b dvmCheckBefore @ (dPC,dFP,self) tail call 13666 13667 /* ------------------------------ */ 13668 .balign 64 13669 .L_ALT_OP_MUL_DOUBLE: /* 0xad */ 13670 /* File: armv5te/alt_stub.S */ 13671 /* 13672 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13673 * any interesting requests and then jump to the real instruction 13674 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13675 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13676 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13677 * bail to the real handler if breakFlags==0. 13678 */ 13679 ldrb r3, [rSELF, #offThread_breakFlags] 13680 adrl lr, dvmAsmInstructionStart + (173 * 64) 13681 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13682 cmp r3, #0 13683 bxeq lr @ nothing to do - jump to real handler 13684 EXPORT_PC() 13685 mov r0, rPC @ arg0 13686 mov r1, rFP @ arg1 13687 mov r2, rSELF @ arg2 13688 b dvmCheckBefore @ (dPC,dFP,self) tail call 13689 13690 /* ------------------------------ */ 13691 .balign 64 13692 .L_ALT_OP_DIV_DOUBLE: /* 0xae */ 13693 /* File: armv5te/alt_stub.S */ 13694 /* 13695 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13696 * any interesting requests and then jump to the real instruction 13697 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13698 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13699 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13700 * bail to the real handler if breakFlags==0. 13701 */ 13702 ldrb r3, [rSELF, #offThread_breakFlags] 13703 adrl lr, dvmAsmInstructionStart + (174 * 64) 13704 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13705 cmp r3, #0 13706 bxeq lr @ nothing to do - jump to real handler 13707 EXPORT_PC() 13708 mov r0, rPC @ arg0 13709 mov r1, rFP @ arg1 13710 mov r2, rSELF @ arg2 13711 b dvmCheckBefore @ (dPC,dFP,self) tail call 13712 13713 /* ------------------------------ */ 13714 .balign 64 13715 .L_ALT_OP_REM_DOUBLE: /* 0xaf */ 13716 /* File: armv5te/alt_stub.S */ 13717 /* 13718 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13719 * any interesting requests and then jump to the real instruction 13720 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13721 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13722 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13723 * bail to the real handler if breakFlags==0. 13724 */ 13725 ldrb r3, [rSELF, #offThread_breakFlags] 13726 adrl lr, dvmAsmInstructionStart + (175 * 64) 13727 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13728 cmp r3, #0 13729 bxeq lr @ nothing to do - jump to real handler 13730 EXPORT_PC() 13731 mov r0, rPC @ arg0 13732 mov r1, rFP @ arg1 13733 mov r2, rSELF @ arg2 13734 b dvmCheckBefore @ (dPC,dFP,self) tail call 13735 13736 /* ------------------------------ */ 13737 .balign 64 13738 .L_ALT_OP_ADD_INT_2ADDR: /* 0xb0 */ 13739 /* File: armv5te/alt_stub.S */ 13740 /* 13741 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13742 * any interesting requests and then jump to the real instruction 13743 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13744 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13745 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13746 * bail to the real handler if breakFlags==0. 13747 */ 13748 ldrb r3, [rSELF, #offThread_breakFlags] 13749 adrl lr, dvmAsmInstructionStart + (176 * 64) 13750 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13751 cmp r3, #0 13752 bxeq lr @ nothing to do - jump to real handler 13753 EXPORT_PC() 13754 mov r0, rPC @ arg0 13755 mov r1, rFP @ arg1 13756 mov r2, rSELF @ arg2 13757 b dvmCheckBefore @ (dPC,dFP,self) tail call 13758 13759 /* ------------------------------ */ 13760 .balign 64 13761 .L_ALT_OP_SUB_INT_2ADDR: /* 0xb1 */ 13762 /* File: armv5te/alt_stub.S */ 13763 /* 13764 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13765 * any interesting requests and then jump to the real instruction 13766 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13767 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13768 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13769 * bail to the real handler if breakFlags==0. 13770 */ 13771 ldrb r3, [rSELF, #offThread_breakFlags] 13772 adrl lr, dvmAsmInstructionStart + (177 * 64) 13773 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13774 cmp r3, #0 13775 bxeq lr @ nothing to do - jump to real handler 13776 EXPORT_PC() 13777 mov r0, rPC @ arg0 13778 mov r1, rFP @ arg1 13779 mov r2, rSELF @ arg2 13780 b dvmCheckBefore @ (dPC,dFP,self) tail call 13781 13782 /* ------------------------------ */ 13783 .balign 64 13784 .L_ALT_OP_MUL_INT_2ADDR: /* 0xb2 */ 13785 /* File: armv5te/alt_stub.S */ 13786 /* 13787 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13788 * any interesting requests and then jump to the real instruction 13789 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13790 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13791 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13792 * bail to the real handler if breakFlags==0. 13793 */ 13794 ldrb r3, [rSELF, #offThread_breakFlags] 13795 adrl lr, dvmAsmInstructionStart + (178 * 64) 13796 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13797 cmp r3, #0 13798 bxeq lr @ nothing to do - jump to real handler 13799 EXPORT_PC() 13800 mov r0, rPC @ arg0 13801 mov r1, rFP @ arg1 13802 mov r2, rSELF @ arg2 13803 b dvmCheckBefore @ (dPC,dFP,self) tail call 13804 13805 /* ------------------------------ */ 13806 .balign 64 13807 .L_ALT_OP_DIV_INT_2ADDR: /* 0xb3 */ 13808 /* File: armv5te/alt_stub.S */ 13809 /* 13810 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13811 * any interesting requests and then jump to the real instruction 13812 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13813 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13814 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13815 * bail to the real handler if breakFlags==0. 13816 */ 13817 ldrb r3, [rSELF, #offThread_breakFlags] 13818 adrl lr, dvmAsmInstructionStart + (179 * 64) 13819 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13820 cmp r3, #0 13821 bxeq lr @ nothing to do - jump to real handler 13822 EXPORT_PC() 13823 mov r0, rPC @ arg0 13824 mov r1, rFP @ arg1 13825 mov r2, rSELF @ arg2 13826 b dvmCheckBefore @ (dPC,dFP,self) tail call 13827 13828 /* ------------------------------ */ 13829 .balign 64 13830 .L_ALT_OP_REM_INT_2ADDR: /* 0xb4 */ 13831 /* File: armv5te/alt_stub.S */ 13832 /* 13833 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13834 * any interesting requests and then jump to the real instruction 13835 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13836 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13837 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13838 * bail to the real handler if breakFlags==0. 13839 */ 13840 ldrb r3, [rSELF, #offThread_breakFlags] 13841 adrl lr, dvmAsmInstructionStart + (180 * 64) 13842 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13843 cmp r3, #0 13844 bxeq lr @ nothing to do - jump to real handler 13845 EXPORT_PC() 13846 mov r0, rPC @ arg0 13847 mov r1, rFP @ arg1 13848 mov r2, rSELF @ arg2 13849 b dvmCheckBefore @ (dPC,dFP,self) tail call 13850 13851 /* ------------------------------ */ 13852 .balign 64 13853 .L_ALT_OP_AND_INT_2ADDR: /* 0xb5 */ 13854 /* File: armv5te/alt_stub.S */ 13855 /* 13856 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13857 * any interesting requests and then jump to the real instruction 13858 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13859 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13860 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13861 * bail to the real handler if breakFlags==0. 13862 */ 13863 ldrb r3, [rSELF, #offThread_breakFlags] 13864 adrl lr, dvmAsmInstructionStart + (181 * 64) 13865 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13866 cmp r3, #0 13867 bxeq lr @ nothing to do - jump to real handler 13868 EXPORT_PC() 13869 mov r0, rPC @ arg0 13870 mov r1, rFP @ arg1 13871 mov r2, rSELF @ arg2 13872 b dvmCheckBefore @ (dPC,dFP,self) tail call 13873 13874 /* ------------------------------ */ 13875 .balign 64 13876 .L_ALT_OP_OR_INT_2ADDR: /* 0xb6 */ 13877 /* File: armv5te/alt_stub.S */ 13878 /* 13879 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13880 * any interesting requests and then jump to the real instruction 13881 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13882 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13883 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13884 * bail to the real handler if breakFlags==0. 13885 */ 13886 ldrb r3, [rSELF, #offThread_breakFlags] 13887 adrl lr, dvmAsmInstructionStart + (182 * 64) 13888 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13889 cmp r3, #0 13890 bxeq lr @ nothing to do - jump to real handler 13891 EXPORT_PC() 13892 mov r0, rPC @ arg0 13893 mov r1, rFP @ arg1 13894 mov r2, rSELF @ arg2 13895 b dvmCheckBefore @ (dPC,dFP,self) tail call 13896 13897 /* ------------------------------ */ 13898 .balign 64 13899 .L_ALT_OP_XOR_INT_2ADDR: /* 0xb7 */ 13900 /* File: armv5te/alt_stub.S */ 13901 /* 13902 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13903 * any interesting requests and then jump to the real instruction 13904 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13905 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13906 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13907 * bail to the real handler if breakFlags==0. 13908 */ 13909 ldrb r3, [rSELF, #offThread_breakFlags] 13910 adrl lr, dvmAsmInstructionStart + (183 * 64) 13911 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13912 cmp r3, #0 13913 bxeq lr @ nothing to do - jump to real handler 13914 EXPORT_PC() 13915 mov r0, rPC @ arg0 13916 mov r1, rFP @ arg1 13917 mov r2, rSELF @ arg2 13918 b dvmCheckBefore @ (dPC,dFP,self) tail call 13919 13920 /* ------------------------------ */ 13921 .balign 64 13922 .L_ALT_OP_SHL_INT_2ADDR: /* 0xb8 */ 13923 /* File: armv5te/alt_stub.S */ 13924 /* 13925 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13926 * any interesting requests and then jump to the real instruction 13927 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13928 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13929 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13930 * bail to the real handler if breakFlags==0. 13931 */ 13932 ldrb r3, [rSELF, #offThread_breakFlags] 13933 adrl lr, dvmAsmInstructionStart + (184 * 64) 13934 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13935 cmp r3, #0 13936 bxeq lr @ nothing to do - jump to real handler 13937 EXPORT_PC() 13938 mov r0, rPC @ arg0 13939 mov r1, rFP @ arg1 13940 mov r2, rSELF @ arg2 13941 b dvmCheckBefore @ (dPC,dFP,self) tail call 13942 13943 /* ------------------------------ */ 13944 .balign 64 13945 .L_ALT_OP_SHR_INT_2ADDR: /* 0xb9 */ 13946 /* File: armv5te/alt_stub.S */ 13947 /* 13948 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13949 * any interesting requests and then jump to the real instruction 13950 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13951 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13952 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13953 * bail to the real handler if breakFlags==0. 13954 */ 13955 ldrb r3, [rSELF, #offThread_breakFlags] 13956 adrl lr, dvmAsmInstructionStart + (185 * 64) 13957 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13958 cmp r3, #0 13959 bxeq lr @ nothing to do - jump to real handler 13960 EXPORT_PC() 13961 mov r0, rPC @ arg0 13962 mov r1, rFP @ arg1 13963 mov r2, rSELF @ arg2 13964 b dvmCheckBefore @ (dPC,dFP,self) tail call 13965 13966 /* ------------------------------ */ 13967 .balign 64 13968 .L_ALT_OP_USHR_INT_2ADDR: /* 0xba */ 13969 /* File: armv5te/alt_stub.S */ 13970 /* 13971 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13972 * any interesting requests and then jump to the real instruction 13973 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13974 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13975 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13976 * bail to the real handler if breakFlags==0. 13977 */ 13978 ldrb r3, [rSELF, #offThread_breakFlags] 13979 adrl lr, dvmAsmInstructionStart + (186 * 64) 13980 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13981 cmp r3, #0 13982 bxeq lr @ nothing to do - jump to real handler 13983 EXPORT_PC() 13984 mov r0, rPC @ arg0 13985 mov r1, rFP @ arg1 13986 mov r2, rSELF @ arg2 13987 b dvmCheckBefore @ (dPC,dFP,self) tail call 13988 13989 /* ------------------------------ */ 13990 .balign 64 13991 .L_ALT_OP_ADD_LONG_2ADDR: /* 0xbb */ 13992 /* File: armv5te/alt_stub.S */ 13993 /* 13994 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13995 * any interesting requests and then jump to the real instruction 13996 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13997 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13998 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13999 * bail to the real handler if breakFlags==0. 14000 */ 14001 ldrb r3, [rSELF, #offThread_breakFlags] 14002 adrl lr, dvmAsmInstructionStart + (187 * 64) 14003 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14004 cmp r3, #0 14005 bxeq lr @ nothing to do - jump to real handler 14006 EXPORT_PC() 14007 mov r0, rPC @ arg0 14008 mov r1, rFP @ arg1 14009 mov r2, rSELF @ arg2 14010 b dvmCheckBefore @ (dPC,dFP,self) tail call 14011 14012 /* ------------------------------ */ 14013 .balign 64 14014 .L_ALT_OP_SUB_LONG_2ADDR: /* 0xbc */ 14015 /* File: armv5te/alt_stub.S */ 14016 /* 14017 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14018 * any interesting requests and then jump to the real instruction 14019 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14020 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14021 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14022 * bail to the real handler if breakFlags==0. 14023 */ 14024 ldrb r3, [rSELF, #offThread_breakFlags] 14025 adrl lr, dvmAsmInstructionStart + (188 * 64) 14026 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14027 cmp r3, #0 14028 bxeq lr @ nothing to do - jump to real handler 14029 EXPORT_PC() 14030 mov r0, rPC @ arg0 14031 mov r1, rFP @ arg1 14032 mov r2, rSELF @ arg2 14033 b dvmCheckBefore @ (dPC,dFP,self) tail call 14034 14035 /* ------------------------------ */ 14036 .balign 64 14037 .L_ALT_OP_MUL_LONG_2ADDR: /* 0xbd */ 14038 /* File: armv5te/alt_stub.S */ 14039 /* 14040 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14041 * any interesting requests and then jump to the real instruction 14042 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14043 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14044 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14045 * bail to the real handler if breakFlags==0. 14046 */ 14047 ldrb r3, [rSELF, #offThread_breakFlags] 14048 adrl lr, dvmAsmInstructionStart + (189 * 64) 14049 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14050 cmp r3, #0 14051 bxeq lr @ nothing to do - jump to real handler 14052 EXPORT_PC() 14053 mov r0, rPC @ arg0 14054 mov r1, rFP @ arg1 14055 mov r2, rSELF @ arg2 14056 b dvmCheckBefore @ (dPC,dFP,self) tail call 14057 14058 /* ------------------------------ */ 14059 .balign 64 14060 .L_ALT_OP_DIV_LONG_2ADDR: /* 0xbe */ 14061 /* File: armv5te/alt_stub.S */ 14062 /* 14063 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14064 * any interesting requests and then jump to the real instruction 14065 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14066 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14067 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14068 * bail to the real handler if breakFlags==0. 14069 */ 14070 ldrb r3, [rSELF, #offThread_breakFlags] 14071 adrl lr, dvmAsmInstructionStart + (190 * 64) 14072 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14073 cmp r3, #0 14074 bxeq lr @ nothing to do - jump to real handler 14075 EXPORT_PC() 14076 mov r0, rPC @ arg0 14077 mov r1, rFP @ arg1 14078 mov r2, rSELF @ arg2 14079 b dvmCheckBefore @ (dPC,dFP,self) tail call 14080 14081 /* ------------------------------ */ 14082 .balign 64 14083 .L_ALT_OP_REM_LONG_2ADDR: /* 0xbf */ 14084 /* File: armv5te/alt_stub.S */ 14085 /* 14086 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14087 * any interesting requests and then jump to the real instruction 14088 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14089 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14090 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14091 * bail to the real handler if breakFlags==0. 14092 */ 14093 ldrb r3, [rSELF, #offThread_breakFlags] 14094 adrl lr, dvmAsmInstructionStart + (191 * 64) 14095 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14096 cmp r3, #0 14097 bxeq lr @ nothing to do - jump to real handler 14098 EXPORT_PC() 14099 mov r0, rPC @ arg0 14100 mov r1, rFP @ arg1 14101 mov r2, rSELF @ arg2 14102 b dvmCheckBefore @ (dPC,dFP,self) tail call 14103 14104 /* ------------------------------ */ 14105 .balign 64 14106 .L_ALT_OP_AND_LONG_2ADDR: /* 0xc0 */ 14107 /* File: armv5te/alt_stub.S */ 14108 /* 14109 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14110 * any interesting requests and then jump to the real instruction 14111 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14112 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14113 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14114 * bail to the real handler if breakFlags==0. 14115 */ 14116 ldrb r3, [rSELF, #offThread_breakFlags] 14117 adrl lr, dvmAsmInstructionStart + (192 * 64) 14118 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14119 cmp r3, #0 14120 bxeq lr @ nothing to do - jump to real handler 14121 EXPORT_PC() 14122 mov r0, rPC @ arg0 14123 mov r1, rFP @ arg1 14124 mov r2, rSELF @ arg2 14125 b dvmCheckBefore @ (dPC,dFP,self) tail call 14126 14127 /* ------------------------------ */ 14128 .balign 64 14129 .L_ALT_OP_OR_LONG_2ADDR: /* 0xc1 */ 14130 /* File: armv5te/alt_stub.S */ 14131 /* 14132 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14133 * any interesting requests and then jump to the real instruction 14134 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14135 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14136 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14137 * bail to the real handler if breakFlags==0. 14138 */ 14139 ldrb r3, [rSELF, #offThread_breakFlags] 14140 adrl lr, dvmAsmInstructionStart + (193 * 64) 14141 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14142 cmp r3, #0 14143 bxeq lr @ nothing to do - jump to real handler 14144 EXPORT_PC() 14145 mov r0, rPC @ arg0 14146 mov r1, rFP @ arg1 14147 mov r2, rSELF @ arg2 14148 b dvmCheckBefore @ (dPC,dFP,self) tail call 14149 14150 /* ------------------------------ */ 14151 .balign 64 14152 .L_ALT_OP_XOR_LONG_2ADDR: /* 0xc2 */ 14153 /* File: armv5te/alt_stub.S */ 14154 /* 14155 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14156 * any interesting requests and then jump to the real instruction 14157 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14158 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14159 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14160 * bail to the real handler if breakFlags==0. 14161 */ 14162 ldrb r3, [rSELF, #offThread_breakFlags] 14163 adrl lr, dvmAsmInstructionStart + (194 * 64) 14164 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14165 cmp r3, #0 14166 bxeq lr @ nothing to do - jump to real handler 14167 EXPORT_PC() 14168 mov r0, rPC @ arg0 14169 mov r1, rFP @ arg1 14170 mov r2, rSELF @ arg2 14171 b dvmCheckBefore @ (dPC,dFP,self) tail call 14172 14173 /* ------------------------------ */ 14174 .balign 64 14175 .L_ALT_OP_SHL_LONG_2ADDR: /* 0xc3 */ 14176 /* File: armv5te/alt_stub.S */ 14177 /* 14178 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14179 * any interesting requests and then jump to the real instruction 14180 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14181 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14182 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14183 * bail to the real handler if breakFlags==0. 14184 */ 14185 ldrb r3, [rSELF, #offThread_breakFlags] 14186 adrl lr, dvmAsmInstructionStart + (195 * 64) 14187 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14188 cmp r3, #0 14189 bxeq lr @ nothing to do - jump to real handler 14190 EXPORT_PC() 14191 mov r0, rPC @ arg0 14192 mov r1, rFP @ arg1 14193 mov r2, rSELF @ arg2 14194 b dvmCheckBefore @ (dPC,dFP,self) tail call 14195 14196 /* ------------------------------ */ 14197 .balign 64 14198 .L_ALT_OP_SHR_LONG_2ADDR: /* 0xc4 */ 14199 /* File: armv5te/alt_stub.S */ 14200 /* 14201 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14202 * any interesting requests and then jump to the real instruction 14203 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14204 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14205 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14206 * bail to the real handler if breakFlags==0. 14207 */ 14208 ldrb r3, [rSELF, #offThread_breakFlags] 14209 adrl lr, dvmAsmInstructionStart + (196 * 64) 14210 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14211 cmp r3, #0 14212 bxeq lr @ nothing to do - jump to real handler 14213 EXPORT_PC() 14214 mov r0, rPC @ arg0 14215 mov r1, rFP @ arg1 14216 mov r2, rSELF @ arg2 14217 b dvmCheckBefore @ (dPC,dFP,self) tail call 14218 14219 /* ------------------------------ */ 14220 .balign 64 14221 .L_ALT_OP_USHR_LONG_2ADDR: /* 0xc5 */ 14222 /* File: armv5te/alt_stub.S */ 14223 /* 14224 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14225 * any interesting requests and then jump to the real instruction 14226 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14227 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14228 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14229 * bail to the real handler if breakFlags==0. 14230 */ 14231 ldrb r3, [rSELF, #offThread_breakFlags] 14232 adrl lr, dvmAsmInstructionStart + (197 * 64) 14233 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14234 cmp r3, #0 14235 bxeq lr @ nothing to do - jump to real handler 14236 EXPORT_PC() 14237 mov r0, rPC @ arg0 14238 mov r1, rFP @ arg1 14239 mov r2, rSELF @ arg2 14240 b dvmCheckBefore @ (dPC,dFP,self) tail call 14241 14242 /* ------------------------------ */ 14243 .balign 64 14244 .L_ALT_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 14245 /* File: armv5te/alt_stub.S */ 14246 /* 14247 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14248 * any interesting requests and then jump to the real instruction 14249 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14250 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14251 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14252 * bail to the real handler if breakFlags==0. 14253 */ 14254 ldrb r3, [rSELF, #offThread_breakFlags] 14255 adrl lr, dvmAsmInstructionStart + (198 * 64) 14256 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14257 cmp r3, #0 14258 bxeq lr @ nothing to do - jump to real handler 14259 EXPORT_PC() 14260 mov r0, rPC @ arg0 14261 mov r1, rFP @ arg1 14262 mov r2, rSELF @ arg2 14263 b dvmCheckBefore @ (dPC,dFP,self) tail call 14264 14265 /* ------------------------------ */ 14266 .balign 64 14267 .L_ALT_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 14268 /* File: armv5te/alt_stub.S */ 14269 /* 14270 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14271 * any interesting requests and then jump to the real instruction 14272 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14273 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14274 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14275 * bail to the real handler if breakFlags==0. 14276 */ 14277 ldrb r3, [rSELF, #offThread_breakFlags] 14278 adrl lr, dvmAsmInstructionStart + (199 * 64) 14279 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14280 cmp r3, #0 14281 bxeq lr @ nothing to do - jump to real handler 14282 EXPORT_PC() 14283 mov r0, rPC @ arg0 14284 mov r1, rFP @ arg1 14285 mov r2, rSELF @ arg2 14286 b dvmCheckBefore @ (dPC,dFP,self) tail call 14287 14288 /* ------------------------------ */ 14289 .balign 64 14290 .L_ALT_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 14291 /* File: armv5te/alt_stub.S */ 14292 /* 14293 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14294 * any interesting requests and then jump to the real instruction 14295 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14296 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14297 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14298 * bail to the real handler if breakFlags==0. 14299 */ 14300 ldrb r3, [rSELF, #offThread_breakFlags] 14301 adrl lr, dvmAsmInstructionStart + (200 * 64) 14302 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14303 cmp r3, #0 14304 bxeq lr @ nothing to do - jump to real handler 14305 EXPORT_PC() 14306 mov r0, rPC @ arg0 14307 mov r1, rFP @ arg1 14308 mov r2, rSELF @ arg2 14309 b dvmCheckBefore @ (dPC,dFP,self) tail call 14310 14311 /* ------------------------------ */ 14312 .balign 64 14313 .L_ALT_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 14314 /* File: armv5te/alt_stub.S */ 14315 /* 14316 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14317 * any interesting requests and then jump to the real instruction 14318 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14319 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14320 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14321 * bail to the real handler if breakFlags==0. 14322 */ 14323 ldrb r3, [rSELF, #offThread_breakFlags] 14324 adrl lr, dvmAsmInstructionStart + (201 * 64) 14325 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14326 cmp r3, #0 14327 bxeq lr @ nothing to do - jump to real handler 14328 EXPORT_PC() 14329 mov r0, rPC @ arg0 14330 mov r1, rFP @ arg1 14331 mov r2, rSELF @ arg2 14332 b dvmCheckBefore @ (dPC,dFP,self) tail call 14333 14334 /* ------------------------------ */ 14335 .balign 64 14336 .L_ALT_OP_REM_FLOAT_2ADDR: /* 0xca */ 14337 /* File: armv5te/alt_stub.S */ 14338 /* 14339 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14340 * any interesting requests and then jump to the real instruction 14341 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14342 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14343 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14344 * bail to the real handler if breakFlags==0. 14345 */ 14346 ldrb r3, [rSELF, #offThread_breakFlags] 14347 adrl lr, dvmAsmInstructionStart + (202 * 64) 14348 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14349 cmp r3, #0 14350 bxeq lr @ nothing to do - jump to real handler 14351 EXPORT_PC() 14352 mov r0, rPC @ arg0 14353 mov r1, rFP @ arg1 14354 mov r2, rSELF @ arg2 14355 b dvmCheckBefore @ (dPC,dFP,self) tail call 14356 14357 /* ------------------------------ */ 14358 .balign 64 14359 .L_ALT_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 14360 /* File: armv5te/alt_stub.S */ 14361 /* 14362 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14363 * any interesting requests and then jump to the real instruction 14364 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14365 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14366 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14367 * bail to the real handler if breakFlags==0. 14368 */ 14369 ldrb r3, [rSELF, #offThread_breakFlags] 14370 adrl lr, dvmAsmInstructionStart + (203 * 64) 14371 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14372 cmp r3, #0 14373 bxeq lr @ nothing to do - jump to real handler 14374 EXPORT_PC() 14375 mov r0, rPC @ arg0 14376 mov r1, rFP @ arg1 14377 mov r2, rSELF @ arg2 14378 b dvmCheckBefore @ (dPC,dFP,self) tail call 14379 14380 /* ------------------------------ */ 14381 .balign 64 14382 .L_ALT_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 14383 /* File: armv5te/alt_stub.S */ 14384 /* 14385 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14386 * any interesting requests and then jump to the real instruction 14387 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14388 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14389 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14390 * bail to the real handler if breakFlags==0. 14391 */ 14392 ldrb r3, [rSELF, #offThread_breakFlags] 14393 adrl lr, dvmAsmInstructionStart + (204 * 64) 14394 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14395 cmp r3, #0 14396 bxeq lr @ nothing to do - jump to real handler 14397 EXPORT_PC() 14398 mov r0, rPC @ arg0 14399 mov r1, rFP @ arg1 14400 mov r2, rSELF @ arg2 14401 b dvmCheckBefore @ (dPC,dFP,self) tail call 14402 14403 /* ------------------------------ */ 14404 .balign 64 14405 .L_ALT_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 14406 /* File: armv5te/alt_stub.S */ 14407 /* 14408 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14409 * any interesting requests and then jump to the real instruction 14410 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14411 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14412 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14413 * bail to the real handler if breakFlags==0. 14414 */ 14415 ldrb r3, [rSELF, #offThread_breakFlags] 14416 adrl lr, dvmAsmInstructionStart + (205 * 64) 14417 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14418 cmp r3, #0 14419 bxeq lr @ nothing to do - jump to real handler 14420 EXPORT_PC() 14421 mov r0, rPC @ arg0 14422 mov r1, rFP @ arg1 14423 mov r2, rSELF @ arg2 14424 b dvmCheckBefore @ (dPC,dFP,self) tail call 14425 14426 /* ------------------------------ */ 14427 .balign 64 14428 .L_ALT_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 14429 /* File: armv5te/alt_stub.S */ 14430 /* 14431 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14432 * any interesting requests and then jump to the real instruction 14433 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14434 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14435 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14436 * bail to the real handler if breakFlags==0. 14437 */ 14438 ldrb r3, [rSELF, #offThread_breakFlags] 14439 adrl lr, dvmAsmInstructionStart + (206 * 64) 14440 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14441 cmp r3, #0 14442 bxeq lr @ nothing to do - jump to real handler 14443 EXPORT_PC() 14444 mov r0, rPC @ arg0 14445 mov r1, rFP @ arg1 14446 mov r2, rSELF @ arg2 14447 b dvmCheckBefore @ (dPC,dFP,self) tail call 14448 14449 /* ------------------------------ */ 14450 .balign 64 14451 .L_ALT_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 14452 /* File: armv5te/alt_stub.S */ 14453 /* 14454 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14455 * any interesting requests and then jump to the real instruction 14456 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14457 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14458 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14459 * bail to the real handler if breakFlags==0. 14460 */ 14461 ldrb r3, [rSELF, #offThread_breakFlags] 14462 adrl lr, dvmAsmInstructionStart + (207 * 64) 14463 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14464 cmp r3, #0 14465 bxeq lr @ nothing to do - jump to real handler 14466 EXPORT_PC() 14467 mov r0, rPC @ arg0 14468 mov r1, rFP @ arg1 14469 mov r2, rSELF @ arg2 14470 b dvmCheckBefore @ (dPC,dFP,self) tail call 14471 14472 /* ------------------------------ */ 14473 .balign 64 14474 .L_ALT_OP_ADD_INT_LIT16: /* 0xd0 */ 14475 /* File: armv5te/alt_stub.S */ 14476 /* 14477 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14478 * any interesting requests and then jump to the real instruction 14479 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14480 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14481 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14482 * bail to the real handler if breakFlags==0. 14483 */ 14484 ldrb r3, [rSELF, #offThread_breakFlags] 14485 adrl lr, dvmAsmInstructionStart + (208 * 64) 14486 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14487 cmp r3, #0 14488 bxeq lr @ nothing to do - jump to real handler 14489 EXPORT_PC() 14490 mov r0, rPC @ arg0 14491 mov r1, rFP @ arg1 14492 mov r2, rSELF @ arg2 14493 b dvmCheckBefore @ (dPC,dFP,self) tail call 14494 14495 /* ------------------------------ */ 14496 .balign 64 14497 .L_ALT_OP_RSUB_INT: /* 0xd1 */ 14498 /* File: armv5te/alt_stub.S */ 14499 /* 14500 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14501 * any interesting requests and then jump to the real instruction 14502 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14503 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14504 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14505 * bail to the real handler if breakFlags==0. 14506 */ 14507 ldrb r3, [rSELF, #offThread_breakFlags] 14508 adrl lr, dvmAsmInstructionStart + (209 * 64) 14509 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14510 cmp r3, #0 14511 bxeq lr @ nothing to do - jump to real handler 14512 EXPORT_PC() 14513 mov r0, rPC @ arg0 14514 mov r1, rFP @ arg1 14515 mov r2, rSELF @ arg2 14516 b dvmCheckBefore @ (dPC,dFP,self) tail call 14517 14518 /* ------------------------------ */ 14519 .balign 64 14520 .L_ALT_OP_MUL_INT_LIT16: /* 0xd2 */ 14521 /* File: armv5te/alt_stub.S */ 14522 /* 14523 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14524 * any interesting requests and then jump to the real instruction 14525 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14526 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14527 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14528 * bail to the real handler if breakFlags==0. 14529 */ 14530 ldrb r3, [rSELF, #offThread_breakFlags] 14531 adrl lr, dvmAsmInstructionStart + (210 * 64) 14532 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14533 cmp r3, #0 14534 bxeq lr @ nothing to do - jump to real handler 14535 EXPORT_PC() 14536 mov r0, rPC @ arg0 14537 mov r1, rFP @ arg1 14538 mov r2, rSELF @ arg2 14539 b dvmCheckBefore @ (dPC,dFP,self) tail call 14540 14541 /* ------------------------------ */ 14542 .balign 64 14543 .L_ALT_OP_DIV_INT_LIT16: /* 0xd3 */ 14544 /* File: armv5te/alt_stub.S */ 14545 /* 14546 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14547 * any interesting requests and then jump to the real instruction 14548 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14549 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14550 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14551 * bail to the real handler if breakFlags==0. 14552 */ 14553 ldrb r3, [rSELF, #offThread_breakFlags] 14554 adrl lr, dvmAsmInstructionStart + (211 * 64) 14555 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14556 cmp r3, #0 14557 bxeq lr @ nothing to do - jump to real handler 14558 EXPORT_PC() 14559 mov r0, rPC @ arg0 14560 mov r1, rFP @ arg1 14561 mov r2, rSELF @ arg2 14562 b dvmCheckBefore @ (dPC,dFP,self) tail call 14563 14564 /* ------------------------------ */ 14565 .balign 64 14566 .L_ALT_OP_REM_INT_LIT16: /* 0xd4 */ 14567 /* File: armv5te/alt_stub.S */ 14568 /* 14569 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14570 * any interesting requests and then jump to the real instruction 14571 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14572 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14573 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14574 * bail to the real handler if breakFlags==0. 14575 */ 14576 ldrb r3, [rSELF, #offThread_breakFlags] 14577 adrl lr, dvmAsmInstructionStart + (212 * 64) 14578 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14579 cmp r3, #0 14580 bxeq lr @ nothing to do - jump to real handler 14581 EXPORT_PC() 14582 mov r0, rPC @ arg0 14583 mov r1, rFP @ arg1 14584 mov r2, rSELF @ arg2 14585 b dvmCheckBefore @ (dPC,dFP,self) tail call 14586 14587 /* ------------------------------ */ 14588 .balign 64 14589 .L_ALT_OP_AND_INT_LIT16: /* 0xd5 */ 14590 /* File: armv5te/alt_stub.S */ 14591 /* 14592 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14593 * any interesting requests and then jump to the real instruction 14594 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14595 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14596 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14597 * bail to the real handler if breakFlags==0. 14598 */ 14599 ldrb r3, [rSELF, #offThread_breakFlags] 14600 adrl lr, dvmAsmInstructionStart + (213 * 64) 14601 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14602 cmp r3, #0 14603 bxeq lr @ nothing to do - jump to real handler 14604 EXPORT_PC() 14605 mov r0, rPC @ arg0 14606 mov r1, rFP @ arg1 14607 mov r2, rSELF @ arg2 14608 b dvmCheckBefore @ (dPC,dFP,self) tail call 14609 14610 /* ------------------------------ */ 14611 .balign 64 14612 .L_ALT_OP_OR_INT_LIT16: /* 0xd6 */ 14613 /* File: armv5te/alt_stub.S */ 14614 /* 14615 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14616 * any interesting requests and then jump to the real instruction 14617 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14618 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14619 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14620 * bail to the real handler if breakFlags==0. 14621 */ 14622 ldrb r3, [rSELF, #offThread_breakFlags] 14623 adrl lr, dvmAsmInstructionStart + (214 * 64) 14624 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14625 cmp r3, #0 14626 bxeq lr @ nothing to do - jump to real handler 14627 EXPORT_PC() 14628 mov r0, rPC @ arg0 14629 mov r1, rFP @ arg1 14630 mov r2, rSELF @ arg2 14631 b dvmCheckBefore @ (dPC,dFP,self) tail call 14632 14633 /* ------------------------------ */ 14634 .balign 64 14635 .L_ALT_OP_XOR_INT_LIT16: /* 0xd7 */ 14636 /* File: armv5te/alt_stub.S */ 14637 /* 14638 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14639 * any interesting requests and then jump to the real instruction 14640 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14641 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14642 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14643 * bail to the real handler if breakFlags==0. 14644 */ 14645 ldrb r3, [rSELF, #offThread_breakFlags] 14646 adrl lr, dvmAsmInstructionStart + (215 * 64) 14647 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14648 cmp r3, #0 14649 bxeq lr @ nothing to do - jump to real handler 14650 EXPORT_PC() 14651 mov r0, rPC @ arg0 14652 mov r1, rFP @ arg1 14653 mov r2, rSELF @ arg2 14654 b dvmCheckBefore @ (dPC,dFP,self) tail call 14655 14656 /* ------------------------------ */ 14657 .balign 64 14658 .L_ALT_OP_ADD_INT_LIT8: /* 0xd8 */ 14659 /* File: armv5te/alt_stub.S */ 14660 /* 14661 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14662 * any interesting requests and then jump to the real instruction 14663 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14664 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14665 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14666 * bail to the real handler if breakFlags==0. 14667 */ 14668 ldrb r3, [rSELF, #offThread_breakFlags] 14669 adrl lr, dvmAsmInstructionStart + (216 * 64) 14670 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14671 cmp r3, #0 14672 bxeq lr @ nothing to do - jump to real handler 14673 EXPORT_PC() 14674 mov r0, rPC @ arg0 14675 mov r1, rFP @ arg1 14676 mov r2, rSELF @ arg2 14677 b dvmCheckBefore @ (dPC,dFP,self) tail call 14678 14679 /* ------------------------------ */ 14680 .balign 64 14681 .L_ALT_OP_RSUB_INT_LIT8: /* 0xd9 */ 14682 /* File: armv5te/alt_stub.S */ 14683 /* 14684 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14685 * any interesting requests and then jump to the real instruction 14686 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14687 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14688 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14689 * bail to the real handler if breakFlags==0. 14690 */ 14691 ldrb r3, [rSELF, #offThread_breakFlags] 14692 adrl lr, dvmAsmInstructionStart + (217 * 64) 14693 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14694 cmp r3, #0 14695 bxeq lr @ nothing to do - jump to real handler 14696 EXPORT_PC() 14697 mov r0, rPC @ arg0 14698 mov r1, rFP @ arg1 14699 mov r2, rSELF @ arg2 14700 b dvmCheckBefore @ (dPC,dFP,self) tail call 14701 14702 /* ------------------------------ */ 14703 .balign 64 14704 .L_ALT_OP_MUL_INT_LIT8: /* 0xda */ 14705 /* File: armv5te/alt_stub.S */ 14706 /* 14707 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14708 * any interesting requests and then jump to the real instruction 14709 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14710 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14711 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14712 * bail to the real handler if breakFlags==0. 14713 */ 14714 ldrb r3, [rSELF, #offThread_breakFlags] 14715 adrl lr, dvmAsmInstructionStart + (218 * 64) 14716 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14717 cmp r3, #0 14718 bxeq lr @ nothing to do - jump to real handler 14719 EXPORT_PC() 14720 mov r0, rPC @ arg0 14721 mov r1, rFP @ arg1 14722 mov r2, rSELF @ arg2 14723 b dvmCheckBefore @ (dPC,dFP,self) tail call 14724 14725 /* ------------------------------ */ 14726 .balign 64 14727 .L_ALT_OP_DIV_INT_LIT8: /* 0xdb */ 14728 /* File: armv5te/alt_stub.S */ 14729 /* 14730 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14731 * any interesting requests and then jump to the real instruction 14732 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14733 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14734 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14735 * bail to the real handler if breakFlags==0. 14736 */ 14737 ldrb r3, [rSELF, #offThread_breakFlags] 14738 adrl lr, dvmAsmInstructionStart + (219 * 64) 14739 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14740 cmp r3, #0 14741 bxeq lr @ nothing to do - jump to real handler 14742 EXPORT_PC() 14743 mov r0, rPC @ arg0 14744 mov r1, rFP @ arg1 14745 mov r2, rSELF @ arg2 14746 b dvmCheckBefore @ (dPC,dFP,self) tail call 14747 14748 /* ------------------------------ */ 14749 .balign 64 14750 .L_ALT_OP_REM_INT_LIT8: /* 0xdc */ 14751 /* File: armv5te/alt_stub.S */ 14752 /* 14753 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14754 * any interesting requests and then jump to the real instruction 14755 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14756 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14757 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14758 * bail to the real handler if breakFlags==0. 14759 */ 14760 ldrb r3, [rSELF, #offThread_breakFlags] 14761 adrl lr, dvmAsmInstructionStart + (220 * 64) 14762 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14763 cmp r3, #0 14764 bxeq lr @ nothing to do - jump to real handler 14765 EXPORT_PC() 14766 mov r0, rPC @ arg0 14767 mov r1, rFP @ arg1 14768 mov r2, rSELF @ arg2 14769 b dvmCheckBefore @ (dPC,dFP,self) tail call 14770 14771 /* ------------------------------ */ 14772 .balign 64 14773 .L_ALT_OP_AND_INT_LIT8: /* 0xdd */ 14774 /* File: armv5te/alt_stub.S */ 14775 /* 14776 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14777 * any interesting requests and then jump to the real instruction 14778 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14779 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14780 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14781 * bail to the real handler if breakFlags==0. 14782 */ 14783 ldrb r3, [rSELF, #offThread_breakFlags] 14784 adrl lr, dvmAsmInstructionStart + (221 * 64) 14785 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14786 cmp r3, #0 14787 bxeq lr @ nothing to do - jump to real handler 14788 EXPORT_PC() 14789 mov r0, rPC @ arg0 14790 mov r1, rFP @ arg1 14791 mov r2, rSELF @ arg2 14792 b dvmCheckBefore @ (dPC,dFP,self) tail call 14793 14794 /* ------------------------------ */ 14795 .balign 64 14796 .L_ALT_OP_OR_INT_LIT8: /* 0xde */ 14797 /* File: armv5te/alt_stub.S */ 14798 /* 14799 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14800 * any interesting requests and then jump to the real instruction 14801 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14802 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14803 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14804 * bail to the real handler if breakFlags==0. 14805 */ 14806 ldrb r3, [rSELF, #offThread_breakFlags] 14807 adrl lr, dvmAsmInstructionStart + (222 * 64) 14808 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14809 cmp r3, #0 14810 bxeq lr @ nothing to do - jump to real handler 14811 EXPORT_PC() 14812 mov r0, rPC @ arg0 14813 mov r1, rFP @ arg1 14814 mov r2, rSELF @ arg2 14815 b dvmCheckBefore @ (dPC,dFP,self) tail call 14816 14817 /* ------------------------------ */ 14818 .balign 64 14819 .L_ALT_OP_XOR_INT_LIT8: /* 0xdf */ 14820 /* File: armv5te/alt_stub.S */ 14821 /* 14822 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14823 * any interesting requests and then jump to the real instruction 14824 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14825 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14826 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14827 * bail to the real handler if breakFlags==0. 14828 */ 14829 ldrb r3, [rSELF, #offThread_breakFlags] 14830 adrl lr, dvmAsmInstructionStart + (223 * 64) 14831 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14832 cmp r3, #0 14833 bxeq lr @ nothing to do - jump to real handler 14834 EXPORT_PC() 14835 mov r0, rPC @ arg0 14836 mov r1, rFP @ arg1 14837 mov r2, rSELF @ arg2 14838 b dvmCheckBefore @ (dPC,dFP,self) tail call 14839 14840 /* ------------------------------ */ 14841 .balign 64 14842 .L_ALT_OP_SHL_INT_LIT8: /* 0xe0 */ 14843 /* File: armv5te/alt_stub.S */ 14844 /* 14845 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14846 * any interesting requests and then jump to the real instruction 14847 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14848 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14849 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14850 * bail to the real handler if breakFlags==0. 14851 */ 14852 ldrb r3, [rSELF, #offThread_breakFlags] 14853 adrl lr, dvmAsmInstructionStart + (224 * 64) 14854 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14855 cmp r3, #0 14856 bxeq lr @ nothing to do - jump to real handler 14857 EXPORT_PC() 14858 mov r0, rPC @ arg0 14859 mov r1, rFP @ arg1 14860 mov r2, rSELF @ arg2 14861 b dvmCheckBefore @ (dPC,dFP,self) tail call 14862 14863 /* ------------------------------ */ 14864 .balign 64 14865 .L_ALT_OP_SHR_INT_LIT8: /* 0xe1 */ 14866 /* File: armv5te/alt_stub.S */ 14867 /* 14868 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14869 * any interesting requests and then jump to the real instruction 14870 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14871 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14872 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14873 * bail to the real handler if breakFlags==0. 14874 */ 14875 ldrb r3, [rSELF, #offThread_breakFlags] 14876 adrl lr, dvmAsmInstructionStart + (225 * 64) 14877 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14878 cmp r3, #0 14879 bxeq lr @ nothing to do - jump to real handler 14880 EXPORT_PC() 14881 mov r0, rPC @ arg0 14882 mov r1, rFP @ arg1 14883 mov r2, rSELF @ arg2 14884 b dvmCheckBefore @ (dPC,dFP,self) tail call 14885 14886 /* ------------------------------ */ 14887 .balign 64 14888 .L_ALT_OP_USHR_INT_LIT8: /* 0xe2 */ 14889 /* File: armv5te/alt_stub.S */ 14890 /* 14891 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14892 * any interesting requests and then jump to the real instruction 14893 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14894 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14895 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14896 * bail to the real handler if breakFlags==0. 14897 */ 14898 ldrb r3, [rSELF, #offThread_breakFlags] 14899 adrl lr, dvmAsmInstructionStart + (226 * 64) 14900 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14901 cmp r3, #0 14902 bxeq lr @ nothing to do - jump to real handler 14903 EXPORT_PC() 14904 mov r0, rPC @ arg0 14905 mov r1, rFP @ arg1 14906 mov r2, rSELF @ arg2 14907 b dvmCheckBefore @ (dPC,dFP,self) tail call 14908 14909 /* ------------------------------ */ 14910 .balign 64 14911 .L_ALT_OP_IGET_VOLATILE: /* 0xe3 */ 14912 /* File: armv5te/alt_stub.S */ 14913 /* 14914 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14915 * any interesting requests and then jump to the real instruction 14916 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14917 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14918 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14919 * bail to the real handler if breakFlags==0. 14920 */ 14921 ldrb r3, [rSELF, #offThread_breakFlags] 14922 adrl lr, dvmAsmInstructionStart + (227 * 64) 14923 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14924 cmp r3, #0 14925 bxeq lr @ nothing to do - jump to real handler 14926 EXPORT_PC() 14927 mov r0, rPC @ arg0 14928 mov r1, rFP @ arg1 14929 mov r2, rSELF @ arg2 14930 b dvmCheckBefore @ (dPC,dFP,self) tail call 14931 14932 /* ------------------------------ */ 14933 .balign 64 14934 .L_ALT_OP_IPUT_VOLATILE: /* 0xe4 */ 14935 /* File: armv5te/alt_stub.S */ 14936 /* 14937 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14938 * any interesting requests and then jump to the real instruction 14939 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14940 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14941 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14942 * bail to the real handler if breakFlags==0. 14943 */ 14944 ldrb r3, [rSELF, #offThread_breakFlags] 14945 adrl lr, dvmAsmInstructionStart + (228 * 64) 14946 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14947 cmp r3, #0 14948 bxeq lr @ nothing to do - jump to real handler 14949 EXPORT_PC() 14950 mov r0, rPC @ arg0 14951 mov r1, rFP @ arg1 14952 mov r2, rSELF @ arg2 14953 b dvmCheckBefore @ (dPC,dFP,self) tail call 14954 14955 /* ------------------------------ */ 14956 .balign 64 14957 .L_ALT_OP_SGET_VOLATILE: /* 0xe5 */ 14958 /* File: armv5te/alt_stub.S */ 14959 /* 14960 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14961 * any interesting requests and then jump to the real instruction 14962 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14963 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14964 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14965 * bail to the real handler if breakFlags==0. 14966 */ 14967 ldrb r3, [rSELF, #offThread_breakFlags] 14968 adrl lr, dvmAsmInstructionStart + (229 * 64) 14969 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14970 cmp r3, #0 14971 bxeq lr @ nothing to do - jump to real handler 14972 EXPORT_PC() 14973 mov r0, rPC @ arg0 14974 mov r1, rFP @ arg1 14975 mov r2, rSELF @ arg2 14976 b dvmCheckBefore @ (dPC,dFP,self) tail call 14977 14978 /* ------------------------------ */ 14979 .balign 64 14980 .L_ALT_OP_SPUT_VOLATILE: /* 0xe6 */ 14981 /* File: armv5te/alt_stub.S */ 14982 /* 14983 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14984 * any interesting requests and then jump to the real instruction 14985 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14986 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14987 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14988 * bail to the real handler if breakFlags==0. 14989 */ 14990 ldrb r3, [rSELF, #offThread_breakFlags] 14991 adrl lr, dvmAsmInstructionStart + (230 * 64) 14992 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14993 cmp r3, #0 14994 bxeq lr @ nothing to do - jump to real handler 14995 EXPORT_PC() 14996 mov r0, rPC @ arg0 14997 mov r1, rFP @ arg1 14998 mov r2, rSELF @ arg2 14999 b dvmCheckBefore @ (dPC,dFP,self) tail call 15000 15001 /* ------------------------------ */ 15002 .balign 64 15003 .L_ALT_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 15004 /* File: armv5te/alt_stub.S */ 15005 /* 15006 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15007 * any interesting requests and then jump to the real instruction 15008 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15009 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15010 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15011 * bail to the real handler if breakFlags==0. 15012 */ 15013 ldrb r3, [rSELF, #offThread_breakFlags] 15014 adrl lr, dvmAsmInstructionStart + (231 * 64) 15015 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15016 cmp r3, #0 15017 bxeq lr @ nothing to do - jump to real handler 15018 EXPORT_PC() 15019 mov r0, rPC @ arg0 15020 mov r1, rFP @ arg1 15021 mov r2, rSELF @ arg2 15022 b dvmCheckBefore @ (dPC,dFP,self) tail call 15023 15024 /* ------------------------------ */ 15025 .balign 64 15026 .L_ALT_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 15027 /* File: armv5te/alt_stub.S */ 15028 /* 15029 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15030 * any interesting requests and then jump to the real instruction 15031 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15032 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15033 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15034 * bail to the real handler if breakFlags==0. 15035 */ 15036 ldrb r3, [rSELF, #offThread_breakFlags] 15037 adrl lr, dvmAsmInstructionStart + (232 * 64) 15038 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15039 cmp r3, #0 15040 bxeq lr @ nothing to do - jump to real handler 15041 EXPORT_PC() 15042 mov r0, rPC @ arg0 15043 mov r1, rFP @ arg1 15044 mov r2, rSELF @ arg2 15045 b dvmCheckBefore @ (dPC,dFP,self) tail call 15046 15047 /* ------------------------------ */ 15048 .balign 64 15049 .L_ALT_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 15050 /* File: armv5te/alt_stub.S */ 15051 /* 15052 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15053 * any interesting requests and then jump to the real instruction 15054 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15055 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15056 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15057 * bail to the real handler if breakFlags==0. 15058 */ 15059 ldrb r3, [rSELF, #offThread_breakFlags] 15060 adrl lr, dvmAsmInstructionStart + (233 * 64) 15061 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15062 cmp r3, #0 15063 bxeq lr @ nothing to do - jump to real handler 15064 EXPORT_PC() 15065 mov r0, rPC @ arg0 15066 mov r1, rFP @ arg1 15067 mov r2, rSELF @ arg2 15068 b dvmCheckBefore @ (dPC,dFP,self) tail call 15069 15070 /* ------------------------------ */ 15071 .balign 64 15072 .L_ALT_OP_SGET_WIDE_VOLATILE: /* 0xea */ 15073 /* File: armv5te/alt_stub.S */ 15074 /* 15075 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15076 * any interesting requests and then jump to the real instruction 15077 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15078 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15079 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15080 * bail to the real handler if breakFlags==0. 15081 */ 15082 ldrb r3, [rSELF, #offThread_breakFlags] 15083 adrl lr, dvmAsmInstructionStart + (234 * 64) 15084 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15085 cmp r3, #0 15086 bxeq lr @ nothing to do - jump to real handler 15087 EXPORT_PC() 15088 mov r0, rPC @ arg0 15089 mov r1, rFP @ arg1 15090 mov r2, rSELF @ arg2 15091 b dvmCheckBefore @ (dPC,dFP,self) tail call 15092 15093 /* ------------------------------ */ 15094 .balign 64 15095 .L_ALT_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 15096 /* File: armv5te/alt_stub.S */ 15097 /* 15098 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15099 * any interesting requests and then jump to the real instruction 15100 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15101 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15102 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15103 * bail to the real handler if breakFlags==0. 15104 */ 15105 ldrb r3, [rSELF, #offThread_breakFlags] 15106 adrl lr, dvmAsmInstructionStart + (235 * 64) 15107 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15108 cmp r3, #0 15109 bxeq lr @ nothing to do - jump to real handler 15110 EXPORT_PC() 15111 mov r0, rPC @ arg0 15112 mov r1, rFP @ arg1 15113 mov r2, rSELF @ arg2 15114 b dvmCheckBefore @ (dPC,dFP,self) tail call 15115 15116 /* ------------------------------ */ 15117 .balign 64 15118 .L_ALT_OP_BREAKPOINT: /* 0xec */ 15119 /* File: armv5te/alt_stub.S */ 15120 /* 15121 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15122 * any interesting requests and then jump to the real instruction 15123 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15124 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15125 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15126 * bail to the real handler if breakFlags==0. 15127 */ 15128 ldrb r3, [rSELF, #offThread_breakFlags] 15129 adrl lr, dvmAsmInstructionStart + (236 * 64) 15130 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15131 cmp r3, #0 15132 bxeq lr @ nothing to do - jump to real handler 15133 EXPORT_PC() 15134 mov r0, rPC @ arg0 15135 mov r1, rFP @ arg1 15136 mov r2, rSELF @ arg2 15137 b dvmCheckBefore @ (dPC,dFP,self) tail call 15138 15139 /* ------------------------------ */ 15140 .balign 64 15141 .L_ALT_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 15142 /* File: armv5te/alt_stub.S */ 15143 /* 15144 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15145 * any interesting requests and then jump to the real instruction 15146 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15147 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15148 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15149 * bail to the real handler if breakFlags==0. 15150 */ 15151 ldrb r3, [rSELF, #offThread_breakFlags] 15152 adrl lr, dvmAsmInstructionStart + (237 * 64) 15153 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15154 cmp r3, #0 15155 bxeq lr @ nothing to do - jump to real handler 15156 EXPORT_PC() 15157 mov r0, rPC @ arg0 15158 mov r1, rFP @ arg1 15159 mov r2, rSELF @ arg2 15160 b dvmCheckBefore @ (dPC,dFP,self) tail call 15161 15162 /* ------------------------------ */ 15163 .balign 64 15164 .L_ALT_OP_EXECUTE_INLINE: /* 0xee */ 15165 /* File: armv5te/alt_stub.S */ 15166 /* 15167 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15168 * any interesting requests and then jump to the real instruction 15169 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15170 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15171 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15172 * bail to the real handler if breakFlags==0. 15173 */ 15174 ldrb r3, [rSELF, #offThread_breakFlags] 15175 adrl lr, dvmAsmInstructionStart + (238 * 64) 15176 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15177 cmp r3, #0 15178 bxeq lr @ nothing to do - jump to real handler 15179 EXPORT_PC() 15180 mov r0, rPC @ arg0 15181 mov r1, rFP @ arg1 15182 mov r2, rSELF @ arg2 15183 b dvmCheckBefore @ (dPC,dFP,self) tail call 15184 15185 /* ------------------------------ */ 15186 .balign 64 15187 .L_ALT_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 15188 /* File: armv5te/alt_stub.S */ 15189 /* 15190 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15191 * any interesting requests and then jump to the real instruction 15192 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15193 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15194 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15195 * bail to the real handler if breakFlags==0. 15196 */ 15197 ldrb r3, [rSELF, #offThread_breakFlags] 15198 adrl lr, dvmAsmInstructionStart + (239 * 64) 15199 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15200 cmp r3, #0 15201 bxeq lr @ nothing to do - jump to real handler 15202 EXPORT_PC() 15203 mov r0, rPC @ arg0 15204 mov r1, rFP @ arg1 15205 mov r2, rSELF @ arg2 15206 b dvmCheckBefore @ (dPC,dFP,self) tail call 15207 15208 /* ------------------------------ */ 15209 .balign 64 15210 .L_ALT_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */ 15211 /* File: armv5te/alt_stub.S */ 15212 /* 15213 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15214 * any interesting requests and then jump to the real instruction 15215 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15216 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15217 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15218 * bail to the real handler if breakFlags==0. 15219 */ 15220 ldrb r3, [rSELF, #offThread_breakFlags] 15221 adrl lr, dvmAsmInstructionStart + (240 * 64) 15222 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15223 cmp r3, #0 15224 bxeq lr @ nothing to do - jump to real handler 15225 EXPORT_PC() 15226 mov r0, rPC @ arg0 15227 mov r1, rFP @ arg1 15228 mov r2, rSELF @ arg2 15229 b dvmCheckBefore @ (dPC,dFP,self) tail call 15230 15231 /* ------------------------------ */ 15232 .balign 64 15233 .L_ALT_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 15234 /* File: armv5te/alt_stub.S */ 15235 /* 15236 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15237 * any interesting requests and then jump to the real instruction 15238 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15239 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15240 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15241 * bail to the real handler if breakFlags==0. 15242 */ 15243 ldrb r3, [rSELF, #offThread_breakFlags] 15244 adrl lr, dvmAsmInstructionStart + (241 * 64) 15245 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15246 cmp r3, #0 15247 bxeq lr @ nothing to do - jump to real handler 15248 EXPORT_PC() 15249 mov r0, rPC @ arg0 15250 mov r1, rFP @ arg1 15251 mov r2, rSELF @ arg2 15252 b dvmCheckBefore @ (dPC,dFP,self) tail call 15253 15254 /* ------------------------------ */ 15255 .balign 64 15256 .L_ALT_OP_IGET_QUICK: /* 0xf2 */ 15257 /* File: armv5te/alt_stub.S */ 15258 /* 15259 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15260 * any interesting requests and then jump to the real instruction 15261 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15262 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15263 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15264 * bail to the real handler if breakFlags==0. 15265 */ 15266 ldrb r3, [rSELF, #offThread_breakFlags] 15267 adrl lr, dvmAsmInstructionStart + (242 * 64) 15268 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15269 cmp r3, #0 15270 bxeq lr @ nothing to do - jump to real handler 15271 EXPORT_PC() 15272 mov r0, rPC @ arg0 15273 mov r1, rFP @ arg1 15274 mov r2, rSELF @ arg2 15275 b dvmCheckBefore @ (dPC,dFP,self) tail call 15276 15277 /* ------------------------------ */ 15278 .balign 64 15279 .L_ALT_OP_IGET_WIDE_QUICK: /* 0xf3 */ 15280 /* File: armv5te/alt_stub.S */ 15281 /* 15282 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15283 * any interesting requests and then jump to the real instruction 15284 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15285 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15286 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15287 * bail to the real handler if breakFlags==0. 15288 */ 15289 ldrb r3, [rSELF, #offThread_breakFlags] 15290 adrl lr, dvmAsmInstructionStart + (243 * 64) 15291 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15292 cmp r3, #0 15293 bxeq lr @ nothing to do - jump to real handler 15294 EXPORT_PC() 15295 mov r0, rPC @ arg0 15296 mov r1, rFP @ arg1 15297 mov r2, rSELF @ arg2 15298 b dvmCheckBefore @ (dPC,dFP,self) tail call 15299 15300 /* ------------------------------ */ 15301 .balign 64 15302 .L_ALT_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 15303 /* File: armv5te/alt_stub.S */ 15304 /* 15305 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15306 * any interesting requests and then jump to the real instruction 15307 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15308 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15309 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15310 * bail to the real handler if breakFlags==0. 15311 */ 15312 ldrb r3, [rSELF, #offThread_breakFlags] 15313 adrl lr, dvmAsmInstructionStart + (244 * 64) 15314 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15315 cmp r3, #0 15316 bxeq lr @ nothing to do - jump to real handler 15317 EXPORT_PC() 15318 mov r0, rPC @ arg0 15319 mov r1, rFP @ arg1 15320 mov r2, rSELF @ arg2 15321 b dvmCheckBefore @ (dPC,dFP,self) tail call 15322 15323 /* ------------------------------ */ 15324 .balign 64 15325 .L_ALT_OP_IPUT_QUICK: /* 0xf5 */ 15326 /* File: armv5te/alt_stub.S */ 15327 /* 15328 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15329 * any interesting requests and then jump to the real instruction 15330 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15331 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15332 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15333 * bail to the real handler if breakFlags==0. 15334 */ 15335 ldrb r3, [rSELF, #offThread_breakFlags] 15336 adrl lr, dvmAsmInstructionStart + (245 * 64) 15337 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15338 cmp r3, #0 15339 bxeq lr @ nothing to do - jump to real handler 15340 EXPORT_PC() 15341 mov r0, rPC @ arg0 15342 mov r1, rFP @ arg1 15343 mov r2, rSELF @ arg2 15344 b dvmCheckBefore @ (dPC,dFP,self) tail call 15345 15346 /* ------------------------------ */ 15347 .balign 64 15348 .L_ALT_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 15349 /* File: armv5te/alt_stub.S */ 15350 /* 15351 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15352 * any interesting requests and then jump to the real instruction 15353 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15354 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15355 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15356 * bail to the real handler if breakFlags==0. 15357 */ 15358 ldrb r3, [rSELF, #offThread_breakFlags] 15359 adrl lr, dvmAsmInstructionStart + (246 * 64) 15360 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15361 cmp r3, #0 15362 bxeq lr @ nothing to do - jump to real handler 15363 EXPORT_PC() 15364 mov r0, rPC @ arg0 15365 mov r1, rFP @ arg1 15366 mov r2, rSELF @ arg2 15367 b dvmCheckBefore @ (dPC,dFP,self) tail call 15368 15369 /* ------------------------------ */ 15370 .balign 64 15371 .L_ALT_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 15372 /* File: armv5te/alt_stub.S */ 15373 /* 15374 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15375 * any interesting requests and then jump to the real instruction 15376 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15377 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15378 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15379 * bail to the real handler if breakFlags==0. 15380 */ 15381 ldrb r3, [rSELF, #offThread_breakFlags] 15382 adrl lr, dvmAsmInstructionStart + (247 * 64) 15383 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15384 cmp r3, #0 15385 bxeq lr @ nothing to do - jump to real handler 15386 EXPORT_PC() 15387 mov r0, rPC @ arg0 15388 mov r1, rFP @ arg1 15389 mov r2, rSELF @ arg2 15390 b dvmCheckBefore @ (dPC,dFP,self) tail call 15391 15392 /* ------------------------------ */ 15393 .balign 64 15394 .L_ALT_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 15395 /* File: armv5te/alt_stub.S */ 15396 /* 15397 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15398 * any interesting requests and then jump to the real instruction 15399 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15400 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15401 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15402 * bail to the real handler if breakFlags==0. 15403 */ 15404 ldrb r3, [rSELF, #offThread_breakFlags] 15405 adrl lr, dvmAsmInstructionStart + (248 * 64) 15406 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15407 cmp r3, #0 15408 bxeq lr @ nothing to do - jump to real handler 15409 EXPORT_PC() 15410 mov r0, rPC @ arg0 15411 mov r1, rFP @ arg1 15412 mov r2, rSELF @ arg2 15413 b dvmCheckBefore @ (dPC,dFP,self) tail call 15414 15415 /* ------------------------------ */ 15416 .balign 64 15417 .L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 15418 /* File: armv5te/alt_stub.S */ 15419 /* 15420 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15421 * any interesting requests and then jump to the real instruction 15422 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15423 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15424 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15425 * bail to the real handler if breakFlags==0. 15426 */ 15427 ldrb r3, [rSELF, #offThread_breakFlags] 15428 adrl lr, dvmAsmInstructionStart + (249 * 64) 15429 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15430 cmp r3, #0 15431 bxeq lr @ nothing to do - jump to real handler 15432 EXPORT_PC() 15433 mov r0, rPC @ arg0 15434 mov r1, rFP @ arg1 15435 mov r2, rSELF @ arg2 15436 b dvmCheckBefore @ (dPC,dFP,self) tail call 15437 15438 /* ------------------------------ */ 15439 .balign 64 15440 .L_ALT_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 15441 /* File: armv5te/alt_stub.S */ 15442 /* 15443 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15444 * any interesting requests and then jump to the real instruction 15445 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15446 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15447 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15448 * bail to the real handler if breakFlags==0. 15449 */ 15450 ldrb r3, [rSELF, #offThread_breakFlags] 15451 adrl lr, dvmAsmInstructionStart + (250 * 64) 15452 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15453 cmp r3, #0 15454 bxeq lr @ nothing to do - jump to real handler 15455 EXPORT_PC() 15456 mov r0, rPC @ arg0 15457 mov r1, rFP @ arg1 15458 mov r2, rSELF @ arg2 15459 b dvmCheckBefore @ (dPC,dFP,self) tail call 15460 15461 /* ------------------------------ */ 15462 .balign 64 15463 .L_ALT_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 15464 /* File: armv5te/alt_stub.S */ 15465 /* 15466 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15467 * any interesting requests and then jump to the real instruction 15468 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15469 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15470 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15471 * bail to the real handler if breakFlags==0. 15472 */ 15473 ldrb r3, [rSELF, #offThread_breakFlags] 15474 adrl lr, dvmAsmInstructionStart + (251 * 64) 15475 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15476 cmp r3, #0 15477 bxeq lr @ nothing to do - jump to real handler 15478 EXPORT_PC() 15479 mov r0, rPC @ arg0 15480 mov r1, rFP @ arg1 15481 mov r2, rSELF @ arg2 15482 b dvmCheckBefore @ (dPC,dFP,self) tail call 15483 15484 /* ------------------------------ */ 15485 .balign 64 15486 .L_ALT_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 15487 /* File: armv5te/alt_stub.S */ 15488 /* 15489 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15490 * any interesting requests and then jump to the real instruction 15491 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15492 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15493 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15494 * bail to the real handler if breakFlags==0. 15495 */ 15496 ldrb r3, [rSELF, #offThread_breakFlags] 15497 adrl lr, dvmAsmInstructionStart + (252 * 64) 15498 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15499 cmp r3, #0 15500 bxeq lr @ nothing to do - jump to real handler 15501 EXPORT_PC() 15502 mov r0, rPC @ arg0 15503 mov r1, rFP @ arg1 15504 mov r2, rSELF @ arg2 15505 b dvmCheckBefore @ (dPC,dFP,self) tail call 15506 15507 /* ------------------------------ */ 15508 .balign 64 15509 .L_ALT_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 15510 /* File: armv5te/alt_stub.S */ 15511 /* 15512 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15513 * any interesting requests and then jump to the real instruction 15514 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15515 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15516 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15517 * bail to the real handler if breakFlags==0. 15518 */ 15519 ldrb r3, [rSELF, #offThread_breakFlags] 15520 adrl lr, dvmAsmInstructionStart + (253 * 64) 15521 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15522 cmp r3, #0 15523 bxeq lr @ nothing to do - jump to real handler 15524 EXPORT_PC() 15525 mov r0, rPC @ arg0 15526 mov r1, rFP @ arg1 15527 mov r2, rSELF @ arg2 15528 b dvmCheckBefore @ (dPC,dFP,self) tail call 15529 15530 /* ------------------------------ */ 15531 .balign 64 15532 .L_ALT_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 15533 /* File: armv5te/alt_stub.S */ 15534 /* 15535 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15536 * any interesting requests and then jump to the real instruction 15537 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15538 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15539 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15540 * bail to the real handler if breakFlags==0. 15541 */ 15542 ldrb r3, [rSELF, #offThread_breakFlags] 15543 adrl lr, dvmAsmInstructionStart + (254 * 64) 15544 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15545 cmp r3, #0 15546 bxeq lr @ nothing to do - jump to real handler 15547 EXPORT_PC() 15548 mov r0, rPC @ arg0 15549 mov r1, rFP @ arg1 15550 mov r2, rSELF @ arg2 15551 b dvmCheckBefore @ (dPC,dFP,self) tail call 15552 15553 /* ------------------------------ */ 15554 .balign 64 15555 .L_ALT_OP_UNUSED_FF: /* 0xff */ 15556 /* File: armv5te/alt_stub.S */ 15557 /* 15558 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15559 * any interesting requests and then jump to the real instruction 15560 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15561 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15562 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15563 * bail to the real handler if breakFlags==0. 15564 */ 15565 ldrb r3, [rSELF, #offThread_breakFlags] 15566 adrl lr, dvmAsmInstructionStart + (255 * 64) 15567 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15568 cmp r3, #0 15569 bxeq lr @ nothing to do - jump to real handler 15570 EXPORT_PC() 15571 mov r0, rPC @ arg0 15572 mov r1, rFP @ arg1 15573 mov r2, rSELF @ arg2 15574 b dvmCheckBefore @ (dPC,dFP,self) tail call 15575 15576 .balign 64 15577 .size dvmAsmAltInstructionStart, .-dvmAsmAltInstructionStart 15578 .global dvmAsmAltInstructionEnd 15579 dvmAsmAltInstructionEnd: 15580 /* File: armv5te/footer.S */ 15581 /* 15582 * =========================================================================== 15583 * Common subroutines and data 15584 * =========================================================================== 15585 */ 15586 15587 .text 15588 .align 2 15589 15590 #if defined(WITH_JIT) 15591 15592 #if defined(WITH_SELF_VERIFICATION) 15593 /* 15594 * "longjmp" to a translation after single-stepping. Before returning 15595 * to translation, must save state for self-verification. 15596 */ 15597 .global dvmJitResumeTranslation @ (Thread* self, u4* dFP) 15598 dvmJitResumeTranslation: 15599 mov rSELF, r0 @ restore self 15600 mov rPC, r1 @ restore Dalvik pc 15601 mov rFP, r2 @ restore Dalvik fp 15602 ldr r10, [rSELF,#offThread_jitResumeNPC] @ resume address 15603 mov r2, #0 15604 str r2, [rSELF,#offThread_jitResumeNPC] @ reset resume address 15605 ldr sp, [rSELF,#offThread_jitResumeNSP] @ cut back native stack 15606 b jitSVShadowRunStart @ resume as if cache hit 15607 @ expects resume addr in r10 15608 15609 .global dvmJitToInterpPunt 15610 dvmJitToInterpPunt: 15611 mov r2,#kSVSPunt @ r2<- interpreter entry point 15612 mov r3, #0 15613 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15614 b jitSVShadowRunEnd @ doesn't return 15615 15616 .global dvmJitToInterpSingleStep 15617 dvmJitToInterpSingleStep: 15618 mov rPC, r0 @ set up dalvik pc 15619 EXPORT_PC() 15620 str lr, [rSELF,#offThread_jitResumeNPC] 15621 str sp, [rSELF,#offThread_jitResumeNSP] 15622 str r1, [rSELF,#offThread_jitResumeDPC] 15623 mov r2,#kSVSSingleStep @ r2<- interpreter entry point 15624 b jitSVShadowRunEnd @ doesn't return 15625 15626 15627 .global dvmJitToInterpNoChainNoProfile 15628 dvmJitToInterpNoChainNoProfile: 15629 mov r0,rPC @ pass our target PC 15630 mov r2,#kSVSNoProfile @ r2<- interpreter entry point 15631 mov r3, #0 @ 0 means !inJitCodeCache 15632 str r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 15633 b jitSVShadowRunEnd @ doesn't return 15634 15635 .global dvmJitToInterpTraceSelectNoChain 15636 dvmJitToInterpTraceSelectNoChain: 15637 mov r0,rPC @ pass our target PC 15638 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 15639 mov r3, #0 @ 0 means !inJitCodeCache 15640 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15641 b jitSVShadowRunEnd @ doesn't return 15642 15643 .global dvmJitToInterpTraceSelect 15644 dvmJitToInterpTraceSelect: 15645 ldr r0,[lr, #-1] @ pass our target PC 15646 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 15647 mov r3, #0 @ 0 means !inJitCodeCache 15648 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15649 b jitSVShadowRunEnd @ doesn't return 15650 15651 .global dvmJitToInterpBackwardBranch 15652 dvmJitToInterpBackwardBranch: 15653 ldr r0,[lr, #-1] @ pass our target PC 15654 mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point 15655 mov r3, #0 @ 0 means !inJitCodeCache 15656 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15657 b jitSVShadowRunEnd @ doesn't return 15658 15659 .global dvmJitToInterpNormal 15660 dvmJitToInterpNormal: 15661 ldr r0,[lr, #-1] @ pass our target PC 15662 mov r2,#kSVSNormal @ r2<- interpreter entry point 15663 mov r3, #0 @ 0 means !inJitCodeCache 15664 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15665 b jitSVShadowRunEnd @ doesn't return 15666 15667 .global dvmJitToInterpNoChain 15668 dvmJitToInterpNoChain: 15669 mov r0,rPC @ pass our target PC 15670 mov r2,#kSVSNoChain @ r2<- interpreter entry point 15671 mov r3, #0 @ 0 means !inJitCodeCache 15672 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15673 b jitSVShadowRunEnd @ doesn't return 15674 #else 15675 15676 /* 15677 * "longjmp" to a translation after single-stepping. 15678 */ 15679 .global dvmJitResumeTranslation @ (Thread* self, u4* dFP) 15680 dvmJitResumeTranslation: 15681 mov rSELF, r0 @ restore self 15682 mov rPC, r1 @ restore Dalvik pc 15683 mov rFP, r2 @ restore Dalvik fp 15684 ldr r0, [rSELF,#offThread_jitResumeNPC] 15685 mov r2, #0 15686 str r2, [rSELF,#offThread_jitResumeNPC] @ reset resume address 15687 ldr sp, [rSELF,#offThread_jitResumeNSP] @ cut back native stack 15688 bx r0 @ resume translation 15689 15690 /* 15691 * Return from the translation cache to the interpreter when the compiler is 15692 * having issues translating/executing a Dalvik instruction. We have to skip 15693 * the code cache lookup otherwise it is possible to indefinitely bouce 15694 * between the interpreter and the code cache if the instruction that fails 15695 * to be compiled happens to be at a trace start. 15696 */ 15697 .global dvmJitToInterpPunt 15698 dvmJitToInterpPunt: 15699 mov rPC, r0 15700 #if defined(WITH_JIT_TUNING) 15701 mov r0,lr 15702 bl dvmBumpPunt; 15703 #endif 15704 EXPORT_PC() 15705 mov r0, #0 15706 str r0, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15707 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15708 FETCH_INST() 15709 GET_INST_OPCODE(ip) 15710 GOTO_OPCODE(ip) 15711 15712 /* 15713 * Return to the interpreter to handle a single instruction. 15714 * We'll use the normal single-stepping mechanism via interpBreak, 15715 * but also save the native pc of the resume point in the translation 15716 * and the native sp so that we can later do the equivalent of a 15717 * longjmp() to resume. 15718 * On entry: 15719 * dPC <= Dalvik PC of instrucion to interpret 15720 * lr <= resume point in translation 15721 * r1 <= Dalvik PC of next instruction 15722 */ 15723 .global dvmJitToInterpSingleStep 15724 dvmJitToInterpSingleStep: 15725 mov rPC, r0 @ set up dalvik pc 15726 EXPORT_PC() 15727 str lr, [rSELF,#offThread_jitResumeNPC] 15728 str sp, [rSELF,#offThread_jitResumeNSP] 15729 str r1, [rSELF,#offThread_jitResumeDPC] 15730 mov r1, #1 15731 str r1, [rSELF,#offThread_singleStepCount] @ just step once 15732 mov r0, rSELF 15733 mov r1, #kSubModeCountedStep 15734 bl dvmEnableSubMode @ (self, newMode) 15735 ldr rIBASE, [rSELF,#offThread_curHandlerTable] 15736 FETCH_INST() 15737 GET_INST_OPCODE(ip) 15738 GOTO_OPCODE(ip) 15739 15740 /* 15741 * Return from the translation cache and immediately request 15742 * a translation for the exit target. Commonly used for callees. 15743 */ 15744 .global dvmJitToInterpTraceSelectNoChain 15745 dvmJitToInterpTraceSelectNoChain: 15746 #if defined(WITH_JIT_TUNING) 15747 bl dvmBumpNoChain 15748 #endif 15749 mov r0,rPC 15750 mov r1,rSELF 15751 bl dvmJitGetTraceAddrThread @ (pc, self) 15752 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15753 mov r1, rPC @ arg1 of translation may need this 15754 mov lr, #0 @ in case target is HANDLER_INTERPRET 15755 cmp r0,#0 @ !0 means translation exists 15756 bxne r0 @ continue native execution if so 15757 b 2f @ branch over to use the interpreter 15758 15759 /* 15760 * Return from the translation cache and immediately request 15761 * a translation for the exit target. Commonly used following 15762 * invokes. 15763 */ 15764 .global dvmJitToInterpTraceSelect 15765 dvmJitToInterpTraceSelect: 15766 ldr rPC,[lr, #-1] @ get our target PC 15767 add rINST,lr,#-5 @ save start of chain branch 15768 add rINST, #-4 @ .. which is 9 bytes back 15769 mov r0,rPC 15770 mov r1,rSELF 15771 bl dvmJitGetTraceAddrThread @ (pc, self) 15772 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15773 cmp r0,#0 15774 beq 2f 15775 mov r1,rINST 15776 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 15777 mov r1, rPC @ arg1 of translation may need this 15778 mov lr, #0 @ in case target is HANDLER_INTERPRET 15779 cmp r0,#0 @ successful chain? 15780 bxne r0 @ continue native execution 15781 b toInterpreter @ didn't chain - resume with interpreter 15782 15783 /* No translation, so request one if profiling isn't disabled*/ 15784 2: 15785 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15786 ldr r0, [rSELF, #offThread_pJitProfTable] 15787 FETCH_INST() 15788 cmp r0, #0 15789 movne r2,#kJitTSelectRequestHot @ ask for trace selection 15790 bne common_selectTrace 15791 GET_INST_OPCODE(ip) 15792 GOTO_OPCODE(ip) 15793 15794 /* 15795 * Return from the translation cache to the interpreter. 15796 * The return was done with a BLX from thumb mode, and 15797 * the following 32-bit word contains the target rPC value. 15798 * Note that lr (r14) will have its low-order bit set to denote 15799 * its thumb-mode origin. 15800 * 15801 * We'll need to stash our lr origin away, recover the new 15802 * target and then check to see if there is a translation available 15803 * for our new target. If so, we do a translation chain and 15804 * go back to native execution. Otherwise, it's back to the 15805 * interpreter (after treating this entry as a potential 15806 * trace start). 15807 */ 15808 .global dvmJitToInterpNormal 15809 dvmJitToInterpNormal: 15810 ldr rPC,[lr, #-1] @ get our target PC 15811 add rINST,lr,#-5 @ save start of chain branch 15812 add rINST,#-4 @ .. which is 9 bytes back 15813 #if defined(WITH_JIT_TUNING) 15814 bl dvmBumpNormal 15815 #endif 15816 mov r0,rPC 15817 mov r1,rSELF 15818 bl dvmJitGetTraceAddrThread @ (pc, self) 15819 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15820 cmp r0,#0 15821 beq toInterpreter @ go if not, otherwise do chain 15822 mov r1,rINST 15823 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 15824 mov r1, rPC @ arg1 of translation may need this 15825 mov lr, #0 @ in case target is HANDLER_INTERPRET 15826 cmp r0,#0 @ successful chain? 15827 bxne r0 @ continue native execution 15828 b toInterpreter @ didn't chain - resume with interpreter 15829 15830 /* 15831 * Return from the translation cache to the interpreter to do method invocation. 15832 * Check if translation exists for the callee, but don't chain to it. 15833 */ 15834 .global dvmJitToInterpNoChainNoProfile 15835 dvmJitToInterpNoChainNoProfile: 15836 #if defined(WITH_JIT_TUNING) 15837 bl dvmBumpNoChain 15838 #endif 15839 mov r0,rPC 15840 mov r1,rSELF 15841 bl dvmJitGetTraceAddrThread @ (pc, self) 15842 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15843 mov r1, rPC @ arg1 of translation may need this 15844 mov lr, #0 @ in case target is HANDLER_INTERPRET 15845 cmp r0,#0 15846 bxne r0 @ continue native execution if so 15847 EXPORT_PC() 15848 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15849 FETCH_INST() 15850 GET_INST_OPCODE(ip) @ extract opcode from rINST 15851 GOTO_OPCODE(ip) @ jump to next instruction 15852 15853 /* 15854 * Return from the translation cache to the interpreter to do method invocation. 15855 * Check if translation exists for the callee, but don't chain to it. 15856 */ 15857 .global dvmJitToInterpNoChain 15858 dvmJitToInterpNoChain: 15859 #if defined(WITH_JIT_TUNING) 15860 bl dvmBumpNoChain 15861 #endif 15862 mov r0,rPC 15863 mov r1,rSELF 15864 bl dvmJitGetTraceAddrThread @ (pc, self) 15865 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15866 mov r1, rPC @ arg1 of translation may need this 15867 mov lr, #0 @ in case target is HANDLER_INTERPRET 15868 cmp r0,#0 15869 bxne r0 @ continue native execution if so 15870 #endif 15871 15872 /* 15873 * No translation, restore interpreter regs and start interpreting. 15874 * rSELF & rFP were preserved in the translated code, and rPC has 15875 * already been restored by the time we get here. We'll need to set 15876 * up rIBASE & rINST, and load the address of the JitTable into r0. 15877 */ 15878 toInterpreter: 15879 EXPORT_PC() 15880 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15881 FETCH_INST() 15882 ldr r0, [rSELF, #offThread_pJitProfTable] 15883 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15884 @ NOTE: intended fallthrough 15885 15886 /* 15887 * Similar to common_updateProfile, but tests for null pJitProfTable 15888 * r0 holds pJifProfTAble, rINST is loaded, rPC is current and 15889 * rIBASE has been recently refreshed. 15890 */ 15891 common_testUpdateProfile: 15892 cmp r0, #0 @ JIT switched off? 15893 beq 4f @ return to interp if so 15894 15895 /* 15896 * Common code to update potential trace start counter, and initiate 15897 * a trace-build if appropriate. 15898 * On entry here: 15899 * r0 <= pJitProfTable (verified non-NULL) 15900 * rPC <= Dalvik PC 15901 * rINST <= next instruction 15902 */ 15903 common_updateProfile: 15904 eor r3,rPC,rPC,lsr #12 @ cheap, but fast hash function 15905 lsl r3,r3,#(32 - JIT_PROF_SIZE_LOG_2) @ shift out excess bits 15906 ldrb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter 15907 GET_INST_OPCODE(ip) 15908 subs r1,r1,#1 @ decrement counter 15909 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it 15910 GOTO_OPCODE_IFNE(ip) @ if not threshold, fallthrough otherwise */ 15911 15912 /* Looks good, reset the counter */ 15913 ldr r1, [rSELF, #offThread_jitThreshold] 15914 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter 15915 EXPORT_PC() 15916 mov r0,rPC 15917 mov r1,rSELF 15918 bl dvmJitGetTraceAddrThread @ (pc, self) 15919 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15920 mov r1, rPC @ arg1 of translation may need this 15921 mov lr, #0 @ in case target is HANDLER_INTERPRET 15922 cmp r0,#0 15923 #if !defined(WITH_SELF_VERIFICATION) 15924 bxne r0 @ jump to the translation 15925 mov r2,#kJitTSelectRequest @ ask for trace selection 15926 @ fall-through to common_selectTrace 15927 #else 15928 moveq r2,#kJitTSelectRequest @ ask for trace selection 15929 beq common_selectTrace 15930 /* 15931 * At this point, we have a target translation. However, if 15932 * that translation is actually the interpret-only pseudo-translation 15933 * we want to treat it the same as no translation. 15934 */ 15935 mov r10, r0 @ save target 15936 bl dvmCompilerGetInterpretTemplate 15937 cmp r0, r10 @ special case? 15938 bne jitSVShadowRunStart @ set up self verification shadow space 15939 @ Need to clear the inJitCodeCache flag 15940 mov r3, #0 @ 0 means not in the JIT code cache 15941 str r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 15942 GET_INST_OPCODE(ip) 15943 GOTO_OPCODE(ip) 15944 /* no return */ 15945 #endif 15946 15947 /* 15948 * On entry: 15949 * r2 is jit state. 15950 */ 15951 common_selectTrace: 15952 ldrh r0,[rSELF,#offThread_subMode] 15953 ands r0, #(kSubModeJitTraceBuild | kSubModeJitSV) 15954 bne 3f @ already doing JIT work, continue 15955 str r2,[rSELF,#offThread_jitState] 15956 mov r0, rSELF 15957 /* 15958 * Call out to validate trace-building request. If successful, 15959 * rIBASE will be swapped to to send us into single-stepping trace 15960 * building mode, so we need to refresh before we continue. 15961 */ 15962 EXPORT_PC() 15963 SAVE_PC_FP_TO_SELF() @ copy of pc/fp to Thread 15964 bl dvmJitCheckTraceRequest 15965 3: 15966 FETCH_INST() 15967 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15968 4: 15969 GET_INST_OPCODE(ip) @ extract opcode from rINST 15970 GOTO_OPCODE(ip) 15971 /* no return */ 15972 #endif 15973 15974 #if defined(WITH_SELF_VERIFICATION) 15975 /* 15976 * Save PC and registers to shadow memory for self verification mode 15977 * before jumping to native translation. 15978 * On entry: 15979 * rPC, rFP, rSELF: the values that they should contain 15980 * r10: the address of the target translation. 15981 */ 15982 jitSVShadowRunStart: 15983 mov r0,rPC @ r0<- program counter 15984 mov r1,rFP @ r1<- frame pointer 15985 mov r2,rSELF @ r2<- self (Thread) pointer 15986 mov r3,r10 @ r3<- target translation 15987 bl dvmSelfVerificationSaveState @ save registers to shadow space 15988 ldr rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space 15989 bx r10 @ jump to the translation 15990 15991 /* 15992 * Restore PC, registers, and interpreter state to original values 15993 * before jumping back to the interpreter. 15994 * On entry: 15995 * r0: dPC 15996 * r2: self verification state 15997 */ 15998 jitSVShadowRunEnd: 15999 mov r1,rFP @ pass ending fp 16000 mov r3,rSELF @ pass self ptr for convenience 16001 bl dvmSelfVerificationRestoreState @ restore pc and fp values 16002 LOAD_PC_FP_FROM_SELF() @ restore pc, fp 16003 ldr r1,[r0,#offShadowSpace_svState] @ get self verification state 16004 cmp r1,#0 @ check for punt condition 16005 beq 1f 16006 @ Set up SV single-stepping 16007 mov r0, rSELF 16008 mov r1, #kSubModeJitSV 16009 bl dvmEnableSubMode @ (self, subMode) 16010 mov r2,#kJitSelfVerification @ ask for self verification 16011 str r2,[rSELF,#offThread_jitState] 16012 @ intentional fallthrough 16013 1: @ exit to interpreter without check 16014 EXPORT_PC() 16015 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16016 FETCH_INST() 16017 GET_INST_OPCODE(ip) 16018 GOTO_OPCODE(ip) 16019 #endif 16020 16021 /* 16022 * The equivalent of "goto bail", this calls through the "bail handler". 16023 * It will end this interpreter activation, and return to the caller 16024 * of dvmMterpStdRun. 16025 * 16026 * State registers will be saved to the "thread" area before bailing 16027 * debugging purposes 16028 */ 16029 common_gotoBail: 16030 SAVE_PC_FP_TO_SELF() @ export state to "thread" 16031 mov r0, rSELF @ r0<- self ptr 16032 b dvmMterpStdBail @ call(self, changeInterp) 16033 16034 /* 16035 * The JIT's invoke method needs to remember the callsite class and 16036 * target pair. Save them here so that they are available to 16037 * dvmCheckJit following the interpretation of this invoke. 16038 */ 16039 #if defined(WITH_JIT) 16040 save_callsiteinfo: 16041 cmp r9, #0 16042 ldrne r9, [r9, #offObject_clazz] 16043 str r0, [rSELF, #offThread_methodToCall] 16044 str r9, [rSELF, #offThread_callsiteClass] 16045 bx lr 16046 #endif 16047 16048 /* 16049 * Common code for method invocation with range. 16050 * 16051 * On entry: 16052 * r0 is "Method* methodToCall", r9 is "this" 16053 */ 16054 common_invokeMethodRange: 16055 .LinvokeNewRange: 16056 #if defined(WITH_JIT) 16057 ldrh r1, [rSELF, #offThread_subMode] 16058 ands r1, #kSubModeJitTraceBuild 16059 blne save_callsiteinfo 16060 #endif 16061 @ prepare to copy args to "outs" area of current frame 16062 movs r2, rINST, lsr #8 @ r2<- AA (arg count) -- test for zero 16063 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 16064 beq .LinvokeArgsDone @ if no args, skip the rest 16065 FETCH(r1, 2) @ r1<- CCCC 16066 16067 .LinvokeRangeArgs: 16068 @ r0=methodToCall, r1=CCCC, r2=count, r10=outs 16069 @ (very few methods have > 10 args; could unroll for common cases) 16070 add r3, rFP, r1, lsl #2 @ r3<- &fp[CCCC] 16071 sub r10, r10, r2, lsl #2 @ r10<- "outs" area, for call args 16072 1: ldr r1, [r3], #4 @ val = *fp++ 16073 subs r2, r2, #1 @ count-- 16074 str r1, [r10], #4 @ *outs++ = val 16075 bne 1b @ ...while count != 0 16076 b .LinvokeArgsDone 16077 16078 /* 16079 * Common code for method invocation without range. 16080 * 16081 * On entry: 16082 * r0 is "Method* methodToCall", r9 is "this" 16083 */ 16084 common_invokeMethodNoRange: 16085 .LinvokeNewNoRange: 16086 #if defined(WITH_JIT) 16087 ldrh r1, [rSELF, #offThread_subMode] 16088 ands r1, #kSubModeJitTraceBuild 16089 blne save_callsiteinfo 16090 #endif 16091 @ prepare to copy args to "outs" area of current frame 16092 movs r2, rINST, lsr #12 @ r2<- B (arg count) -- test for zero 16093 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 16094 FETCH(r1, 2) @ r1<- GFED (load here to hide latency) 16095 beq .LinvokeArgsDone 16096 16097 @ r0=methodToCall, r1=GFED, r2=count, r10=outs 16098 .LinvokeNonRange: 16099 rsb r2, r2, #5 @ r2<- 5-r2 16100 add pc, pc, r2, lsl #4 @ computed goto, 4 instrs each 16101 bl common_abort @ (skipped due to ARM prefetch) 16102 5: and ip, rINST, #0x0f00 @ isolate A 16103 ldr r2, [rFP, ip, lsr #6] @ r2<- vA (shift right 8, left 2) 16104 mov r0, r0 @ nop 16105 str r2, [r10, #-4]! @ *--outs = vA 16106 4: and ip, r1, #0xf000 @ isolate G 16107 ldr r2, [rFP, ip, lsr #10] @ r2<- vG (shift right 12, left 2) 16108 mov r0, r0 @ nop 16109 str r2, [r10, #-4]! @ *--outs = vG 16110 3: and ip, r1, #0x0f00 @ isolate F 16111 ldr r2, [rFP, ip, lsr #6] @ r2<- vF 16112 mov r0, r0 @ nop 16113 str r2, [r10, #-4]! @ *--outs = vF 16114 2: and ip, r1, #0x00f0 @ isolate E 16115 ldr r2, [rFP, ip, lsr #2] @ r2<- vE 16116 mov r0, r0 @ nop 16117 str r2, [r10, #-4]! @ *--outs = vE 16118 1: and ip, r1, #0x000f @ isolate D 16119 ldr r2, [rFP, ip, lsl #2] @ r2<- vD 16120 mov r0, r0 @ nop 16121 str r2, [r10, #-4]! @ *--outs = vD 16122 0: @ fall through to .LinvokeArgsDone 16123 16124 .LinvokeArgsDone: @ r0=methodToCall 16125 ldrh r9, [r0, #offMethod_registersSize] @ r9<- methodToCall->regsSize 16126 ldrh r3, [r0, #offMethod_outsSize] @ r3<- methodToCall->outsSize 16127 ldr r2, [r0, #offMethod_insns] @ r2<- method->insns 16128 ldr rINST, [r0, #offMethod_clazz] @ rINST<- method->clazz 16129 @ find space for the new stack frame, check for overflow 16130 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area 16131 sub r1, r1, r9, lsl #2 @ r1<- newFp (old savearea - regsSize) 16132 SAVEAREA_FROM_FP(r10, r1) @ r10<- newSaveArea 16133 @ bl common_dumpRegs 16134 ldr r9, [rSELF, #offThread_interpStackEnd] @ r9<- interpStackEnd 16135 sub r3, r10, r3, lsl #2 @ r3<- bottom (newsave - outsSize) 16136 cmp r3, r9 @ bottom < interpStackEnd? 16137 ldrh lr, [rSELF, #offThread_subMode] 16138 ldr r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags 16139 blo .LstackOverflow @ yes, this frame will overflow stack 16140 16141 @ set up newSaveArea 16142 #ifdef EASY_GDB 16143 SAVEAREA_FROM_FP(ip, rFP) @ ip<- stack save area 16144 str ip, [r10, #offStackSaveArea_prevSave] 16145 #endif 16146 str rFP, [r10, #offStackSaveArea_prevFrame] 16147 str rPC, [r10, #offStackSaveArea_savedPc] 16148 #if defined(WITH_JIT) 16149 mov r9, #0 16150 str r9, [r10, #offStackSaveArea_returnAddr] 16151 #endif 16152 str r0, [r10, #offStackSaveArea_method] 16153 16154 @ Profiling? 16155 cmp lr, #0 @ any special modes happening? 16156 bne 2f @ go if so 16157 1: 16158 tst r3, #ACC_NATIVE 16159 bne .LinvokeNative 16160 16161 /* 16162 stmfd sp!, {r0-r3} 16163 bl common_printNewline 16164 mov r0, rFP 16165 mov r1, #0 16166 bl dvmDumpFp 16167 ldmfd sp!, {r0-r3} 16168 stmfd sp!, {r0-r3} 16169 mov r0, r1 16170 mov r1, r10 16171 bl dvmDumpFp 16172 bl common_printNewline 16173 ldmfd sp!, {r0-r3} 16174 */ 16175 16176 ldrh r9, [r2] @ r9 <- load INST from new PC 16177 ldr r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex 16178 mov rPC, r2 @ publish new rPC 16179 16180 @ Update state values for the new method 16181 @ r0=methodToCall, r1=newFp, r3=newMethodClass, r9=newINST 16182 str r0, [rSELF, #offThread_method] @ self->method = methodToCall 16183 str r3, [rSELF, #offThread_methodClassDex] @ self->methodClassDex = ... 16184 mov r2, #1 16185 str r2, [rSELF, #offThread_debugIsMethodEntry] 16186 #if defined(WITH_JIT) 16187 ldr r0, [rSELF, #offThread_pJitProfTable] 16188 mov rFP, r1 @ fp = newFp 16189 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 16190 mov rINST, r9 @ publish new rINST 16191 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16192 cmp r0,#0 16193 bne common_updateProfile 16194 GOTO_OPCODE(ip) @ jump to next instruction 16195 #else 16196 mov rFP, r1 @ fp = newFp 16197 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 16198 mov rINST, r9 @ publish new rINST 16199 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16200 GOTO_OPCODE(ip) @ jump to next instruction 16201 #endif 16202 16203 2: 16204 @ Profiling - record method entry. r0: methodToCall 16205 stmfd sp!, {r0-r3} @ preserve r0-r3 16206 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16207 mov r1, r0 16208 mov r0, rSELF 16209 bl dvmReportInvoke @ (self, method) 16210 ldmfd sp!, {r0-r3} @ restore r0-r3 16211 b 1b 16212 16213 .LinvokeNative: 16214 @ Prep for the native call 16215 @ r0=methodToCall, r1=newFp, r10=newSaveArea 16216 ldrh lr, [rSELF, #offThread_subMode] 16217 ldr r9, [rSELF, #offThread_jniLocal_topCookie]@r9<-thread->localRef->... 16218 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16219 str r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top 16220 mov r2, r0 @ r2<- methodToCall 16221 mov r0, r1 @ r0<- newFp (points to args) 16222 add r1, rSELF, #offThread_retval @ r1<- &retval 16223 mov r3, rSELF @ arg3<- self 16224 16225 #ifdef ASSIST_DEBUGGER 16226 /* insert fake function header to help gdb find the stack frame */ 16227 b .Lskip 16228 .type dalvik_mterp, %function 16229 dalvik_mterp: 16230 .fnstart 16231 MTERP_ENTRY1 16232 MTERP_ENTRY2 16233 .Lskip: 16234 #endif 16235 16236 cmp lr, #0 @ any special SubModes active? 16237 bne 11f @ go handle them if so 16238 mov lr, pc @ set return addr 16239 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 16240 7: 16241 16242 @ native return; r10=newSaveArea 16243 @ equivalent to dvmPopJniLocals 16244 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top 16245 ldr r1, [rSELF, #offThread_exception] @ check for exception 16246 str rFP, [rSELF, #offThread_curFrame] @ curFrame = fp 16247 cmp r1, #0 @ null? 16248 str r0, [rSELF, #offThread_jniLocal_topCookie] @ new top <- old top 16249 bne common_exceptionThrown @ no, handle exception 16250 16251 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 16252 GET_INST_OPCODE(ip) @ extract opcode from rINST 16253 GOTO_OPCODE(ip) @ jump to next instruction 16254 16255 11: 16256 @ r0=newFp, r1=&retval, r2=methodToCall, r3=self, lr=subModes 16257 stmfd sp!, {r0-r3} @ save all but subModes 16258 mov r0, r2 @ r0<- methodToCall 16259 mov r1, rSELF 16260 mov r2, rFP 16261 bl dvmReportPreNativeInvoke @ (methodToCall, self, fp) 16262 ldmfd sp, {r0-r3} @ refresh. NOTE: no sp autoincrement 16263 16264 @ Call the native method 16265 mov lr, pc @ set return addr 16266 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 16267 16268 @ Restore the pre-call arguments 16269 ldmfd sp!, {r0-r3} @ r2<- methodToCall (others unneeded) 16270 16271 @ Finish up any post-invoke subMode requirements 16272 mov r0, r2 @ r0<- methodToCall 16273 mov r1, rSELF 16274 mov r2, rFP 16275 bl dvmReportPostNativeInvoke @ (methodToCall, self, fp) 16276 b 7b @ resume 16277 16278 .LstackOverflow: @ r0=methodToCall 16279 mov r1, r0 @ r1<- methodToCall 16280 mov r0, rSELF @ r0<- self 16281 bl dvmHandleStackOverflow 16282 b common_exceptionThrown 16283 #ifdef ASSIST_DEBUGGER 16284 .fnend 16285 .size dalvik_mterp, .-dalvik_mterp 16286 #endif 16287 16288 16289 /* 16290 * Common code for method invocation, calling through "glue code". 16291 * 16292 * TODO: now that we have range and non-range invoke handlers, this 16293 * needs to be split into two. Maybe just create entry points 16294 * that set r9 and jump here? 16295 * 16296 * On entry: 16297 * r0 is "Method* methodToCall", the method we're trying to call 16298 * r9 is "bool methodCallRange", indicating if this is a /range variant 16299 */ 16300 .if 0 16301 .LinvokeOld: 16302 sub sp, sp, #8 @ space for args + pad 16303 FETCH(ip, 2) @ ip<- FEDC or CCCC 16304 mov r2, r0 @ A2<- methodToCall 16305 mov r0, rSELF @ A0<- self 16306 SAVE_PC_FP_TO_SELF() @ export state to "self" 16307 mov r1, r9 @ A1<- methodCallRange 16308 mov r3, rINST, lsr #8 @ A3<- AA 16309 str ip, [sp, #0] @ A4<- ip 16310 bl dvmMterp_invokeMethod @ call the C invokeMethod 16311 add sp, sp, #8 @ remove arg area 16312 b common_resumeAfterGlueCall @ continue to next instruction 16313 .endif 16314 16315 16316 16317 /* 16318 * Common code for handling a return instruction. 16319 * 16320 * This does not return. 16321 */ 16322 common_returnFromMethod: 16323 .LreturnNew: 16324 ldrh lr, [rSELF, #offThread_subMode] 16325 SAVEAREA_FROM_FP(r0, rFP) 16326 ldr r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc 16327 cmp lr, #0 @ any special subMode handling needed? 16328 bne 19f 16329 14: 16330 ldr rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame 16331 ldr r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)] 16332 @ r2<- method we're returning to 16333 cmp r2, #0 @ is this a break frame? 16334 #if defined(WORKAROUND_CORTEX_A9_745320) 16335 /* Don't use conditional loads if the HW defect exists */ 16336 beq 15f 16337 ldr r10, [r2, #offMethod_clazz] @ r10<- method->clazz 16338 15: 16339 #else 16340 ldrne r10, [r2, #offMethod_clazz] @ r10<- method->clazz 16341 #endif 16342 beq common_gotoBail @ break frame, bail out completely 16343 16344 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 16345 PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST 16346 str r2, [rSELF, #offThread_method]@ self->method = newSave->method 16347 ldr r1, [r10, #offClassObject_pDvmDex] @ r1<- method->clazz->pDvmDex 16348 str rFP, [rSELF, #offThread_curFrame] @ curFrame = fp 16349 #if defined(WITH_JIT) 16350 ldr r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr 16351 mov rPC, r9 @ publish new rPC 16352 str r1, [rSELF, #offThread_methodClassDex] 16353 str r10, [rSELF, #offThread_inJitCodeCache] @ may return to JIT'ed land 16354 cmp r10, #0 @ caller is compiled code 16355 blxne r10 16356 GET_INST_OPCODE(ip) @ extract opcode from rINST 16357 GOTO_OPCODE(ip) @ jump to next instruction 16358 #else 16359 GET_INST_OPCODE(ip) @ extract opcode from rINST 16360 mov rPC, r9 @ publish new rPC 16361 str r1, [rSELF, #offThread_methodClassDex] 16362 GOTO_OPCODE(ip) @ jump to next instruction 16363 #endif 16364 16365 19: 16366 @ Handle special actions 16367 @ On entry, r0: StackSaveArea 16368 ldr r1, [r0, #offStackSaveArea_prevFrame] @ r2<- prevFP 16369 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16370 str r1, [rSELF, #offThread_curFrame] @ update interpSave.curFrame 16371 mov r0, rSELF 16372 bl dvmReportReturn @ (self) 16373 SAVEAREA_FROM_FP(r0, rFP) @ restore StackSaveArea 16374 b 14b @ continue 16375 16376 /* 16377 * Return handling, calls through "glue code". 16378 */ 16379 .if 0 16380 .LreturnOld: 16381 SAVE_PC_FP_TO_SELF() @ export state 16382 mov r0, rSELF @ arg to function 16383 bl dvmMterp_returnFromMethod 16384 b common_resumeAfterGlueCall 16385 .endif 16386 16387 16388 /* 16389 * Somebody has thrown an exception. Handle it. 16390 * 16391 * If the exception processing code returns to us (instead of falling 16392 * out of the interpreter), continue with whatever the next instruction 16393 * now happens to be. 16394 * 16395 * This does not return. 16396 */ 16397 .global dvmMterpCommonExceptionThrown 16398 dvmMterpCommonExceptionThrown: 16399 common_exceptionThrown: 16400 .LexceptionNew: 16401 16402 EXPORT_PC() 16403 16404 mov r0, rSELF 16405 bl dvmCheckSuspendPending 16406 16407 ldr r9, [rSELF, #offThread_exception] @ r9<- self->exception 16408 mov r1, rSELF @ r1<- self 16409 mov r0, r9 @ r0<- exception 16410 bl dvmAddTrackedAlloc @ don't let the exception be GCed 16411 ldrh r2, [rSELF, #offThread_subMode] @ get subMode flags 16412 mov r3, #0 @ r3<- NULL 16413 str r3, [rSELF, #offThread_exception] @ self->exception = NULL 16414 16415 @ Special subMode? 16416 cmp r2, #0 @ any special subMode handling needed? 16417 bne 7f @ go if so 16418 8: 16419 /* set up args and a local for "&fp" */ 16420 /* (str sp, [sp, #-4]! would be perfect here, but is discouraged) */ 16421 str rFP, [sp, #-4]! @ *--sp = fp 16422 mov ip, sp @ ip<- &fp 16423 mov r3, #0 @ r3<- false 16424 str ip, [sp, #-4]! @ *--sp = &fp 16425 ldr r1, [rSELF, #offThread_method] @ r1<- self->method 16426 mov r0, rSELF @ r0<- self 16427 ldr r1, [r1, #offMethod_insns] @ r1<- method->insns 16428 ldrh lr, [rSELF, #offThread_subMode] @ lr<- subMode flags 16429 mov r2, r9 @ r2<- exception 16430 sub r1, rPC, r1 @ r1<- pc - method->insns 16431 mov r1, r1, asr #1 @ r1<- offset in code units 16432 16433 /* call, r0 gets catchRelPc (a code-unit offset) */ 16434 bl dvmFindCatchBlock @ call(self, relPc, exc, scan?, &fp) 16435 16436 /* fix earlier stack overflow if necessary; may trash rFP */ 16437 ldrb r1, [rSELF, #offThread_stackOverflowed] 16438 cmp r1, #0 @ did we overflow earlier? 16439 beq 1f @ no, skip ahead 16440 mov rFP, r0 @ save relPc result in rFP 16441 mov r0, rSELF @ r0<- self 16442 mov r1, r9 @ r1<- exception 16443 bl dvmCleanupStackOverflow @ call(self) 16444 mov r0, rFP @ restore result 16445 1: 16446 16447 /* update frame pointer and check result from dvmFindCatchBlock */ 16448 ldr rFP, [sp, #4] @ retrieve the updated rFP 16449 cmp r0, #0 @ is catchRelPc < 0? 16450 add sp, sp, #8 @ restore stack 16451 bmi .LnotCaughtLocally 16452 16453 /* adjust locals to match self->interpSave.curFrame and updated PC */ 16454 SAVEAREA_FROM_FP(r1, rFP) @ r1<- new save area 16455 ldr r1, [r1, #offStackSaveArea_method] @ r1<- new method 16456 str r1, [rSELF, #offThread_method] @ self->method = new method 16457 ldr r2, [r1, #offMethod_clazz] @ r2<- method->clazz 16458 ldr r3, [r1, #offMethod_insns] @ r3<- method->insns 16459 ldr r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex 16460 add rPC, r3, r0, asl #1 @ rPC<- method->insns + catchRelPc 16461 str r2, [rSELF, #offThread_methodClassDex] @ self->pDvmDex = meth... 16462 16463 /* release the tracked alloc on the exception */ 16464 mov r0, r9 @ r0<- exception 16465 mov r1, rSELF @ r1<- self 16466 bl dvmReleaseTrackedAlloc @ release the exception 16467 16468 /* restore the exception if the handler wants it */ 16469 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 16470 FETCH_INST() @ load rINST from rPC 16471 GET_INST_OPCODE(ip) @ extract opcode from rINST 16472 cmp ip, #OP_MOVE_EXCEPTION @ is it "move-exception"? 16473 streq r9, [rSELF, #offThread_exception] @ yes, restore the exception 16474 GOTO_OPCODE(ip) @ jump to next instruction 16475 16476 @ Manage debugger bookkeeping 16477 7: 16478 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16479 str rFP, [rSELF, #offThread_curFrame] @ update interpSave.curFrame 16480 mov r0, rSELF @ arg0<- self 16481 mov r1, r9 @ arg1<- exception 16482 bl dvmReportExceptionThrow @ (self, exception) 16483 b 8b @ resume with normal handling 16484 16485 .LnotCaughtLocally: @ r9=exception 16486 /* fix stack overflow if necessary */ 16487 ldrb r1, [rSELF, #offThread_stackOverflowed] 16488 cmp r1, #0 @ did we overflow earlier? 16489 movne r0, rSELF @ if yes: r0<- self 16490 movne r1, r9 @ if yes: r1<- exception 16491 blne dvmCleanupStackOverflow @ if yes: call(self) 16492 16493 @ may want to show "not caught locally" debug messages here 16494 #if DVM_SHOW_EXCEPTION >= 2 16495 /* call __android_log_print(prio, tag, format, ...) */ 16496 /* "Exception %s from %s:%d not caught locally" */ 16497 @ dvmLineNumFromPC(method, pc - method->insns) 16498 ldr r0, [rSELF, #offThread_method] 16499 ldr r1, [r0, #offMethod_insns] 16500 sub r1, rPC, r1 16501 asr r1, r1, #1 16502 bl dvmLineNumFromPC 16503 str r0, [sp, #-4]! 16504 @ dvmGetMethodSourceFile(method) 16505 ldr r0, [rSELF, #offThread_method] 16506 bl dvmGetMethodSourceFile 16507 str r0, [sp, #-4]! 16508 @ exception->clazz->descriptor 16509 ldr r3, [r9, #offObject_clazz] 16510 ldr r3, [r3, #offClassObject_descriptor] 16511 @ 16512 ldr r2, strExceptionNotCaughtLocally 16513 ldr r1, strLogTag 16514 mov r0, #3 @ LOG_DEBUG 16515 bl __android_log_print 16516 #endif 16517 str r9, [rSELF, #offThread_exception] @ restore exception 16518 mov r0, r9 @ r0<- exception 16519 mov r1, rSELF @ r1<- self 16520 bl dvmReleaseTrackedAlloc @ release the exception 16521 b common_gotoBail @ bail out 16522 16523 16524 /* 16525 * Exception handling, calls through "glue code". 16526 */ 16527 .if 0 16528 .LexceptionOld: 16529 SAVE_PC_FP_TO_SELF() @ export state 16530 mov r0, rSELF @ arg to function 16531 bl dvmMterp_exceptionThrown 16532 b common_resumeAfterGlueCall 16533 .endif 16534 16535 #if defined(WITH_JIT) 16536 /* 16537 * If the JIT is actively building a trace we need to make sure 16538 * that the field is fully resolved before including the current 16539 * instruction. 16540 * 16541 * On entry: 16542 * r10: &dvmDex->pResFields[field] 16543 * r0: field pointer (must preserve) 16544 */ 16545 common_verifyField: 16546 ldrh r3, [rSELF, #offThread_subMode] @ r3 <- submode byte 16547 ands r3, #kSubModeJitTraceBuild 16548 bxeq lr @ Not building trace, continue 16549 ldr r1, [r10] @ r1<- reload resolved StaticField ptr 16550 cmp r1, #0 @ resolution complete? 16551 bxne lr @ yes, continue 16552 stmfd sp!, {r0-r2,lr} @ save regs 16553 mov r0, rSELF 16554 mov r1, rPC 16555 bl dvmJitEndTraceSelect @ (self,pc) end trace before this inst 16556 ldmfd sp!, {r0-r2, lr} 16557 bx lr @ return 16558 #endif 16559 16560 /* 16561 * After returning from a "glued" function, pull out the updated 16562 * values and start executing at the next instruction. 16563 */ 16564 common_resumeAfterGlueCall: 16565 LOAD_PC_FP_FROM_SELF() @ pull rPC and rFP out of thread 16566 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh 16567 FETCH_INST() @ load rINST from rPC 16568 GET_INST_OPCODE(ip) @ extract opcode from rINST 16569 GOTO_OPCODE(ip) @ jump to next instruction 16570 16571 /* 16572 * Invalid array index. Note that our calling convention is strange; we use r1 16573 * and r3 because those just happen to be the registers all our callers are 16574 * using. We move r3 before calling the C function, but r1 happens to match. 16575 * r1: index 16576 * r3: size 16577 */ 16578 common_errArrayIndex: 16579 EXPORT_PC() 16580 mov r0, r3 16581 bl dvmThrowArrayIndexOutOfBoundsException 16582 b common_exceptionThrown 16583 16584 /* 16585 * Integer divide or mod by zero. 16586 */ 16587 common_errDivideByZero: 16588 EXPORT_PC() 16589 ldr r0, strDivideByZero 16590 bl dvmThrowArithmeticException 16591 b common_exceptionThrown 16592 16593 /* 16594 * Attempt to allocate an array with a negative size. 16595 * On entry: length in r1 16596 */ 16597 common_errNegativeArraySize: 16598 EXPORT_PC() 16599 mov r0, r1 @ arg0 <- len 16600 bl dvmThrowNegativeArraySizeException @ (len) 16601 b common_exceptionThrown 16602 16603 /* 16604 * Invocation of a non-existent method. 16605 * On entry: method name in r1 16606 */ 16607 common_errNoSuchMethod: 16608 EXPORT_PC() 16609 mov r0, r1 16610 bl dvmThrowNoSuchMethodError 16611 b common_exceptionThrown 16612 16613 /* 16614 * We encountered a null object when we weren't expecting one. We 16615 * export the PC, throw a NullPointerException, and goto the exception 16616 * processing code. 16617 */ 16618 common_errNullObject: 16619 EXPORT_PC() 16620 mov r0, #0 16621 bl dvmThrowNullPointerException 16622 b common_exceptionThrown 16623 16624 /* 16625 * For debugging, cause an immediate fault. The source address will 16626 * be in lr (use a bl instruction to jump here). 16627 */ 16628 common_abort: 16629 ldr pc, .LdeadFood 16630 .LdeadFood: 16631 .word 0xdeadf00d 16632 16633 /* 16634 * Spit out a "we were here", preserving all registers. (The attempt 16635 * to save ip won't work, but we need to save an even number of 16636 * registers for EABI 64-bit stack alignment.) 16637 */ 16638 .macro SQUEAK num 16639 common_squeak\num: 16640 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16641 ldr r0, strSqueak 16642 mov r1, #\num 16643 bl printf 16644 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16645 bx lr 16646 .endm 16647 16648 SQUEAK 0 16649 SQUEAK 1 16650 SQUEAK 2 16651 SQUEAK 3 16652 SQUEAK 4 16653 SQUEAK 5 16654 16655 /* 16656 * Spit out the number in r0, preserving registers. 16657 */ 16658 common_printNum: 16659 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16660 mov r1, r0 16661 ldr r0, strSqueak 16662 bl printf 16663 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16664 bx lr 16665 16666 /* 16667 * Print a newline, preserving registers. 16668 */ 16669 common_printNewline: 16670 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16671 ldr r0, strNewline 16672 bl printf 16673 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16674 bx lr 16675 16676 /* 16677 * Print the 32-bit quantity in r0 as a hex value, preserving registers. 16678 */ 16679 common_printHex: 16680 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16681 mov r1, r0 16682 ldr r0, strPrintHex 16683 bl printf 16684 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16685 bx lr 16686 16687 /* 16688 * Print the 64-bit quantity in r0-r1, preserving registers. 16689 */ 16690 common_printLong: 16691 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16692 mov r3, r1 16693 mov r2, r0 16694 ldr r0, strPrintLong 16695 bl printf 16696 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16697 bx lr 16698 16699 /* 16700 * Print full method info. Pass the Method* in r0. Preserves regs. 16701 */ 16702 common_printMethod: 16703 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16704 bl dvmMterpPrintMethod 16705 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16706 bx lr 16707 16708 /* 16709 * Call a C helper function that dumps regs and possibly some 16710 * additional info. Requires the C function to be compiled in. 16711 */ 16712 .if 0 16713 common_dumpRegs: 16714 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16715 bl dvmMterpDumpArmRegs 16716 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16717 bx lr 16718 .endif 16719 16720 #if 0 16721 /* 16722 * Experiment on VFP mode. 16723 * 16724 * uint32_t setFPSCR(uint32_t val, uint32_t mask) 16725 * 16726 * Updates the bits specified by "mask", setting them to the values in "val". 16727 */ 16728 setFPSCR: 16729 and r0, r0, r1 @ make sure no stray bits are set 16730 fmrx r2, fpscr @ get VFP reg 16731 mvn r1, r1 @ bit-invert mask 16732 and r2, r2, r1 @ clear masked bits 16733 orr r2, r2, r0 @ set specified bits 16734 fmxr fpscr, r2 @ set VFP reg 16735 mov r0, r2 @ return new value 16736 bx lr 16737 16738 .align 2 16739 .global dvmConfigureFP 16740 .type dvmConfigureFP, %function 16741 dvmConfigureFP: 16742 stmfd sp!, {ip, lr} 16743 /* 0x03000000 sets DN/FZ */ 16744 /* 0x00009f00 clears the six exception enable flags */ 16745 bl common_squeak0 16746 mov r0, #0x03000000 @ r0<- 0x03000000 16747 add r1, r0, #0x9f00 @ r1<- 0x03009f00 16748 bl setFPSCR 16749 ldmfd sp!, {ip, pc} 16750 #endif 16751 16752 16753 /* 16754 * String references, must be close to the code that uses them. 16755 */ 16756 .align 2 16757 strDivideByZero: 16758 .word .LstrDivideByZero 16759 strLogTag: 16760 .word .LstrLogTag 16761 strExceptionNotCaughtLocally: 16762 .word .LstrExceptionNotCaughtLocally 16763 16764 strNewline: 16765 .word .LstrNewline 16766 strSqueak: 16767 .word .LstrSqueak 16768 strPrintHex: 16769 .word .LstrPrintHex 16770 strPrintLong: 16771 .word .LstrPrintLong 16772 16773 /* 16774 * Zero-terminated ASCII string data. 16775 * 16776 * On ARM we have two choices: do like gcc does, and LDR from a .word 16777 * with the address, or use an ADR pseudo-op to get the address 16778 * directly. ADR saves 4 bytes and an indirection, but it's using a 16779 * PC-relative addressing mode and hence has a limited range, which 16780 * makes it not work well with mergeable string sections. 16781 */ 16782 .section .rodata.str1.4,"aMS",%progbits,1 16783 16784 .LstrBadEntryPoint: 16785 .asciz "Bad entry point %d\n" 16786 .LstrFilledNewArrayNotImpl: 16787 .asciz "filled-new-array only implemented for objects and 'int'" 16788 .LstrDivideByZero: 16789 .asciz "divide by zero" 16790 .LstrLogTag: 16791 .asciz "mterp" 16792 .LstrExceptionNotCaughtLocally: 16793 .asciz "Exception %s from %s:%d not caught locally\n" 16794 16795 .LstrNewline: 16796 .asciz "\n" 16797 .LstrSqueak: 16798 .asciz "<%d>" 16799 .LstrPrintHex: 16800 .asciz "<%#x>" 16801 .LstrPrintLong: 16802 .asciz "<%lld>" 16803 16804