1 /* 2 * This file was generated automatically by gen-mterp.py for 'armv5te-vfp'. 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: armv5te/platform.S */ 206 /* 207 * =========================================================================== 208 * CPU-version-specific defines 209 * =========================================================================== 210 */ 211 212 /* 213 * Macro for data memory barrier; not meaningful pre-ARMv6K. 214 */ 215 .macro SMP_DMB 216 .endm 217 218 /* 219 * Macro for data memory barrier; not meaningful pre-ARMv6K. 220 */ 221 .macro SMP_DMB_ST 222 .endm 223 224 /* File: armv5te/entry.S */ 225 /* 226 * Copyright (C) 2008 The Android Open Source Project 227 * 228 * Licensed under the Apache License, Version 2.0 (the "License"); 229 * you may not use this file except in compliance with the License. 230 * You may obtain a copy of the License at 231 * 232 * http://www.apache.org/licenses/LICENSE-2.0 233 * 234 * Unless required by applicable law or agreed to in writing, software 235 * distributed under the License is distributed on an "AS IS" BASIS, 236 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 237 * See the License for the specific language governing permissions and 238 * limitations under the License. 239 */ 240 /* 241 * Interpreter entry point. 242 */ 243 244 /* 245 * We don't have formal stack frames, so gdb scans upward in the code 246 * to find the start of the function (a label with the %function type), 247 * and then looks at the next few instructions to figure out what 248 * got pushed onto the stack. From this it figures out how to restore 249 * the registers, including PC, for the previous stack frame. If gdb 250 * sees a non-function label, it stops scanning, so either we need to 251 * have nothing but assembler-local labels between the entry point and 252 * the break, or we need to fake it out. 253 * 254 * When this is defined, we add some stuff to make gdb less confused. 255 */ 256 #define ASSIST_DEBUGGER 1 257 258 .text 259 .align 2 260 .global dvmMterpStdRun 261 .type dvmMterpStdRun, %function 262 263 /* 264 * On entry: 265 * r0 Thread* self 266 * 267 * The return comes via a call to dvmMterpStdBail(). 268 */ 269 dvmMterpStdRun: 270 #define MTERP_ENTRY1 \ 271 .save {r4-r10,fp,lr}; \ 272 stmfd sp!, {r4-r10,fp,lr} @ save 9 regs 273 #define MTERP_ENTRY2 \ 274 .pad #4; \ 275 sub sp, sp, #4 @ align 64 276 277 .fnstart 278 MTERP_ENTRY1 279 MTERP_ENTRY2 280 281 /* save stack pointer, add magic word for debuggerd */ 282 str sp, [r0, #offThread_bailPtr] @ save SP for eventual return 283 284 /* set up "named" registers, figure out entry point */ 285 mov rSELF, r0 @ set rSELF 286 LOAD_PC_FP_FROM_SELF() @ load rPC and rFP from "thread" 287 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ set rIBASE 288 289 #if defined(WITH_JIT) 290 .LentryInstr: 291 /* Entry is always a possible trace start */ 292 ldr r0, [rSELF, #offThread_pJitProfTable] 293 FETCH_INST() 294 mov r1, #0 @ prepare the value for the new state 295 str r1, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 296 cmp r0,#0 @ is profiling disabled? 297 #if !defined(WITH_SELF_VERIFICATION) 298 bne common_updateProfile @ profiling is enabled 299 #else 300 ldr r2, [rSELF, #offThread_shadowSpace] @ to find out the jit exit state 301 beq 1f @ profiling is disabled 302 ldr r3, [r2, #offShadowSpace_jitExitState] @ jit exit state 303 cmp r3, #kSVSTraceSelect @ hot trace following? 304 moveq r2,#kJitTSelectRequestHot @ ask for trace selection 305 beq common_selectTrace @ go build the trace 306 cmp r3, #kSVSNoProfile @ don't profile the next instruction? 307 beq 1f @ intrepret the next instruction 308 b common_updateProfile @ collect profiles 309 #endif 310 1: 311 GET_INST_OPCODE(ip) 312 GOTO_OPCODE(ip) 313 #else 314 /* start executing the instruction at rPC */ 315 FETCH_INST() @ load rINST from rPC 316 GET_INST_OPCODE(ip) @ extract opcode from rINST 317 GOTO_OPCODE(ip) @ jump to next instruction 318 #endif 319 320 .Lbad_arg: 321 ldr r0, strBadEntryPoint 322 @ r1 holds value of entryPoint 323 bl printf 324 bl dvmAbort 325 .fnend 326 .size dvmMterpStdRun, .-dvmMterpStdRun 327 328 329 .global dvmMterpStdBail 330 .type dvmMterpStdBail, %function 331 332 /* 333 * Restore the stack pointer and PC from the save point established on entry. 334 * This is essentially the same as a longjmp, but should be cheaper. The 335 * last instruction causes us to return to whoever called dvmMterpStdRun. 336 * 337 * We pushed some registers on the stack in dvmMterpStdRun, then saved 338 * SP and LR. Here we restore SP, restore the registers, and then restore 339 * LR to PC. 340 * 341 * On entry: 342 * r0 Thread* self 343 */ 344 dvmMterpStdBail: 345 ldr sp, [r0, #offThread_bailPtr] @ sp<- saved SP 346 add sp, sp, #4 @ un-align 64 347 ldmfd sp!, {r4-r10,fp,pc} @ restore 9 regs and return 348 349 350 /* 351 * String references. 352 */ 353 strBadEntryPoint: 354 .word .LstrBadEntryPoint 355 356 357 .global dvmAsmInstructionStart 358 .type dvmAsmInstructionStart, %function 359 dvmAsmInstructionStart = .L_OP_NOP 360 .text 361 362 /* ------------------------------ */ 363 .balign 64 364 .L_OP_NOP: /* 0x00 */ 365 /* File: armv5te/OP_NOP.S */ 366 FETCH_ADVANCE_INST(1) @ advance to next instr, load rINST 367 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 368 GOTO_OPCODE(ip) @ execute it 369 370 #ifdef ASSIST_DEBUGGER 371 /* insert fake function header to help gdb find the stack frame */ 372 .type dalvik_inst, %function 373 dalvik_inst: 374 .fnstart 375 MTERP_ENTRY1 376 MTERP_ENTRY2 377 .fnend 378 #endif 379 380 /* ------------------------------ */ 381 .balign 64 382 .L_OP_MOVE: /* 0x01 */ 383 /* File: armv5te/OP_MOVE.S */ 384 /* for move, move-object, long-to-int */ 385 /* op vA, vB */ 386 mov r1, rINST, lsr #12 @ r1<- B from 15:12 387 mov r0, rINST, lsr #8 @ r0<- A from 11:8 388 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 389 GET_VREG(r2, r1) @ r2<- fp[B] 390 and r0, r0, #15 391 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 392 SET_VREG(r2, r0) @ fp[A]<- r2 393 GOTO_OPCODE(ip) @ execute next instruction 394 395 /* ------------------------------ */ 396 .balign 64 397 .L_OP_MOVE_FROM16: /* 0x02 */ 398 /* File: armv5te/OP_MOVE_FROM16.S */ 399 /* for: move/from16, move-object/from16 */ 400 /* op vAA, vBBBB */ 401 FETCH(r1, 1) @ r1<- BBBB 402 mov r0, rINST, lsr #8 @ r0<- AA 403 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 404 GET_VREG(r2, r1) @ r2<- fp[BBBB] 405 GET_INST_OPCODE(ip) @ extract opcode from rINST 406 SET_VREG(r2, r0) @ fp[AA]<- r2 407 GOTO_OPCODE(ip) @ jump to next instruction 408 409 /* ------------------------------ */ 410 .balign 64 411 .L_OP_MOVE_16: /* 0x03 */ 412 /* File: armv5te/OP_MOVE_16.S */ 413 /* for: move/16, move-object/16 */ 414 /* op vAAAA, vBBBB */ 415 FETCH(r1, 2) @ r1<- BBBB 416 FETCH(r0, 1) @ r0<- AAAA 417 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 418 GET_VREG(r2, r1) @ r2<- fp[BBBB] 419 GET_INST_OPCODE(ip) @ extract opcode from rINST 420 SET_VREG(r2, r0) @ fp[AAAA]<- r2 421 GOTO_OPCODE(ip) @ jump to next instruction 422 423 /* ------------------------------ */ 424 .balign 64 425 .L_OP_MOVE_WIDE: /* 0x04 */ 426 /* File: armv5te/OP_MOVE_WIDE.S */ 427 /* move-wide vA, vB */ 428 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 429 mov r2, rINST, lsr #8 @ r2<- A(+) 430 mov r3, rINST, lsr #12 @ r3<- B 431 and r2, r2, #15 432 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 433 add r2, rFP, r2, lsl #2 @ r2<- &fp[A] 434 ldmia r3, {r0-r1} @ r0/r1<- fp[B] 435 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 436 GET_INST_OPCODE(ip) @ extract opcode from rINST 437 stmia r2, {r0-r1} @ fp[A]<- r0/r1 438 GOTO_OPCODE(ip) @ jump to next instruction 439 440 /* ------------------------------ */ 441 .balign 64 442 .L_OP_MOVE_WIDE_FROM16: /* 0x05 */ 443 /* File: armv5te/OP_MOVE_WIDE_FROM16.S */ 444 /* move-wide/from16 vAA, vBBBB */ 445 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 446 FETCH(r3, 1) @ r3<- BBBB 447 mov r2, rINST, lsr #8 @ r2<- AA 448 add r3, rFP, r3, lsl #2 @ r3<- &fp[BBBB] 449 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 450 ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB] 451 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 452 GET_INST_OPCODE(ip) @ extract opcode from rINST 453 stmia r2, {r0-r1} @ fp[AA]<- r0/r1 454 GOTO_OPCODE(ip) @ jump to next instruction 455 456 /* ------------------------------ */ 457 .balign 64 458 .L_OP_MOVE_WIDE_16: /* 0x06 */ 459 /* File: armv5te/OP_MOVE_WIDE_16.S */ 460 /* move-wide/16 vAAAA, vBBBB */ 461 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 462 FETCH(r3, 2) @ r3<- BBBB 463 FETCH(r2, 1) @ r2<- AAAA 464 add r3, rFP, r3, lsl #2 @ r3<- &fp[BBBB] 465 add r2, rFP, r2, lsl #2 @ r2<- &fp[AAAA] 466 ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB] 467 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 468 GET_INST_OPCODE(ip) @ extract opcode from rINST 469 stmia r2, {r0-r1} @ fp[AAAA]<- r0/r1 470 GOTO_OPCODE(ip) @ jump to next instruction 471 472 /* ------------------------------ */ 473 .balign 64 474 .L_OP_MOVE_OBJECT: /* 0x07 */ 475 /* File: armv5te/OP_MOVE_OBJECT.S */ 476 /* File: armv5te/OP_MOVE.S */ 477 /* for move, move-object, long-to-int */ 478 /* op vA, vB */ 479 mov r1, rINST, lsr #12 @ r1<- B from 15:12 480 mov r0, rINST, lsr #8 @ r0<- A from 11:8 481 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 482 GET_VREG(r2, r1) @ r2<- fp[B] 483 and r0, r0, #15 484 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 485 SET_VREG(r2, r0) @ fp[A]<- r2 486 GOTO_OPCODE(ip) @ execute next instruction 487 488 489 /* ------------------------------ */ 490 .balign 64 491 .L_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 492 /* File: armv5te/OP_MOVE_OBJECT_FROM16.S */ 493 /* File: armv5te/OP_MOVE_FROM16.S */ 494 /* for: move/from16, move-object/from16 */ 495 /* op vAA, vBBBB */ 496 FETCH(r1, 1) @ r1<- BBBB 497 mov r0, rINST, lsr #8 @ r0<- AA 498 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 499 GET_VREG(r2, r1) @ r2<- fp[BBBB] 500 GET_INST_OPCODE(ip) @ extract opcode from rINST 501 SET_VREG(r2, r0) @ fp[AA]<- r2 502 GOTO_OPCODE(ip) @ jump to next instruction 503 504 505 /* ------------------------------ */ 506 .balign 64 507 .L_OP_MOVE_OBJECT_16: /* 0x09 */ 508 /* File: armv5te/OP_MOVE_OBJECT_16.S */ 509 /* File: armv5te/OP_MOVE_16.S */ 510 /* for: move/16, move-object/16 */ 511 /* op vAAAA, vBBBB */ 512 FETCH(r1, 2) @ r1<- BBBB 513 FETCH(r0, 1) @ r0<- AAAA 514 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 515 GET_VREG(r2, r1) @ r2<- fp[BBBB] 516 GET_INST_OPCODE(ip) @ extract opcode from rINST 517 SET_VREG(r2, r0) @ fp[AAAA]<- r2 518 GOTO_OPCODE(ip) @ jump to next instruction 519 520 521 /* ------------------------------ */ 522 .balign 64 523 .L_OP_MOVE_RESULT: /* 0x0a */ 524 /* File: armv5te/OP_MOVE_RESULT.S */ 525 /* for: move-result, move-result-object */ 526 /* op vAA */ 527 mov r2, rINST, lsr #8 @ r2<- AA 528 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 529 ldr r0, [rSELF, #offThread_retval] @ r0<- self->retval.i 530 GET_INST_OPCODE(ip) @ extract opcode from rINST 531 SET_VREG(r0, r2) @ fp[AA]<- r0 532 GOTO_OPCODE(ip) @ jump to next instruction 533 534 /* ------------------------------ */ 535 .balign 64 536 .L_OP_MOVE_RESULT_WIDE: /* 0x0b */ 537 /* File: armv5te/OP_MOVE_RESULT_WIDE.S */ 538 /* move-result-wide vAA */ 539 mov r2, rINST, lsr #8 @ r2<- AA 540 add r3, rSELF, #offThread_retval @ r3<- &self->retval 541 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 542 ldmia r3, {r0-r1} @ r0/r1<- retval.j 543 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 544 GET_INST_OPCODE(ip) @ extract opcode from rINST 545 stmia r2, {r0-r1} @ fp[AA]<- r0/r1 546 GOTO_OPCODE(ip) @ jump to next instruction 547 548 /* ------------------------------ */ 549 .balign 64 550 .L_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 551 /* File: armv5te/OP_MOVE_RESULT_OBJECT.S */ 552 /* File: armv5te/OP_MOVE_RESULT.S */ 553 /* for: move-result, move-result-object */ 554 /* op vAA */ 555 mov r2, rINST, lsr #8 @ r2<- AA 556 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 557 ldr r0, [rSELF, #offThread_retval] @ r0<- self->retval.i 558 GET_INST_OPCODE(ip) @ extract opcode from rINST 559 SET_VREG(r0, r2) @ fp[AA]<- r0 560 GOTO_OPCODE(ip) @ jump to next instruction 561 562 563 /* ------------------------------ */ 564 .balign 64 565 .L_OP_MOVE_EXCEPTION: /* 0x0d */ 566 /* File: armv5te/OP_MOVE_EXCEPTION.S */ 567 /* move-exception vAA */ 568 mov r2, rINST, lsr #8 @ r2<- AA 569 ldr r3, [rSELF, #offThread_exception] @ r3<- dvmGetException bypass 570 mov r1, #0 @ r1<- 0 571 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 572 SET_VREG(r3, r2) @ fp[AA]<- exception obj 573 GET_INST_OPCODE(ip) @ extract opcode from rINST 574 str r1, [rSELF, #offThread_exception] @ dvmClearException bypass 575 GOTO_OPCODE(ip) @ jump to next instruction 576 577 /* ------------------------------ */ 578 .balign 64 579 .L_OP_RETURN_VOID: /* 0x0e */ 580 /* File: armv5te/OP_RETURN_VOID.S */ 581 b common_returnFromMethod 582 583 /* ------------------------------ */ 584 .balign 64 585 .L_OP_RETURN: /* 0x0f */ 586 /* File: armv5te/OP_RETURN.S */ 587 /* 588 * Return a 32-bit value. Copies the return value into the "thread" 589 * structure, then jumps to the return handler. 590 * 591 * for: return, return-object 592 */ 593 /* op vAA */ 594 mov r2, rINST, lsr #8 @ r2<- AA 595 GET_VREG(r0, r2) @ r0<- vAA 596 str r0, [rSELF, #offThread_retval] @ retval.i <- vAA 597 b common_returnFromMethod 598 599 /* ------------------------------ */ 600 .balign 64 601 .L_OP_RETURN_WIDE: /* 0x10 */ 602 /* File: armv5te/OP_RETURN_WIDE.S */ 603 /* 604 * Return a 64-bit value. Copies the return value into the "thread" 605 * structure, then jumps to the return handler. 606 */ 607 /* return-wide vAA */ 608 mov r2, rINST, lsr #8 @ r2<- AA 609 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 610 add r3, rSELF, #offThread_retval @ r3<- &self->retval 611 ldmia r2, {r0-r1} @ r0/r1 <- vAA/vAA+1 612 stmia r3, {r0-r1} @ retval<- r0/r1 613 b common_returnFromMethod 614 615 /* ------------------------------ */ 616 .balign 64 617 .L_OP_RETURN_OBJECT: /* 0x11 */ 618 /* File: armv5te/OP_RETURN_OBJECT.S */ 619 /* File: armv5te/OP_RETURN.S */ 620 /* 621 * Return a 32-bit value. Copies the return value into the "thread" 622 * structure, then jumps to the return handler. 623 * 624 * for: return, return-object 625 */ 626 /* op vAA */ 627 mov r2, rINST, lsr #8 @ r2<- AA 628 GET_VREG(r0, r2) @ r0<- vAA 629 str r0, [rSELF, #offThread_retval] @ retval.i <- vAA 630 b common_returnFromMethod 631 632 633 /* ------------------------------ */ 634 .balign 64 635 .L_OP_CONST_4: /* 0x12 */ 636 /* File: armv5te/OP_CONST_4.S */ 637 /* const/4 vA, #+B */ 638 mov r1, rINST, lsl #16 @ r1<- Bxxx0000 639 mov r0, rINST, lsr #8 @ r0<- A+ 640 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 641 mov r1, r1, asr #28 @ r1<- sssssssB (sign-extended) 642 and r0, r0, #15 643 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 644 SET_VREG(r1, r0) @ fp[A]<- r1 645 GOTO_OPCODE(ip) @ execute next instruction 646 647 /* ------------------------------ */ 648 .balign 64 649 .L_OP_CONST_16: /* 0x13 */ 650 /* File: armv5te/OP_CONST_16.S */ 651 /* const/16 vAA, #+BBBB */ 652 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 653 mov r3, rINST, lsr #8 @ r3<- AA 654 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 655 SET_VREG(r0, r3) @ vAA<- r0 656 GET_INST_OPCODE(ip) @ extract opcode from rINST 657 GOTO_OPCODE(ip) @ jump to next instruction 658 659 /* ------------------------------ */ 660 .balign 64 661 .L_OP_CONST: /* 0x14 */ 662 /* File: armv5te/OP_CONST.S */ 663 /* const vAA, #+BBBBbbbb */ 664 mov r3, rINST, lsr #8 @ r3<- AA 665 FETCH(r0, 1) @ r0<- bbbb (low) 666 FETCH(r1, 2) @ r1<- BBBB (high) 667 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 668 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 669 GET_INST_OPCODE(ip) @ extract opcode from rINST 670 SET_VREG(r0, r3) @ vAA<- r0 671 GOTO_OPCODE(ip) @ jump to next instruction 672 673 /* ------------------------------ */ 674 .balign 64 675 .L_OP_CONST_HIGH16: /* 0x15 */ 676 /* File: armv5te/OP_CONST_HIGH16.S */ 677 /* const/high16 vAA, #+BBBB0000 */ 678 FETCH(r0, 1) @ r0<- 0000BBBB (zero-extended) 679 mov r3, rINST, lsr #8 @ r3<- AA 680 mov r0, r0, lsl #16 @ r0<- BBBB0000 681 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 682 SET_VREG(r0, r3) @ vAA<- r0 683 GET_INST_OPCODE(ip) @ extract opcode from rINST 684 GOTO_OPCODE(ip) @ jump to next instruction 685 686 /* ------------------------------ */ 687 .balign 64 688 .L_OP_CONST_WIDE_16: /* 0x16 */ 689 /* File: armv5te/OP_CONST_WIDE_16.S */ 690 /* const-wide/16 vAA, #+BBBB */ 691 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 692 mov r3, rINST, lsr #8 @ r3<- AA 693 mov r1, r0, asr #31 @ r1<- ssssssss 694 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 695 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 696 GET_INST_OPCODE(ip) @ extract opcode from rINST 697 stmia r3, {r0-r1} @ vAA<- r0/r1 698 GOTO_OPCODE(ip) @ jump to next instruction 699 700 /* ------------------------------ */ 701 .balign 64 702 .L_OP_CONST_WIDE_32: /* 0x17 */ 703 /* File: armv5te/OP_CONST_WIDE_32.S */ 704 /* const-wide/32 vAA, #+BBBBbbbb */ 705 FETCH(r0, 1) @ r0<- 0000bbbb (low) 706 mov r3, rINST, lsr #8 @ r3<- AA 707 FETCH_S(r2, 2) @ r2<- ssssBBBB (high) 708 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 709 orr r0, r0, r2, lsl #16 @ r0<- BBBBbbbb 710 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 711 mov r1, r0, asr #31 @ r1<- ssssssss 712 GET_INST_OPCODE(ip) @ extract opcode from rINST 713 stmia r3, {r0-r1} @ vAA<- r0/r1 714 GOTO_OPCODE(ip) @ jump to next instruction 715 716 /* ------------------------------ */ 717 .balign 64 718 .L_OP_CONST_WIDE: /* 0x18 */ 719 /* File: armv5te/OP_CONST_WIDE.S */ 720 /* const-wide vAA, #+HHHHhhhhBBBBbbbb */ 721 FETCH(r0, 1) @ r0<- bbbb (low) 722 FETCH(r1, 2) @ r1<- BBBB (low middle) 723 FETCH(r2, 3) @ r2<- hhhh (high middle) 724 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb (low word) 725 FETCH(r3, 4) @ r3<- HHHH (high) 726 mov r9, rINST, lsr #8 @ r9<- AA 727 orr r1, r2, r3, lsl #16 @ r1<- HHHHhhhh (high word) 728 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 729 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 730 GET_INST_OPCODE(ip) @ extract opcode from rINST 731 stmia r9, {r0-r1} @ vAA<- r0/r1 732 GOTO_OPCODE(ip) @ jump to next instruction 733 734 /* ------------------------------ */ 735 .balign 64 736 .L_OP_CONST_WIDE_HIGH16: /* 0x19 */ 737 /* File: armv5te/OP_CONST_WIDE_HIGH16.S */ 738 /* const-wide/high16 vAA, #+BBBB000000000000 */ 739 FETCH(r1, 1) @ r1<- 0000BBBB (zero-extended) 740 mov r3, rINST, lsr #8 @ r3<- AA 741 mov r0, #0 @ r0<- 00000000 742 mov r1, r1, lsl #16 @ r1<- BBBB0000 743 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 744 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 745 GET_INST_OPCODE(ip) @ extract opcode from rINST 746 stmia r3, {r0-r1} @ vAA<- r0/r1 747 GOTO_OPCODE(ip) @ jump to next instruction 748 749 /* ------------------------------ */ 750 .balign 64 751 .L_OP_CONST_STRING: /* 0x1a */ 752 /* File: armv5te/OP_CONST_STRING.S */ 753 /* const/string vAA, String@BBBB */ 754 FETCH(r1, 1) @ r1<- BBBB 755 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 756 mov r9, rINST, lsr #8 @ r9<- AA 757 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 758 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 759 cmp r0, #0 @ not yet resolved? 760 beq .LOP_CONST_STRING_resolve 761 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 762 GET_INST_OPCODE(ip) @ extract opcode from rINST 763 SET_VREG(r0, r9) @ vAA<- r0 764 GOTO_OPCODE(ip) @ jump to next instruction 765 766 /* ------------------------------ */ 767 .balign 64 768 .L_OP_CONST_STRING_JUMBO: /* 0x1b */ 769 /* File: armv5te/OP_CONST_STRING_JUMBO.S */ 770 /* const/string vAA, String@BBBBBBBB */ 771 FETCH(r0, 1) @ r0<- bbbb (low) 772 FETCH(r1, 2) @ r1<- BBBB (high) 773 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 774 mov r9, rINST, lsr #8 @ r9<- AA 775 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 776 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 777 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 778 cmp r0, #0 779 beq .LOP_CONST_STRING_JUMBO_resolve 780 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 781 GET_INST_OPCODE(ip) @ extract opcode from rINST 782 SET_VREG(r0, r9) @ vAA<- r0 783 GOTO_OPCODE(ip) @ jump to next instruction 784 785 /* ------------------------------ */ 786 .balign 64 787 .L_OP_CONST_CLASS: /* 0x1c */ 788 /* File: armv5te/OP_CONST_CLASS.S */ 789 /* const/class vAA, Class@BBBB */ 790 FETCH(r1, 1) @ r1<- BBBB 791 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 792 mov r9, rINST, lsr #8 @ r9<- AA 793 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- dvmDex->pResClasses 794 ldr r0, [r2, r1, lsl #2] @ r0<- pResClasses[BBBB] 795 cmp r0, #0 @ not yet resolved? 796 beq .LOP_CONST_CLASS_resolve 797 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 798 GET_INST_OPCODE(ip) @ extract opcode from rINST 799 SET_VREG(r0, r9) @ vAA<- r0 800 GOTO_OPCODE(ip) @ jump to next instruction 801 802 /* ------------------------------ */ 803 .balign 64 804 .L_OP_MONITOR_ENTER: /* 0x1d */ 805 /* File: armv5te/OP_MONITOR_ENTER.S */ 806 /* 807 * Synchronize on an object. 808 */ 809 /* monitor-enter vAA */ 810 mov r2, rINST, lsr #8 @ r2<- AA 811 GET_VREG(r1, r2) @ r1<- vAA (object) 812 mov r0, rSELF @ r0<- self 813 cmp r1, #0 @ null object? 814 EXPORT_PC() @ need for precise GC 815 beq common_errNullObject @ null object, throw an exception 816 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 817 bl dvmLockObject @ call(self, obj) 818 GET_INST_OPCODE(ip) @ extract opcode from rINST 819 GOTO_OPCODE(ip) @ jump to next instruction 820 821 /* ------------------------------ */ 822 .balign 64 823 .L_OP_MONITOR_EXIT: /* 0x1e */ 824 /* File: armv5te/OP_MONITOR_EXIT.S */ 825 /* 826 * Unlock an object. 827 * 828 * Exceptions that occur when unlocking a monitor need to appear as 829 * if they happened at the following instruction. See the Dalvik 830 * instruction spec. 831 */ 832 /* monitor-exit vAA */ 833 mov r2, rINST, lsr #8 @ r2<- AA 834 EXPORT_PC() @ before fetch: export the PC 835 GET_VREG(r1, r2) @ r1<- vAA (object) 836 cmp r1, #0 @ null object? 837 beq 1f @ yes 838 mov r0, rSELF @ r0<- self 839 bl dvmUnlockObject @ r0<- success for unlock(self, obj) 840 cmp r0, #0 @ failed? 841 FETCH_ADVANCE_INST(1) @ before throw: advance rPC, load rINST 842 beq common_exceptionThrown @ yes, exception is pending 843 GET_INST_OPCODE(ip) @ extract opcode from rINST 844 GOTO_OPCODE(ip) @ jump to next instruction 845 1: 846 FETCH_ADVANCE_INST(1) @ advance before throw 847 b common_errNullObject 848 849 /* ------------------------------ */ 850 .balign 64 851 .L_OP_CHECK_CAST: /* 0x1f */ 852 /* File: armv5te/OP_CHECK_CAST.S */ 853 /* 854 * Check to see if a cast from one class to another is allowed. 855 */ 856 /* check-cast vAA, class@BBBB */ 857 mov r3, rINST, lsr #8 @ r3<- AA 858 FETCH(r2, 1) @ r2<- BBBB 859 GET_VREG(r9, r3) @ r9<- object 860 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- pDvmDex 861 cmp r9, #0 @ is object null? 862 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 863 beq .LOP_CHECK_CAST_okay @ null obj, cast always succeeds 864 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 865 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 866 cmp r1, #0 @ have we resolved this before? 867 beq .LOP_CHECK_CAST_resolve @ not resolved, do it now 868 .LOP_CHECK_CAST_resolved: 869 cmp r0, r1 @ same class (trivial success)? 870 bne .LOP_CHECK_CAST_fullcheck @ no, do full check 871 .LOP_CHECK_CAST_okay: 872 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 873 GET_INST_OPCODE(ip) @ extract opcode from rINST 874 GOTO_OPCODE(ip) @ jump to next instruction 875 876 /* ------------------------------ */ 877 .balign 64 878 .L_OP_INSTANCE_OF: /* 0x20 */ 879 /* File: armv5te/OP_INSTANCE_OF.S */ 880 /* 881 * Check to see if an object reference is an instance of a class. 882 * 883 * Most common situation is a non-null object, being compared against 884 * an already-resolved class. 885 */ 886 /* instance-of vA, vB, class@CCCC */ 887 mov r3, rINST, lsr #12 @ r3<- B 888 mov r9, rINST, lsr #8 @ r9<- A+ 889 GET_VREG(r0, r3) @ r0<- vB (object) 890 and r9, r9, #15 @ r9<- A 891 cmp r0, #0 @ is object null? 892 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- pDvmDex 893 beq .LOP_INSTANCE_OF_store @ null obj, not an instance, store r0 894 FETCH(r3, 1) @ r3<- CCCC 895 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 896 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 897 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 898 cmp r1, #0 @ have we resolved this before? 899 beq .LOP_INSTANCE_OF_resolve @ not resolved, do it now 900 .LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class 901 cmp r0, r1 @ same class (trivial success)? 902 beq .LOP_INSTANCE_OF_trivial @ yes, trivial finish 903 b .LOP_INSTANCE_OF_fullcheck @ no, do full check 904 905 /* ------------------------------ */ 906 .balign 64 907 .L_OP_ARRAY_LENGTH: /* 0x21 */ 908 /* File: armv5te/OP_ARRAY_LENGTH.S */ 909 /* 910 * Return the length of an array. 911 */ 912 mov r1, rINST, lsr #12 @ r1<- B 913 mov r2, rINST, lsr #8 @ r2<- A+ 914 GET_VREG(r0, r1) @ r0<- vB (object ref) 915 and r2, r2, #15 @ r2<- A 916 cmp r0, #0 @ is object null? 917 beq common_errNullObject @ yup, fail 918 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 919 ldr r3, [r0, #offArrayObject_length] @ r3<- array length 920 GET_INST_OPCODE(ip) @ extract opcode from rINST 921 SET_VREG(r3, r2) @ vB<- length 922 GOTO_OPCODE(ip) @ jump to next instruction 923 924 /* ------------------------------ */ 925 .balign 64 926 .L_OP_NEW_INSTANCE: /* 0x22 */ 927 /* File: armv5te/OP_NEW_INSTANCE.S */ 928 /* 929 * Create a new instance of a class. 930 */ 931 /* new-instance vAA, class@BBBB */ 932 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 933 FETCH(r1, 1) @ r1<- BBBB 934 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 935 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 936 #if defined(WITH_JIT) 937 add r10, r3, r1, lsl #2 @ r10<- &resolved_class 938 #endif 939 EXPORT_PC() @ req'd for init, resolve, alloc 940 cmp r0, #0 @ already resolved? 941 beq .LOP_NEW_INSTANCE_resolve @ no, resolve it now 942 .LOP_NEW_INSTANCE_resolved: @ r0=class 943 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 944 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 945 bne .LOP_NEW_INSTANCE_needinit @ no, init class now 946 .LOP_NEW_INSTANCE_initialized: @ r0=class 947 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 948 bl dvmAllocObject @ r0<- new object 949 b .LOP_NEW_INSTANCE_finish @ continue 950 951 /* ------------------------------ */ 952 .balign 64 953 .L_OP_NEW_ARRAY: /* 0x23 */ 954 /* File: armv5te/OP_NEW_ARRAY.S */ 955 /* 956 * Allocate an array of objects, specified with the array class 957 * and a count. 958 * 959 * The verifier guarantees that this is an array class, so we don't 960 * check for it here. 961 */ 962 /* new-array vA, vB, class@CCCC */ 963 mov r0, rINST, lsr #12 @ r0<- B 964 FETCH(r2, 1) @ r2<- CCCC 965 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 966 GET_VREG(r1, r0) @ r1<- vB (array length) 967 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 968 cmp r1, #0 @ check length 969 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 970 bmi common_errNegativeArraySize @ negative length, bail - len in r1 971 cmp r0, #0 @ already resolved? 972 EXPORT_PC() @ req'd for resolve, alloc 973 bne .LOP_NEW_ARRAY_finish @ resolved, continue 974 b .LOP_NEW_ARRAY_resolve @ do resolve now 975 976 /* ------------------------------ */ 977 .balign 64 978 .L_OP_FILLED_NEW_ARRAY: /* 0x24 */ 979 /* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 980 /* 981 * Create a new array with elements filled from registers. 982 * 983 * for: filled-new-array, filled-new-array/range 984 */ 985 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 986 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 987 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 988 FETCH(r1, 1) @ r1<- BBBB 989 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 990 EXPORT_PC() @ need for resolve and alloc 991 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 992 mov r10, rINST, lsr #8 @ r10<- AA or BA 993 cmp r0, #0 @ already resolved? 994 bne .LOP_FILLED_NEW_ARRAY_continue @ yes, continue on 995 8: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 996 mov r2, #0 @ r2<- false 997 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 998 bl dvmResolveClass @ r0<- call(clazz, ref) 999 cmp r0, #0 @ got null? 1000 beq common_exceptionThrown @ yes, handle exception 1001 b .LOP_FILLED_NEW_ARRAY_continue 1002 1003 /* ------------------------------ */ 1004 .balign 64 1005 .L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 1006 /* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */ 1007 /* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1008 /* 1009 * Create a new array with elements filled from registers. 1010 * 1011 * for: filled-new-array, filled-new-array/range 1012 */ 1013 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1014 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1015 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 1016 FETCH(r1, 1) @ r1<- BBBB 1017 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1018 EXPORT_PC() @ need for resolve and alloc 1019 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1020 mov r10, rINST, lsr #8 @ r10<- AA or BA 1021 cmp r0, #0 @ already resolved? 1022 bne .LOP_FILLED_NEW_ARRAY_RANGE_continue @ yes, continue on 1023 8: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 1024 mov r2, #0 @ r2<- false 1025 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1026 bl dvmResolveClass @ r0<- call(clazz, ref) 1027 cmp r0, #0 @ got null? 1028 beq common_exceptionThrown @ yes, handle exception 1029 b .LOP_FILLED_NEW_ARRAY_RANGE_continue 1030 1031 1032 /* ------------------------------ */ 1033 .balign 64 1034 .L_OP_FILL_ARRAY_DATA: /* 0x26 */ 1035 /* File: armv5te/OP_FILL_ARRAY_DATA.S */ 1036 /* fill-array-data vAA, +BBBBBBBB */ 1037 FETCH(r0, 1) @ r0<- bbbb (lo) 1038 FETCH(r1, 2) @ r1<- BBBB (hi) 1039 mov r3, rINST, lsr #8 @ r3<- AA 1040 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 1041 GET_VREG(r0, r3) @ r0<- vAA (array object) 1042 add r1, rPC, r1, lsl #1 @ r1<- PC + BBBBbbbb*2 (array data off.) 1043 EXPORT_PC(); 1044 bl dvmInterpHandleFillArrayData@ fill the array with predefined data 1045 cmp r0, #0 @ 0 means an exception is thrown 1046 beq common_exceptionThrown @ has exception 1047 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 1048 GET_INST_OPCODE(ip) @ extract opcode from rINST 1049 GOTO_OPCODE(ip) @ jump to next instruction 1050 1051 /* ------------------------------ */ 1052 .balign 64 1053 .L_OP_THROW: /* 0x27 */ 1054 /* File: armv5te/OP_THROW.S */ 1055 /* 1056 * Throw an exception object in the current thread. 1057 */ 1058 /* throw vAA */ 1059 mov r2, rINST, lsr #8 @ r2<- AA 1060 GET_VREG(r1, r2) @ r1<- vAA (exception object) 1061 EXPORT_PC() @ exception handler can throw 1062 cmp r1, #0 @ null object? 1063 beq common_errNullObject @ yes, throw an NPE instead 1064 @ bypass dvmSetException, just store it 1065 str r1, [rSELF, #offThread_exception] @ thread->exception<- obj 1066 b common_exceptionThrown 1067 1068 /* ------------------------------ */ 1069 .balign 64 1070 .L_OP_GOTO: /* 0x28 */ 1071 /* File: armv5te/OP_GOTO.S */ 1072 /* 1073 * Unconditional branch, 8-bit offset. 1074 * 1075 * The branch distance is a signed code-unit offset, which we need to 1076 * double to get a byte offset. 1077 */ 1078 /* goto +AA */ 1079 /* tuning: use sbfx for 6t2+ targets */ 1080 mov r0, rINST, lsl #16 @ r0<- AAxx0000 1081 movs r1, r0, asr #24 @ r1<- ssssssAA (sign-extended) 1082 add r2, r1, r1 @ r2<- byte offset, set flags 1083 @ If backwards branch refresh rIBASE 1084 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1085 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1086 #if defined(WITH_JIT) 1087 ldr r0, [rSELF, #offThread_pJitProfTable] 1088 bmi common_testUpdateProfile @ (r0) check for trace hotness 1089 #endif 1090 GET_INST_OPCODE(ip) @ extract opcode from rINST 1091 GOTO_OPCODE(ip) @ jump to next instruction 1092 1093 /* ------------------------------ */ 1094 .balign 64 1095 .L_OP_GOTO_16: /* 0x29 */ 1096 /* File: armv5te/OP_GOTO_16.S */ 1097 /* 1098 * Unconditional branch, 16-bit offset. 1099 * 1100 * The branch distance is a signed code-unit offset, which we need to 1101 * double to get a byte offset. 1102 */ 1103 /* goto/16 +AAAA */ 1104 FETCH_S(r0, 1) @ r0<- ssssAAAA (sign-extended) 1105 adds r1, r0, r0 @ r1<- byte offset, flags set 1106 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1107 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1108 #if defined(WITH_JIT) 1109 ldr r0, [rSELF, #offThread_pJitProfTable] 1110 bmi common_testUpdateProfile @ (r0) hot trace head? 1111 #endif 1112 GET_INST_OPCODE(ip) @ extract opcode from rINST 1113 GOTO_OPCODE(ip) @ jump to next instruction 1114 1115 /* ------------------------------ */ 1116 .balign 64 1117 .L_OP_GOTO_32: /* 0x2a */ 1118 /* File: armv5te/OP_GOTO_32.S */ 1119 /* 1120 * Unconditional branch, 32-bit offset. 1121 * 1122 * The branch distance is a signed code-unit offset, which we need to 1123 * double to get a byte offset. 1124 * 1125 * Unlike most opcodes, this one is allowed to branch to itself, so 1126 * our "backward branch" test must be "<=0" instead of "<0". Because 1127 * we need the V bit set, we'll use an adds to convert from Dalvik 1128 * offset to byte offset. 1129 */ 1130 /* goto/32 +AAAAAAAA */ 1131 FETCH(r0, 1) @ r0<- aaaa (lo) 1132 FETCH(r1, 2) @ r1<- AAAA (hi) 1133 orr r0, r0, r1, lsl #16 @ r0<- AAAAaaaa 1134 adds r1, r0, r0 @ r1<- byte offset 1135 #if defined(WITH_JIT) 1136 ldr r0, [rSELF, #offThread_pJitProfTable] 1137 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1138 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1139 ble common_testUpdateProfile @ (r0) hot trace head? 1140 #else 1141 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1142 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1143 #endif 1144 GET_INST_OPCODE(ip) @ extract opcode from rINST 1145 GOTO_OPCODE(ip) @ jump to next instruction 1146 1147 /* ------------------------------ */ 1148 .balign 64 1149 .L_OP_PACKED_SWITCH: /* 0x2b */ 1150 /* File: armv5te/OP_PACKED_SWITCH.S */ 1151 /* 1152 * Handle a packed-switch or sparse-switch instruction. In both cases 1153 * we decode it and hand it off to a helper function. 1154 * 1155 * We don't really expect backward branches in a switch statement, but 1156 * they're perfectly legal, so we check for them here. 1157 * 1158 * When the JIT is present, all targets are considered treated as 1159 * a potential trace heads regardless of branch direction. 1160 * 1161 * for: packed-switch, sparse-switch 1162 */ 1163 /* op vAA, +BBBB */ 1164 FETCH(r0, 1) @ r0<- bbbb (lo) 1165 FETCH(r1, 2) @ r1<- BBBB (hi) 1166 mov r3, rINST, lsr #8 @ r3<- AA 1167 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1168 GET_VREG(r1, r3) @ r1<- vAA 1169 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1170 bl dvmInterpHandlePackedSwitch @ r0<- code-unit branch offset 1171 adds r1, r0, r0 @ r1<- byte offset; clear V 1172 #if defined(WITH_JIT) 1173 ldr r0, [rSELF, #offThread_pJitProfTable] 1174 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1175 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1176 cmp r0, #0 1177 bne common_updateProfile 1178 #else 1179 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1180 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1181 #endif 1182 GET_INST_OPCODE(ip) @ extract opcode from rINST 1183 GOTO_OPCODE(ip) @ jump to next instruction 1184 1185 /* ------------------------------ */ 1186 .balign 64 1187 .L_OP_SPARSE_SWITCH: /* 0x2c */ 1188 /* File: armv5te/OP_SPARSE_SWITCH.S */ 1189 /* File: armv5te/OP_PACKED_SWITCH.S */ 1190 /* 1191 * Handle a packed-switch or sparse-switch instruction. In both cases 1192 * we decode it and hand it off to a helper function. 1193 * 1194 * We don't really expect backward branches in a switch statement, but 1195 * they're perfectly legal, so we check for them here. 1196 * 1197 * When the JIT is present, all targets are considered treated as 1198 * a potential trace heads regardless of branch direction. 1199 * 1200 * for: packed-switch, sparse-switch 1201 */ 1202 /* op vAA, +BBBB */ 1203 FETCH(r0, 1) @ r0<- bbbb (lo) 1204 FETCH(r1, 2) @ r1<- BBBB (hi) 1205 mov r3, rINST, lsr #8 @ r3<- AA 1206 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1207 GET_VREG(r1, r3) @ r1<- vAA 1208 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1209 bl dvmInterpHandleSparseSwitch @ r0<- code-unit branch offset 1210 adds r1, r0, r0 @ r1<- byte offset; clear V 1211 #if defined(WITH_JIT) 1212 ldr r0, [rSELF, #offThread_pJitProfTable] 1213 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1214 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1215 cmp r0, #0 1216 bne common_updateProfile 1217 #else 1218 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1219 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1220 #endif 1221 GET_INST_OPCODE(ip) @ extract opcode from rINST 1222 GOTO_OPCODE(ip) @ jump to next instruction 1223 1224 1225 /* ------------------------------ */ 1226 .balign 64 1227 .L_OP_CMPL_FLOAT: /* 0x2d */ 1228 /* File: arm-vfp/OP_CMPL_FLOAT.S */ 1229 /* 1230 * Compare two floating-point values. Puts 0, 1, or -1 into the 1231 * destination register based on the results of the comparison. 1232 * 1233 * int compare(x, y) { 1234 * if (x == y) { 1235 * return 0; 1236 * } else if (x > y) { 1237 * return 1; 1238 * } else if (x < y) { 1239 * return -1; 1240 * } else { 1241 * return -1; 1242 * } 1243 * } 1244 */ 1245 /* op vAA, vBB, vCC */ 1246 FETCH(r0, 1) @ r0<- CCBB 1247 mov r9, rINST, lsr #8 @ r9<- AA 1248 and r2, r0, #255 @ r2<- BB 1249 mov r3, r0, lsr #8 @ r3<- CC 1250 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1251 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1252 flds s0, [r2] @ s0<- vBB 1253 flds s1, [r3] @ s1<- vCC 1254 fcmpes s0, s1 @ compare (vBB, vCC) 1255 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1256 mvn r0, #0 @ r0<- -1 (default) 1257 GET_INST_OPCODE(ip) @ extract opcode from rINST 1258 fmstat @ export status flags 1259 movgt r0, #1 @ (greater than) r1<- 1 1260 moveq r0, #0 @ (equal) r1<- 0 1261 b .LOP_CMPL_FLOAT_finish @ argh 1262 1263 1264 /* ------------------------------ */ 1265 .balign 64 1266 .L_OP_CMPG_FLOAT: /* 0x2e */ 1267 /* File: arm-vfp/OP_CMPG_FLOAT.S */ 1268 /* 1269 * Compare two floating-point values. Puts 0, 1, or -1 into the 1270 * destination register based on the results of the comparison. 1271 * 1272 * int compare(x, y) { 1273 * if (x == y) { 1274 * return 0; 1275 * } else if (x < y) { 1276 * return -1; 1277 * } else if (x > y) { 1278 * return 1; 1279 * } else { 1280 * return 1; 1281 * } 1282 * } 1283 */ 1284 /* op vAA, vBB, vCC */ 1285 FETCH(r0, 1) @ r0<- CCBB 1286 mov r9, rINST, lsr #8 @ r9<- AA 1287 and r2, r0, #255 @ r2<- BB 1288 mov r3, r0, lsr #8 @ r3<- CC 1289 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1290 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1291 flds s0, [r2] @ s0<- vBB 1292 flds s1, [r3] @ s1<- vCC 1293 fcmpes s0, s1 @ compare (vBB, vCC) 1294 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1295 mov r0, #1 @ r0<- 1 (default) 1296 GET_INST_OPCODE(ip) @ extract opcode from rINST 1297 fmstat @ export status flags 1298 mvnmi r0, #0 @ (less than) r1<- -1 1299 moveq r0, #0 @ (equal) r1<- 0 1300 b .LOP_CMPG_FLOAT_finish @ argh 1301 1302 1303 /* ------------------------------ */ 1304 .balign 64 1305 .L_OP_CMPL_DOUBLE: /* 0x2f */ 1306 /* File: arm-vfp/OP_CMPL_DOUBLE.S */ 1307 /* 1308 * Compare two floating-point values. Puts 0, 1, or -1 into the 1309 * destination register based on the results of the comparison. 1310 * 1311 * int compare(x, y) { 1312 * if (x == y) { 1313 * return 0; 1314 * } else if (x > y) { 1315 * return 1; 1316 * } else if (x < y) { 1317 * return -1; 1318 * } else { 1319 * return -1; 1320 * } 1321 * } 1322 */ 1323 /* op vAA, vBB, vCC */ 1324 FETCH(r0, 1) @ r0<- CCBB 1325 mov r9, rINST, lsr #8 @ r9<- AA 1326 and r2, r0, #255 @ r2<- BB 1327 mov r3, r0, lsr #8 @ r3<- CC 1328 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1329 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1330 fldd d0, [r2] @ d0<- vBB 1331 fldd d1, [r3] @ d1<- vCC 1332 fcmped d0, d1 @ compare (vBB, vCC) 1333 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1334 mvn r0, #0 @ r0<- -1 (default) 1335 GET_INST_OPCODE(ip) @ extract opcode from rINST 1336 fmstat @ export status flags 1337 movgt r0, #1 @ (greater than) r1<- 1 1338 moveq r0, #0 @ (equal) r1<- 0 1339 b .LOP_CMPL_DOUBLE_finish @ argh 1340 1341 1342 /* ------------------------------ */ 1343 .balign 64 1344 .L_OP_CMPG_DOUBLE: /* 0x30 */ 1345 /* File: arm-vfp/OP_CMPG_DOUBLE.S */ 1346 /* 1347 * Compare two floating-point values. Puts 0, 1, or -1 into the 1348 * destination register based on the results of the comparison. 1349 * 1350 * int compare(x, y) { 1351 * if (x == y) { 1352 * return 0; 1353 * } else if (x < y) { 1354 * return -1; 1355 * } else if (x > y) { 1356 * return 1; 1357 * } else { 1358 * return 1; 1359 * } 1360 * } 1361 */ 1362 /* op vAA, vBB, vCC */ 1363 FETCH(r0, 1) @ r0<- CCBB 1364 mov r9, rINST, lsr #8 @ r9<- AA 1365 and r2, r0, #255 @ r2<- BB 1366 mov r3, r0, lsr #8 @ r3<- CC 1367 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1368 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1369 fldd d0, [r2] @ d0<- vBB 1370 fldd d1, [r3] @ d1<- vCC 1371 fcmped d0, d1 @ compare (vBB, vCC) 1372 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1373 mov r0, #1 @ r0<- 1 (default) 1374 GET_INST_OPCODE(ip) @ extract opcode from rINST 1375 fmstat @ export status flags 1376 mvnmi r0, #0 @ (less than) r1<- -1 1377 moveq r0, #0 @ (equal) r1<- 0 1378 b .LOP_CMPG_DOUBLE_finish @ argh 1379 1380 1381 /* ------------------------------ */ 1382 .balign 64 1383 .L_OP_CMP_LONG: /* 0x31 */ 1384 /* File: armv5te/OP_CMP_LONG.S */ 1385 /* 1386 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 1387 * register based on the results of the comparison. 1388 * 1389 * We load the full values with LDM, but in practice many values could 1390 * be resolved by only looking at the high word. This could be made 1391 * faster or slower by splitting the LDM into a pair of LDRs. 1392 * 1393 * If we just wanted to set condition flags, we could do this: 1394 * subs ip, r0, r2 1395 * sbcs ip, r1, r3 1396 * subeqs ip, r0, r2 1397 * Leaving { <0, 0, >0 } in ip. However, we have to set it to a specific 1398 * integer value, which we can do with 2 conditional mov/mvn instructions 1399 * (set 1, set -1; if they're equal we already have 0 in ip), giving 1400 * us a constant 5-cycle path plus a branch at the end to the 1401 * instruction epilogue code. The multi-compare approach below needs 1402 * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch 1403 * in the worst case (the 64-bit values are equal). 1404 */ 1405 /* cmp-long vAA, vBB, vCC */ 1406 FETCH(r0, 1) @ r0<- CCBB 1407 mov r9, rINST, lsr #8 @ r9<- AA 1408 and r2, r0, #255 @ r2<- BB 1409 mov r3, r0, lsr #8 @ r3<- CC 1410 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 1411 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 1412 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 1413 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 1414 cmp r1, r3 @ compare (vBB+1, vCC+1) 1415 blt .LOP_CMP_LONG_less @ signed compare on high part 1416 bgt .LOP_CMP_LONG_greater 1417 subs r1, r0, r2 @ r1<- r0 - r2 1418 bhi .LOP_CMP_LONG_greater @ unsigned compare on low part 1419 bne .LOP_CMP_LONG_less 1420 b .LOP_CMP_LONG_finish @ equal; r1 already holds 0 1421 1422 /* ------------------------------ */ 1423 .balign 64 1424 .L_OP_IF_EQ: /* 0x32 */ 1425 /* File: armv5te/OP_IF_EQ.S */ 1426 /* File: armv5te/bincmp.S */ 1427 /* 1428 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1429 * fragment that specifies the *reverse* comparison to perform, e.g. 1430 * for "if-le" you would use "gt". 1431 * 1432 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1433 */ 1434 /* if-cmp vA, vB, +CCCC */ 1435 mov r0, rINST, lsr #8 @ r0<- A+ 1436 mov r1, rINST, lsr #12 @ r1<- B 1437 and r0, r0, #15 1438 GET_VREG(r3, r1) @ r3<- vB 1439 GET_VREG(r2, r0) @ r2<- vA 1440 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1441 cmp r2, r3 @ compare (vA, vB) 1442 movne r1, #2 @ r1<- BYTE branch dist for not-taken 1443 adds r2, r1, r1 @ convert to bytes, check sign 1444 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1445 #if defined(WITH_JIT) 1446 ldr r0, [rSELF, #offThread_pJitProfTable] 1447 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1448 cmp r0,#0 1449 bne common_updateProfile 1450 #else 1451 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1452 #endif 1453 GET_INST_OPCODE(ip) @ extract opcode from rINST 1454 GOTO_OPCODE(ip) @ jump to next instruction 1455 1456 1457 /* ------------------------------ */ 1458 .balign 64 1459 .L_OP_IF_NE: /* 0x33 */ 1460 /* File: armv5te/OP_IF_NE.S */ 1461 /* File: armv5te/bincmp.S */ 1462 /* 1463 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1464 * fragment that specifies the *reverse* comparison to perform, e.g. 1465 * for "if-le" you would use "gt". 1466 * 1467 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1468 */ 1469 /* if-cmp vA, vB, +CCCC */ 1470 mov r0, rINST, lsr #8 @ r0<- A+ 1471 mov r1, rINST, lsr #12 @ r1<- B 1472 and r0, r0, #15 1473 GET_VREG(r3, r1) @ r3<- vB 1474 GET_VREG(r2, r0) @ r2<- vA 1475 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1476 cmp r2, r3 @ compare (vA, vB) 1477 moveq r1, #2 @ r1<- BYTE branch dist for not-taken 1478 adds r2, r1, r1 @ convert to bytes, check sign 1479 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1480 #if defined(WITH_JIT) 1481 ldr r0, [rSELF, #offThread_pJitProfTable] 1482 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1483 cmp r0,#0 1484 bne common_updateProfile 1485 #else 1486 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1487 #endif 1488 GET_INST_OPCODE(ip) @ extract opcode from rINST 1489 GOTO_OPCODE(ip) @ jump to next instruction 1490 1491 1492 /* ------------------------------ */ 1493 .balign 64 1494 .L_OP_IF_LT: /* 0x34 */ 1495 /* File: armv5te/OP_IF_LT.S */ 1496 /* File: armv5te/bincmp.S */ 1497 /* 1498 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1499 * fragment that specifies the *reverse* comparison to perform, e.g. 1500 * for "if-le" you would use "gt". 1501 * 1502 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1503 */ 1504 /* if-cmp vA, vB, +CCCC */ 1505 mov r0, rINST, lsr #8 @ r0<- A+ 1506 mov r1, rINST, lsr #12 @ r1<- B 1507 and r0, r0, #15 1508 GET_VREG(r3, r1) @ r3<- vB 1509 GET_VREG(r2, r0) @ r2<- vA 1510 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1511 cmp r2, r3 @ compare (vA, vB) 1512 movge r1, #2 @ r1<- BYTE branch dist for not-taken 1513 adds r2, r1, r1 @ convert to bytes, check sign 1514 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1515 #if defined(WITH_JIT) 1516 ldr r0, [rSELF, #offThread_pJitProfTable] 1517 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1518 cmp r0,#0 1519 bne common_updateProfile 1520 #else 1521 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1522 #endif 1523 GET_INST_OPCODE(ip) @ extract opcode from rINST 1524 GOTO_OPCODE(ip) @ jump to next instruction 1525 1526 1527 /* ------------------------------ */ 1528 .balign 64 1529 .L_OP_IF_GE: /* 0x35 */ 1530 /* File: armv5te/OP_IF_GE.S */ 1531 /* File: armv5te/bincmp.S */ 1532 /* 1533 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1534 * fragment that specifies the *reverse* comparison to perform, e.g. 1535 * for "if-le" you would use "gt". 1536 * 1537 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1538 */ 1539 /* if-cmp vA, vB, +CCCC */ 1540 mov r0, rINST, lsr #8 @ r0<- A+ 1541 mov r1, rINST, lsr #12 @ r1<- B 1542 and r0, r0, #15 1543 GET_VREG(r3, r1) @ r3<- vB 1544 GET_VREG(r2, r0) @ r2<- vA 1545 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1546 cmp r2, r3 @ compare (vA, vB) 1547 movlt r1, #2 @ r1<- BYTE branch dist for not-taken 1548 adds r2, r1, r1 @ convert to bytes, check sign 1549 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1550 #if defined(WITH_JIT) 1551 ldr r0, [rSELF, #offThread_pJitProfTable] 1552 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1553 cmp r0,#0 1554 bne common_updateProfile 1555 #else 1556 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1557 #endif 1558 GET_INST_OPCODE(ip) @ extract opcode from rINST 1559 GOTO_OPCODE(ip) @ jump to next instruction 1560 1561 1562 /* ------------------------------ */ 1563 .balign 64 1564 .L_OP_IF_GT: /* 0x36 */ 1565 /* File: armv5te/OP_IF_GT.S */ 1566 /* File: armv5te/bincmp.S */ 1567 /* 1568 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1569 * fragment that specifies the *reverse* comparison to perform, e.g. 1570 * for "if-le" you would use "gt". 1571 * 1572 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1573 */ 1574 /* if-cmp vA, vB, +CCCC */ 1575 mov r0, rINST, lsr #8 @ r0<- A+ 1576 mov r1, rINST, lsr #12 @ r1<- B 1577 and r0, r0, #15 1578 GET_VREG(r3, r1) @ r3<- vB 1579 GET_VREG(r2, r0) @ r2<- vA 1580 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1581 cmp r2, r3 @ compare (vA, vB) 1582 movle r1, #2 @ r1<- BYTE branch dist for not-taken 1583 adds r2, r1, r1 @ convert to bytes, check sign 1584 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1585 #if defined(WITH_JIT) 1586 ldr r0, [rSELF, #offThread_pJitProfTable] 1587 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1588 cmp r0,#0 1589 bne common_updateProfile 1590 #else 1591 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1592 #endif 1593 GET_INST_OPCODE(ip) @ extract opcode from rINST 1594 GOTO_OPCODE(ip) @ jump to next instruction 1595 1596 1597 /* ------------------------------ */ 1598 .balign 64 1599 .L_OP_IF_LE: /* 0x37 */ 1600 /* File: armv5te/OP_IF_LE.S */ 1601 /* File: armv5te/bincmp.S */ 1602 /* 1603 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1604 * fragment that specifies the *reverse* comparison to perform, e.g. 1605 * for "if-le" you would use "gt". 1606 * 1607 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1608 */ 1609 /* if-cmp vA, vB, +CCCC */ 1610 mov r0, rINST, lsr #8 @ r0<- A+ 1611 mov r1, rINST, lsr #12 @ r1<- B 1612 and r0, r0, #15 1613 GET_VREG(r3, r1) @ r3<- vB 1614 GET_VREG(r2, r0) @ r2<- vA 1615 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1616 cmp r2, r3 @ compare (vA, vB) 1617 movgt r1, #2 @ r1<- BYTE branch dist for not-taken 1618 adds r2, r1, r1 @ convert to bytes, check sign 1619 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1620 #if defined(WITH_JIT) 1621 ldr r0, [rSELF, #offThread_pJitProfTable] 1622 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1623 cmp r0,#0 1624 bne common_updateProfile 1625 #else 1626 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1627 #endif 1628 GET_INST_OPCODE(ip) @ extract opcode from rINST 1629 GOTO_OPCODE(ip) @ jump to next instruction 1630 1631 1632 /* ------------------------------ */ 1633 .balign 64 1634 .L_OP_IF_EQZ: /* 0x38 */ 1635 /* File: armv5te/OP_IF_EQZ.S */ 1636 /* File: armv5te/zcmp.S */ 1637 /* 1638 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1639 * fragment that specifies the *reverse* comparison to perform, e.g. 1640 * for "if-le" you would use "gt". 1641 * 1642 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1643 */ 1644 /* if-cmp vAA, +BBBB */ 1645 mov r0, rINST, lsr #8 @ r0<- AA 1646 GET_VREG(r2, r0) @ r2<- vAA 1647 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1648 cmp r2, #0 @ compare (vA, 0) 1649 movne r1, #2 @ r1<- inst branch dist for not-taken 1650 adds r1, r1, r1 @ convert to bytes & set flags 1651 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1652 #if defined(WITH_JIT) 1653 ldr r0, [rSELF, #offThread_pJitProfTable] 1654 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1655 cmp r0,#0 1656 bne common_updateProfile @ test for JIT off at target 1657 #else 1658 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1659 #endif 1660 GET_INST_OPCODE(ip) @ extract opcode from rINST 1661 GOTO_OPCODE(ip) @ jump to next instruction 1662 1663 1664 /* ------------------------------ */ 1665 .balign 64 1666 .L_OP_IF_NEZ: /* 0x39 */ 1667 /* File: armv5te/OP_IF_NEZ.S */ 1668 /* File: armv5te/zcmp.S */ 1669 /* 1670 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1671 * fragment that specifies the *reverse* comparison to perform, e.g. 1672 * for "if-le" you would use "gt". 1673 * 1674 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1675 */ 1676 /* if-cmp vAA, +BBBB */ 1677 mov r0, rINST, lsr #8 @ r0<- AA 1678 GET_VREG(r2, r0) @ r2<- vAA 1679 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1680 cmp r2, #0 @ compare (vA, 0) 1681 moveq r1, #2 @ r1<- inst branch dist for not-taken 1682 adds r1, r1, r1 @ convert to bytes & set flags 1683 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1684 #if defined(WITH_JIT) 1685 ldr r0, [rSELF, #offThread_pJitProfTable] 1686 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1687 cmp r0,#0 1688 bne common_updateProfile @ test for JIT off at target 1689 #else 1690 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1691 #endif 1692 GET_INST_OPCODE(ip) @ extract opcode from rINST 1693 GOTO_OPCODE(ip) @ jump to next instruction 1694 1695 1696 /* ------------------------------ */ 1697 .balign 64 1698 .L_OP_IF_LTZ: /* 0x3a */ 1699 /* File: armv5te/OP_IF_LTZ.S */ 1700 /* File: armv5te/zcmp.S */ 1701 /* 1702 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1703 * fragment that specifies the *reverse* comparison to perform, e.g. 1704 * for "if-le" you would use "gt". 1705 * 1706 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1707 */ 1708 /* if-cmp vAA, +BBBB */ 1709 mov r0, rINST, lsr #8 @ r0<- AA 1710 GET_VREG(r2, r0) @ r2<- vAA 1711 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1712 cmp r2, #0 @ compare (vA, 0) 1713 movge r1, #2 @ r1<- inst branch dist for not-taken 1714 adds r1, r1, r1 @ convert to bytes & set flags 1715 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1716 #if defined(WITH_JIT) 1717 ldr r0, [rSELF, #offThread_pJitProfTable] 1718 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1719 cmp r0,#0 1720 bne common_updateProfile @ test for JIT off at target 1721 #else 1722 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1723 #endif 1724 GET_INST_OPCODE(ip) @ extract opcode from rINST 1725 GOTO_OPCODE(ip) @ jump to next instruction 1726 1727 1728 /* ------------------------------ */ 1729 .balign 64 1730 .L_OP_IF_GEZ: /* 0x3b */ 1731 /* File: armv5te/OP_IF_GEZ.S */ 1732 /* File: armv5te/zcmp.S */ 1733 /* 1734 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1735 * fragment that specifies the *reverse* comparison to perform, e.g. 1736 * for "if-le" you would use "gt". 1737 * 1738 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1739 */ 1740 /* if-cmp vAA, +BBBB */ 1741 mov r0, rINST, lsr #8 @ r0<- AA 1742 GET_VREG(r2, r0) @ r2<- vAA 1743 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1744 cmp r2, #0 @ compare (vA, 0) 1745 movlt r1, #2 @ r1<- inst branch dist for not-taken 1746 adds r1, r1, r1 @ convert to bytes & set flags 1747 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1748 #if defined(WITH_JIT) 1749 ldr r0, [rSELF, #offThread_pJitProfTable] 1750 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1751 cmp r0,#0 1752 bne common_updateProfile @ test for JIT off at target 1753 #else 1754 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1755 #endif 1756 GET_INST_OPCODE(ip) @ extract opcode from rINST 1757 GOTO_OPCODE(ip) @ jump to next instruction 1758 1759 1760 /* ------------------------------ */ 1761 .balign 64 1762 .L_OP_IF_GTZ: /* 0x3c */ 1763 /* File: armv5te/OP_IF_GTZ.S */ 1764 /* File: armv5te/zcmp.S */ 1765 /* 1766 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1767 * fragment that specifies the *reverse* comparison to perform, e.g. 1768 * for "if-le" you would use "gt". 1769 * 1770 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1771 */ 1772 /* if-cmp vAA, +BBBB */ 1773 mov r0, rINST, lsr #8 @ r0<- AA 1774 GET_VREG(r2, r0) @ r2<- vAA 1775 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1776 cmp r2, #0 @ compare (vA, 0) 1777 movle r1, #2 @ r1<- inst branch dist for not-taken 1778 adds r1, r1, r1 @ convert to bytes & set flags 1779 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1780 #if defined(WITH_JIT) 1781 ldr r0, [rSELF, #offThread_pJitProfTable] 1782 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1783 cmp r0,#0 1784 bne common_updateProfile @ test for JIT off at target 1785 #else 1786 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1787 #endif 1788 GET_INST_OPCODE(ip) @ extract opcode from rINST 1789 GOTO_OPCODE(ip) @ jump to next instruction 1790 1791 1792 /* ------------------------------ */ 1793 .balign 64 1794 .L_OP_IF_LEZ: /* 0x3d */ 1795 /* File: armv5te/OP_IF_LEZ.S */ 1796 /* File: armv5te/zcmp.S */ 1797 /* 1798 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1799 * fragment that specifies the *reverse* comparison to perform, e.g. 1800 * for "if-le" you would use "gt". 1801 * 1802 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1803 */ 1804 /* if-cmp vAA, +BBBB */ 1805 mov r0, rINST, lsr #8 @ r0<- AA 1806 GET_VREG(r2, r0) @ r2<- vAA 1807 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1808 cmp r2, #0 @ compare (vA, 0) 1809 movgt r1, #2 @ r1<- inst branch dist for not-taken 1810 adds r1, r1, r1 @ convert to bytes & set flags 1811 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1812 #if defined(WITH_JIT) 1813 ldr r0, [rSELF, #offThread_pJitProfTable] 1814 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1815 cmp r0,#0 1816 bne common_updateProfile @ test for JIT off at target 1817 #else 1818 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1819 #endif 1820 GET_INST_OPCODE(ip) @ extract opcode from rINST 1821 GOTO_OPCODE(ip) @ jump to next instruction 1822 1823 1824 /* ------------------------------ */ 1825 .balign 64 1826 .L_OP_UNUSED_3E: /* 0x3e */ 1827 /* File: armv5te/OP_UNUSED_3E.S */ 1828 /* File: armv5te/unused.S */ 1829 bl common_abort 1830 1831 1832 /* ------------------------------ */ 1833 .balign 64 1834 .L_OP_UNUSED_3F: /* 0x3f */ 1835 /* File: armv5te/OP_UNUSED_3F.S */ 1836 /* File: armv5te/unused.S */ 1837 bl common_abort 1838 1839 1840 /* ------------------------------ */ 1841 .balign 64 1842 .L_OP_UNUSED_40: /* 0x40 */ 1843 /* File: armv5te/OP_UNUSED_40.S */ 1844 /* File: armv5te/unused.S */ 1845 bl common_abort 1846 1847 1848 /* ------------------------------ */ 1849 .balign 64 1850 .L_OP_UNUSED_41: /* 0x41 */ 1851 /* File: armv5te/OP_UNUSED_41.S */ 1852 /* File: armv5te/unused.S */ 1853 bl common_abort 1854 1855 1856 /* ------------------------------ */ 1857 .balign 64 1858 .L_OP_UNUSED_42: /* 0x42 */ 1859 /* File: armv5te/OP_UNUSED_42.S */ 1860 /* File: armv5te/unused.S */ 1861 bl common_abort 1862 1863 1864 /* ------------------------------ */ 1865 .balign 64 1866 .L_OP_UNUSED_43: /* 0x43 */ 1867 /* File: armv5te/OP_UNUSED_43.S */ 1868 /* File: armv5te/unused.S */ 1869 bl common_abort 1870 1871 1872 /* ------------------------------ */ 1873 .balign 64 1874 .L_OP_AGET: /* 0x44 */ 1875 /* File: armv5te/OP_AGET.S */ 1876 /* 1877 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1878 * 1879 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1880 * instructions. We use a pair of FETCH_Bs instead. 1881 * 1882 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1883 */ 1884 /* op vAA, vBB, vCC */ 1885 FETCH_B(r2, 1, 0) @ r2<- BB 1886 mov r9, rINST, lsr #8 @ r9<- AA 1887 FETCH_B(r3, 1, 1) @ r3<- CC 1888 GET_VREG(r0, r2) @ r0<- vBB (array object) 1889 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1890 cmp r0, #0 @ null array object? 1891 beq common_errNullObject @ yes, bail 1892 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1893 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1894 cmp r1, r3 @ compare unsigned index, length 1895 bcs common_errArrayIndex @ index >= length, bail 1896 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1897 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1898 GET_INST_OPCODE(ip) @ extract opcode from rINST 1899 SET_VREG(r2, r9) @ vAA<- r2 1900 GOTO_OPCODE(ip) @ jump to next instruction 1901 1902 /* ------------------------------ */ 1903 .balign 64 1904 .L_OP_AGET_WIDE: /* 0x45 */ 1905 /* File: armv5te/OP_AGET_WIDE.S */ 1906 /* 1907 * Array get, 64 bits. vAA <- vBB[vCC]. 1908 * 1909 * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD. 1910 */ 1911 /* aget-wide vAA, vBB, vCC */ 1912 FETCH(r0, 1) @ r0<- CCBB 1913 mov r9, rINST, lsr #8 @ r9<- AA 1914 and r2, r0, #255 @ r2<- BB 1915 mov r3, r0, lsr #8 @ r3<- CC 1916 GET_VREG(r0, r2) @ r0<- vBB (array object) 1917 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1918 cmp r0, #0 @ null array object? 1919 beq common_errNullObject @ yes, bail 1920 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1921 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 1922 cmp r1, r3 @ compare unsigned index, length 1923 bcc .LOP_AGET_WIDE_finish @ okay, continue below 1924 b common_errArrayIndex @ index >= length, bail 1925 @ May want to swap the order of these two branches depending on how the 1926 @ branch prediction (if any) handles conditional forward branches vs. 1927 @ unconditional forward branches. 1928 1929 /* ------------------------------ */ 1930 .balign 64 1931 .L_OP_AGET_OBJECT: /* 0x46 */ 1932 /* File: armv5te/OP_AGET_OBJECT.S */ 1933 /* File: armv5te/OP_AGET.S */ 1934 /* 1935 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1936 * 1937 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1938 * instructions. We use a pair of FETCH_Bs instead. 1939 * 1940 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1941 */ 1942 /* op vAA, vBB, vCC */ 1943 FETCH_B(r2, 1, 0) @ r2<- BB 1944 mov r9, rINST, lsr #8 @ r9<- AA 1945 FETCH_B(r3, 1, 1) @ r3<- CC 1946 GET_VREG(r0, r2) @ r0<- vBB (array object) 1947 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1948 cmp r0, #0 @ null array object? 1949 beq common_errNullObject @ yes, bail 1950 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1951 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1952 cmp r1, r3 @ compare unsigned index, length 1953 bcs common_errArrayIndex @ index >= length, bail 1954 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1955 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1956 GET_INST_OPCODE(ip) @ extract opcode from rINST 1957 SET_VREG(r2, r9) @ vAA<- r2 1958 GOTO_OPCODE(ip) @ jump to next instruction 1959 1960 1961 /* ------------------------------ */ 1962 .balign 64 1963 .L_OP_AGET_BOOLEAN: /* 0x47 */ 1964 /* File: armv5te/OP_AGET_BOOLEAN.S */ 1965 /* File: armv5te/OP_AGET.S */ 1966 /* 1967 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1968 * 1969 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1970 * instructions. We use a pair of FETCH_Bs instead. 1971 * 1972 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1973 */ 1974 /* op vAA, vBB, vCC */ 1975 FETCH_B(r2, 1, 0) @ r2<- BB 1976 mov r9, rINST, lsr #8 @ r9<- AA 1977 FETCH_B(r3, 1, 1) @ r3<- CC 1978 GET_VREG(r0, r2) @ r0<- vBB (array object) 1979 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1980 cmp r0, #0 @ null array object? 1981 beq common_errNullObject @ yes, bail 1982 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1983 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 1984 cmp r1, r3 @ compare unsigned index, length 1985 bcs common_errArrayIndex @ index >= length, bail 1986 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1987 ldrb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1988 GET_INST_OPCODE(ip) @ extract opcode from rINST 1989 SET_VREG(r2, r9) @ vAA<- r2 1990 GOTO_OPCODE(ip) @ jump to next instruction 1991 1992 1993 /* ------------------------------ */ 1994 .balign 64 1995 .L_OP_AGET_BYTE: /* 0x48 */ 1996 /* File: armv5te/OP_AGET_BYTE.S */ 1997 /* File: armv5te/OP_AGET.S */ 1998 /* 1999 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2000 * 2001 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2002 * instructions. We use a pair of FETCH_Bs instead. 2003 * 2004 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2005 */ 2006 /* op vAA, vBB, vCC */ 2007 FETCH_B(r2, 1, 0) @ r2<- BB 2008 mov r9, rINST, lsr #8 @ r9<- AA 2009 FETCH_B(r3, 1, 1) @ r3<- CC 2010 GET_VREG(r0, r2) @ r0<- vBB (array object) 2011 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2012 cmp r0, #0 @ null array object? 2013 beq common_errNullObject @ yes, bail 2014 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2015 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2016 cmp r1, r3 @ compare unsigned index, length 2017 bcs common_errArrayIndex @ index >= length, bail 2018 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2019 ldrsb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2020 GET_INST_OPCODE(ip) @ extract opcode from rINST 2021 SET_VREG(r2, r9) @ vAA<- r2 2022 GOTO_OPCODE(ip) @ jump to next instruction 2023 2024 2025 /* ------------------------------ */ 2026 .balign 64 2027 .L_OP_AGET_CHAR: /* 0x49 */ 2028 /* File: armv5te/OP_AGET_CHAR.S */ 2029 /* File: armv5te/OP_AGET.S */ 2030 /* 2031 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2032 * 2033 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2034 * instructions. We use a pair of FETCH_Bs instead. 2035 * 2036 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2037 */ 2038 /* op vAA, vBB, vCC */ 2039 FETCH_B(r2, 1, 0) @ r2<- BB 2040 mov r9, rINST, lsr #8 @ r9<- AA 2041 FETCH_B(r3, 1, 1) @ r3<- CC 2042 GET_VREG(r0, r2) @ r0<- vBB (array object) 2043 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2044 cmp r0, #0 @ null array object? 2045 beq common_errNullObject @ yes, bail 2046 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2047 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2048 cmp r1, r3 @ compare unsigned index, length 2049 bcs common_errArrayIndex @ index >= length, bail 2050 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2051 ldrh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2052 GET_INST_OPCODE(ip) @ extract opcode from rINST 2053 SET_VREG(r2, r9) @ vAA<- r2 2054 GOTO_OPCODE(ip) @ jump to next instruction 2055 2056 2057 /* ------------------------------ */ 2058 .balign 64 2059 .L_OP_AGET_SHORT: /* 0x4a */ 2060 /* File: armv5te/OP_AGET_SHORT.S */ 2061 /* File: armv5te/OP_AGET.S */ 2062 /* 2063 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2064 * 2065 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2066 * instructions. We use a pair of FETCH_Bs instead. 2067 * 2068 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2069 */ 2070 /* op vAA, vBB, vCC */ 2071 FETCH_B(r2, 1, 0) @ r2<- BB 2072 mov r9, rINST, lsr #8 @ r9<- AA 2073 FETCH_B(r3, 1, 1) @ r3<- CC 2074 GET_VREG(r0, r2) @ r0<- vBB (array object) 2075 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2076 cmp r0, #0 @ null array object? 2077 beq common_errNullObject @ yes, bail 2078 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2079 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2080 cmp r1, r3 @ compare unsigned index, length 2081 bcs common_errArrayIndex @ index >= length, bail 2082 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2083 ldrsh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2084 GET_INST_OPCODE(ip) @ extract opcode from rINST 2085 SET_VREG(r2, r9) @ vAA<- r2 2086 GOTO_OPCODE(ip) @ jump to next instruction 2087 2088 2089 /* ------------------------------ */ 2090 .balign 64 2091 .L_OP_APUT: /* 0x4b */ 2092 /* File: armv5te/OP_APUT.S */ 2093 /* 2094 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2095 * 2096 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2097 * instructions. We use a pair of FETCH_Bs instead. 2098 * 2099 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2100 */ 2101 /* op vAA, vBB, vCC */ 2102 FETCH_B(r2, 1, 0) @ r2<- BB 2103 mov r9, rINST, lsr #8 @ r9<- AA 2104 FETCH_B(r3, 1, 1) @ r3<- CC 2105 GET_VREG(r0, r2) @ r0<- vBB (array object) 2106 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2107 cmp r0, #0 @ null array object? 2108 beq common_errNullObject @ yes, bail 2109 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2110 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2111 cmp r1, r3 @ compare unsigned index, length 2112 bcs common_errArrayIndex @ index >= length, bail 2113 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2114 GET_VREG(r2, r9) @ r2<- vAA 2115 GET_INST_OPCODE(ip) @ extract opcode from rINST 2116 str r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2117 GOTO_OPCODE(ip) @ jump to next instruction 2118 2119 /* ------------------------------ */ 2120 .balign 64 2121 .L_OP_APUT_WIDE: /* 0x4c */ 2122 /* File: armv5te/OP_APUT_WIDE.S */ 2123 /* 2124 * Array put, 64 bits. vBB[vCC] <- vAA. 2125 * 2126 * Arrays of long/double are 64-bit aligned, so it's okay to use STRD. 2127 */ 2128 /* aput-wide vAA, vBB, vCC */ 2129 FETCH(r0, 1) @ r0<- CCBB 2130 mov r9, rINST, lsr #8 @ r9<- AA 2131 and r2, r0, #255 @ r2<- BB 2132 mov r3, r0, lsr #8 @ r3<- CC 2133 GET_VREG(r0, r2) @ r0<- vBB (array object) 2134 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2135 cmp r0, #0 @ null array object? 2136 beq common_errNullObject @ yes, bail 2137 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2138 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2139 cmp r1, r3 @ compare unsigned index, length 2140 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2141 bcc .LOP_APUT_WIDE_finish @ okay, continue below 2142 b common_errArrayIndex @ index >= length, bail 2143 @ May want to swap the order of these two branches depending on how the 2144 @ branch prediction (if any) handles conditional forward branches vs. 2145 @ unconditional forward branches. 2146 2147 /* ------------------------------ */ 2148 .balign 64 2149 .L_OP_APUT_OBJECT: /* 0x4d */ 2150 /* File: armv5te/OP_APUT_OBJECT.S */ 2151 /* 2152 * Store an object into an array. vBB[vCC] <- vAA. 2153 */ 2154 /* op vAA, vBB, vCC */ 2155 FETCH(r0, 1) @ r0<- CCBB 2156 mov r9, rINST, lsr #8 @ r9<- AA 2157 and r2, r0, #255 @ r2<- BB 2158 mov r3, r0, lsr #8 @ r3<- CC 2159 GET_VREG(rINST, r2) @ rINST<- vBB (array object) 2160 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2161 cmp rINST, #0 @ null array object? 2162 GET_VREG(r9, r9) @ r9<- vAA 2163 beq common_errNullObject @ yes, bail 2164 ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length 2165 add r10, rINST, r1, lsl #2 @ r10<- arrayObj + index*width 2166 cmp r1, r3 @ compare unsigned index, length 2167 bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on 2168 b common_errArrayIndex @ index >= length, bail 2169 2170 2171 /* ------------------------------ */ 2172 .balign 64 2173 .L_OP_APUT_BOOLEAN: /* 0x4e */ 2174 /* File: armv5te/OP_APUT_BOOLEAN.S */ 2175 /* File: armv5te/OP_APUT.S */ 2176 /* 2177 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2178 * 2179 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2180 * instructions. We use a pair of FETCH_Bs instead. 2181 * 2182 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2183 */ 2184 /* op vAA, vBB, vCC */ 2185 FETCH_B(r2, 1, 0) @ r2<- BB 2186 mov r9, rINST, lsr #8 @ r9<- AA 2187 FETCH_B(r3, 1, 1) @ r3<- CC 2188 GET_VREG(r0, r2) @ r0<- vBB (array object) 2189 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2190 cmp r0, #0 @ null array object? 2191 beq common_errNullObject @ yes, bail 2192 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2193 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2194 cmp r1, r3 @ compare unsigned index, length 2195 bcs common_errArrayIndex @ index >= length, bail 2196 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2197 GET_VREG(r2, r9) @ r2<- vAA 2198 GET_INST_OPCODE(ip) @ extract opcode from rINST 2199 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2200 GOTO_OPCODE(ip) @ jump to next instruction 2201 2202 2203 /* ------------------------------ */ 2204 .balign 64 2205 .L_OP_APUT_BYTE: /* 0x4f */ 2206 /* File: armv5te/OP_APUT_BYTE.S */ 2207 /* File: armv5te/OP_APUT.S */ 2208 /* 2209 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2210 * 2211 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2212 * instructions. We use a pair of FETCH_Bs instead. 2213 * 2214 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2215 */ 2216 /* op vAA, vBB, vCC */ 2217 FETCH_B(r2, 1, 0) @ r2<- BB 2218 mov r9, rINST, lsr #8 @ r9<- AA 2219 FETCH_B(r3, 1, 1) @ r3<- CC 2220 GET_VREG(r0, r2) @ r0<- vBB (array object) 2221 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2222 cmp r0, #0 @ null array object? 2223 beq common_errNullObject @ yes, bail 2224 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2225 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2226 cmp r1, r3 @ compare unsigned index, length 2227 bcs common_errArrayIndex @ index >= length, bail 2228 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2229 GET_VREG(r2, r9) @ r2<- vAA 2230 GET_INST_OPCODE(ip) @ extract opcode from rINST 2231 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2232 GOTO_OPCODE(ip) @ jump to next instruction 2233 2234 2235 /* ------------------------------ */ 2236 .balign 64 2237 .L_OP_APUT_CHAR: /* 0x50 */ 2238 /* File: armv5te/OP_APUT_CHAR.S */ 2239 /* File: armv5te/OP_APUT.S */ 2240 /* 2241 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2242 * 2243 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2244 * instructions. We use a pair of FETCH_Bs instead. 2245 * 2246 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2247 */ 2248 /* op vAA, vBB, vCC */ 2249 FETCH_B(r2, 1, 0) @ r2<- BB 2250 mov r9, rINST, lsr #8 @ r9<- AA 2251 FETCH_B(r3, 1, 1) @ r3<- CC 2252 GET_VREG(r0, r2) @ r0<- vBB (array object) 2253 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2254 cmp r0, #0 @ null array object? 2255 beq common_errNullObject @ yes, bail 2256 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2257 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2258 cmp r1, r3 @ compare unsigned index, length 2259 bcs common_errArrayIndex @ index >= length, bail 2260 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2261 GET_VREG(r2, r9) @ r2<- vAA 2262 GET_INST_OPCODE(ip) @ extract opcode from rINST 2263 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2264 GOTO_OPCODE(ip) @ jump to next instruction 2265 2266 2267 /* ------------------------------ */ 2268 .balign 64 2269 .L_OP_APUT_SHORT: /* 0x51 */ 2270 /* File: armv5te/OP_APUT_SHORT.S */ 2271 /* File: armv5te/OP_APUT.S */ 2272 /* 2273 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2274 * 2275 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2276 * instructions. We use a pair of FETCH_Bs instead. 2277 * 2278 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2279 */ 2280 /* op vAA, vBB, vCC */ 2281 FETCH_B(r2, 1, 0) @ r2<- BB 2282 mov r9, rINST, lsr #8 @ r9<- AA 2283 FETCH_B(r3, 1, 1) @ r3<- CC 2284 GET_VREG(r0, r2) @ r0<- vBB (array object) 2285 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2286 cmp r0, #0 @ null array object? 2287 beq common_errNullObject @ yes, bail 2288 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2289 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2290 cmp r1, r3 @ compare unsigned index, length 2291 bcs common_errArrayIndex @ index >= length, bail 2292 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2293 GET_VREG(r2, r9) @ r2<- vAA 2294 GET_INST_OPCODE(ip) @ extract opcode from rINST 2295 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2296 GOTO_OPCODE(ip) @ jump to next instruction 2297 2298 2299 /* ------------------------------ */ 2300 .balign 64 2301 .L_OP_IGET: /* 0x52 */ 2302 /* File: armv5te/OP_IGET.S */ 2303 /* 2304 * General 32-bit instance field get. 2305 * 2306 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2307 */ 2308 /* op vA, vB, field@CCCC */ 2309 mov r0, rINST, lsr #12 @ r0<- B 2310 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2311 FETCH(r1, 1) @ r1<- field ref CCCC 2312 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2313 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2314 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2315 cmp r0, #0 @ is resolved entry null? 2316 bne .LOP_IGET_finish @ no, already resolved 2317 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2318 EXPORT_PC() @ resolve() could throw 2319 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2320 bl dvmResolveInstField @ r0<- resolved InstField ptr 2321 cmp r0, #0 2322 bne .LOP_IGET_finish 2323 b common_exceptionThrown 2324 2325 /* ------------------------------ */ 2326 .balign 64 2327 .L_OP_IGET_WIDE: /* 0x53 */ 2328 /* File: armv5te/OP_IGET_WIDE.S */ 2329 /* 2330 * Wide 32-bit instance field get. 2331 */ 2332 /* iget-wide vA, vB, field@CCCC */ 2333 mov r0, rINST, lsr #12 @ r0<- B 2334 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2335 FETCH(r1, 1) @ r1<- field ref CCCC 2336 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2337 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2338 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2339 cmp r0, #0 @ is resolved entry null? 2340 bne .LOP_IGET_WIDE_finish @ no, already resolved 2341 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2342 EXPORT_PC() @ resolve() could throw 2343 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2344 bl dvmResolveInstField @ r0<- resolved InstField ptr 2345 cmp r0, #0 2346 bne .LOP_IGET_WIDE_finish 2347 b common_exceptionThrown 2348 2349 /* ------------------------------ */ 2350 .balign 64 2351 .L_OP_IGET_OBJECT: /* 0x54 */ 2352 /* File: armv5te/OP_IGET_OBJECT.S */ 2353 /* File: armv5te/OP_IGET.S */ 2354 /* 2355 * General 32-bit instance field get. 2356 * 2357 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2358 */ 2359 /* op vA, vB, field@CCCC */ 2360 mov r0, rINST, lsr #12 @ r0<- B 2361 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2362 FETCH(r1, 1) @ r1<- field ref CCCC 2363 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2364 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2365 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2366 cmp r0, #0 @ is resolved entry null? 2367 bne .LOP_IGET_OBJECT_finish @ no, already resolved 2368 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2369 EXPORT_PC() @ resolve() could throw 2370 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2371 bl dvmResolveInstField @ r0<- resolved InstField ptr 2372 cmp r0, #0 2373 bne .LOP_IGET_OBJECT_finish 2374 b common_exceptionThrown 2375 2376 2377 /* ------------------------------ */ 2378 .balign 64 2379 .L_OP_IGET_BOOLEAN: /* 0x55 */ 2380 /* File: armv5te/OP_IGET_BOOLEAN.S */ 2381 @include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" } 2382 /* File: armv5te/OP_IGET.S */ 2383 /* 2384 * General 32-bit instance field get. 2385 * 2386 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2387 */ 2388 /* op vA, vB, field@CCCC */ 2389 mov r0, rINST, lsr #12 @ r0<- B 2390 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2391 FETCH(r1, 1) @ r1<- field ref CCCC 2392 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2393 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2394 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2395 cmp r0, #0 @ is resolved entry null? 2396 bne .LOP_IGET_BOOLEAN_finish @ no, already resolved 2397 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2398 EXPORT_PC() @ resolve() could throw 2399 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2400 bl dvmResolveInstField @ r0<- resolved InstField ptr 2401 cmp r0, #0 2402 bne .LOP_IGET_BOOLEAN_finish 2403 b common_exceptionThrown 2404 2405 2406 /* ------------------------------ */ 2407 .balign 64 2408 .L_OP_IGET_BYTE: /* 0x56 */ 2409 /* File: armv5te/OP_IGET_BYTE.S */ 2410 @include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" } 2411 /* File: armv5te/OP_IGET.S */ 2412 /* 2413 * General 32-bit instance field get. 2414 * 2415 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2416 */ 2417 /* op vA, vB, field@CCCC */ 2418 mov r0, rINST, lsr #12 @ r0<- B 2419 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2420 FETCH(r1, 1) @ r1<- field ref CCCC 2421 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2422 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2423 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2424 cmp r0, #0 @ is resolved entry null? 2425 bne .LOP_IGET_BYTE_finish @ no, already resolved 2426 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2427 EXPORT_PC() @ resolve() could throw 2428 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2429 bl dvmResolveInstField @ r0<- resolved InstField ptr 2430 cmp r0, #0 2431 bne .LOP_IGET_BYTE_finish 2432 b common_exceptionThrown 2433 2434 2435 /* ------------------------------ */ 2436 .balign 64 2437 .L_OP_IGET_CHAR: /* 0x57 */ 2438 /* File: armv5te/OP_IGET_CHAR.S */ 2439 @include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" } 2440 /* File: armv5te/OP_IGET.S */ 2441 /* 2442 * General 32-bit instance field get. 2443 * 2444 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2445 */ 2446 /* op vA, vB, field@CCCC */ 2447 mov r0, rINST, lsr #12 @ r0<- B 2448 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2449 FETCH(r1, 1) @ r1<- field ref CCCC 2450 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2451 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2452 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2453 cmp r0, #0 @ is resolved entry null? 2454 bne .LOP_IGET_CHAR_finish @ no, already resolved 2455 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2456 EXPORT_PC() @ resolve() could throw 2457 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2458 bl dvmResolveInstField @ r0<- resolved InstField ptr 2459 cmp r0, #0 2460 bne .LOP_IGET_CHAR_finish 2461 b common_exceptionThrown 2462 2463 2464 /* ------------------------------ */ 2465 .balign 64 2466 .L_OP_IGET_SHORT: /* 0x58 */ 2467 /* File: armv5te/OP_IGET_SHORT.S */ 2468 @include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" } 2469 /* File: armv5te/OP_IGET.S */ 2470 /* 2471 * General 32-bit instance field get. 2472 * 2473 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2474 */ 2475 /* op vA, vB, field@CCCC */ 2476 mov r0, rINST, lsr #12 @ r0<- B 2477 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2478 FETCH(r1, 1) @ r1<- field ref CCCC 2479 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2480 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2481 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2482 cmp r0, #0 @ is resolved entry null? 2483 bne .LOP_IGET_SHORT_finish @ no, already resolved 2484 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2485 EXPORT_PC() @ resolve() could throw 2486 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2487 bl dvmResolveInstField @ r0<- resolved InstField ptr 2488 cmp r0, #0 2489 bne .LOP_IGET_SHORT_finish 2490 b common_exceptionThrown 2491 2492 2493 /* ------------------------------ */ 2494 .balign 64 2495 .L_OP_IPUT: /* 0x59 */ 2496 /* File: armv5te/OP_IPUT.S */ 2497 /* 2498 * General 32-bit instance field put. 2499 * 2500 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2501 */ 2502 /* op vA, vB, field@CCCC */ 2503 mov r0, rINST, lsr #12 @ r0<- B 2504 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2505 FETCH(r1, 1) @ r1<- field ref CCCC 2506 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2507 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2508 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2509 cmp r0, #0 @ is resolved entry null? 2510 bne .LOP_IPUT_finish @ no, already resolved 2511 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2512 EXPORT_PC() @ resolve() could throw 2513 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2514 bl dvmResolveInstField @ r0<- resolved InstField ptr 2515 cmp r0, #0 @ success? 2516 bne .LOP_IPUT_finish @ yes, finish up 2517 b common_exceptionThrown 2518 2519 /* ------------------------------ */ 2520 .balign 64 2521 .L_OP_IPUT_WIDE: /* 0x5a */ 2522 /* File: armv5te/OP_IPUT_WIDE.S */ 2523 /* iput-wide vA, vB, field@CCCC */ 2524 mov r0, rINST, lsr #12 @ r0<- B 2525 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2526 FETCH(r1, 1) @ r1<- field ref CCCC 2527 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2528 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2529 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2530 cmp r0, #0 @ is resolved entry null? 2531 bne .LOP_IPUT_WIDE_finish @ no, already resolved 2532 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2533 EXPORT_PC() @ resolve() could throw 2534 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2535 bl dvmResolveInstField @ r0<- resolved InstField ptr 2536 cmp r0, #0 @ success? 2537 bne .LOP_IPUT_WIDE_finish @ yes, finish up 2538 b common_exceptionThrown 2539 2540 /* ------------------------------ */ 2541 .balign 64 2542 .L_OP_IPUT_OBJECT: /* 0x5b */ 2543 /* File: armv5te/OP_IPUT_OBJECT.S */ 2544 /* 2545 * 32-bit instance field put. 2546 * 2547 * for: iput-object, iput-object-volatile 2548 */ 2549 /* op vA, vB, field@CCCC */ 2550 mov r0, rINST, lsr #12 @ r0<- B 2551 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2552 FETCH(r1, 1) @ r1<- field ref CCCC 2553 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2554 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2555 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2556 cmp r0, #0 @ is resolved entry null? 2557 bne .LOP_IPUT_OBJECT_finish @ no, already resolved 2558 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2559 EXPORT_PC() @ resolve() could throw 2560 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2561 bl dvmResolveInstField @ r0<- resolved InstField ptr 2562 cmp r0, #0 @ success? 2563 bne .LOP_IPUT_OBJECT_finish @ yes, finish up 2564 b common_exceptionThrown 2565 2566 /* ------------------------------ */ 2567 .balign 64 2568 .L_OP_IPUT_BOOLEAN: /* 0x5c */ 2569 /* File: armv5te/OP_IPUT_BOOLEAN.S */ 2570 @include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" } 2571 /* File: armv5te/OP_IPUT.S */ 2572 /* 2573 * General 32-bit instance field put. 2574 * 2575 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2576 */ 2577 /* op vA, vB, field@CCCC */ 2578 mov r0, rINST, lsr #12 @ r0<- B 2579 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2580 FETCH(r1, 1) @ r1<- field ref CCCC 2581 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2582 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2583 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2584 cmp r0, #0 @ is resolved entry null? 2585 bne .LOP_IPUT_BOOLEAN_finish @ no, already resolved 2586 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2587 EXPORT_PC() @ resolve() could throw 2588 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2589 bl dvmResolveInstField @ r0<- resolved InstField ptr 2590 cmp r0, #0 @ success? 2591 bne .LOP_IPUT_BOOLEAN_finish @ yes, finish up 2592 b common_exceptionThrown 2593 2594 2595 /* ------------------------------ */ 2596 .balign 64 2597 .L_OP_IPUT_BYTE: /* 0x5d */ 2598 /* File: armv5te/OP_IPUT_BYTE.S */ 2599 @include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" } 2600 /* File: armv5te/OP_IPUT.S */ 2601 /* 2602 * General 32-bit instance field put. 2603 * 2604 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2605 */ 2606 /* op vA, vB, field@CCCC */ 2607 mov r0, rINST, lsr #12 @ r0<- B 2608 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2609 FETCH(r1, 1) @ r1<- field ref CCCC 2610 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2611 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2612 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2613 cmp r0, #0 @ is resolved entry null? 2614 bne .LOP_IPUT_BYTE_finish @ no, already resolved 2615 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2616 EXPORT_PC() @ resolve() could throw 2617 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2618 bl dvmResolveInstField @ r0<- resolved InstField ptr 2619 cmp r0, #0 @ success? 2620 bne .LOP_IPUT_BYTE_finish @ yes, finish up 2621 b common_exceptionThrown 2622 2623 2624 /* ------------------------------ */ 2625 .balign 64 2626 .L_OP_IPUT_CHAR: /* 0x5e */ 2627 /* File: armv5te/OP_IPUT_CHAR.S */ 2628 @include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" } 2629 /* File: armv5te/OP_IPUT.S */ 2630 /* 2631 * General 32-bit instance field put. 2632 * 2633 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2634 */ 2635 /* op vA, vB, field@CCCC */ 2636 mov r0, rINST, lsr #12 @ r0<- B 2637 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2638 FETCH(r1, 1) @ r1<- field ref CCCC 2639 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2640 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2641 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2642 cmp r0, #0 @ is resolved entry null? 2643 bne .LOP_IPUT_CHAR_finish @ no, already resolved 2644 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2645 EXPORT_PC() @ resolve() could throw 2646 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2647 bl dvmResolveInstField @ r0<- resolved InstField ptr 2648 cmp r0, #0 @ success? 2649 bne .LOP_IPUT_CHAR_finish @ yes, finish up 2650 b common_exceptionThrown 2651 2652 2653 /* ------------------------------ */ 2654 .balign 64 2655 .L_OP_IPUT_SHORT: /* 0x5f */ 2656 /* File: armv5te/OP_IPUT_SHORT.S */ 2657 @include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" } 2658 /* File: armv5te/OP_IPUT.S */ 2659 /* 2660 * General 32-bit instance field put. 2661 * 2662 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2663 */ 2664 /* op vA, vB, field@CCCC */ 2665 mov r0, rINST, lsr #12 @ r0<- B 2666 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2667 FETCH(r1, 1) @ r1<- field ref CCCC 2668 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2669 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2670 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2671 cmp r0, #0 @ is resolved entry null? 2672 bne .LOP_IPUT_SHORT_finish @ no, already resolved 2673 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2674 EXPORT_PC() @ resolve() could throw 2675 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2676 bl dvmResolveInstField @ r0<- resolved InstField ptr 2677 cmp r0, #0 @ success? 2678 bne .LOP_IPUT_SHORT_finish @ yes, finish up 2679 b common_exceptionThrown 2680 2681 2682 /* ------------------------------ */ 2683 .balign 64 2684 .L_OP_SGET: /* 0x60 */ 2685 /* File: armv5te/OP_SGET.S */ 2686 /* 2687 * General 32-bit SGET handler. 2688 * 2689 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2690 */ 2691 /* op vAA, field@BBBB */ 2692 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2693 FETCH(r1, 1) @ r1<- field ref BBBB 2694 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2695 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2696 cmp r0, #0 @ is resolved entry null? 2697 beq .LOP_SGET_resolve @ yes, do resolve 2698 .LOP_SGET_finish: @ field ptr in r0 2699 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2700 @ no-op @ acquiring load 2701 mov r2, rINST, lsr #8 @ r2<- AA 2702 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2703 SET_VREG(r1, r2) @ fp[AA]<- r1 2704 GET_INST_OPCODE(ip) @ extract opcode from rINST 2705 GOTO_OPCODE(ip) @ jump to next instruction 2706 2707 /* ------------------------------ */ 2708 .balign 64 2709 .L_OP_SGET_WIDE: /* 0x61 */ 2710 /* File: armv5te/OP_SGET_WIDE.S */ 2711 /* 2712 * 64-bit SGET handler. 2713 */ 2714 /* sget-wide vAA, field@BBBB */ 2715 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2716 FETCH(r1, 1) @ r1<- field ref BBBB 2717 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2718 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2719 cmp r0, #0 @ is resolved entry null? 2720 beq .LOP_SGET_WIDE_resolve @ yes, do resolve 2721 .LOP_SGET_WIDE_finish: 2722 mov r9, rINST, lsr #8 @ r9<- AA 2723 .if 0 2724 add r0, r0, #offStaticField_value @ r0<- pointer to data 2725 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 2726 .else 2727 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 2728 .endif 2729 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2730 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2731 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 2732 GET_INST_OPCODE(ip) @ extract opcode from rINST 2733 GOTO_OPCODE(ip) @ jump to next instruction 2734 2735 /* ------------------------------ */ 2736 .balign 64 2737 .L_OP_SGET_OBJECT: /* 0x62 */ 2738 /* File: armv5te/OP_SGET_OBJECT.S */ 2739 /* File: armv5te/OP_SGET.S */ 2740 /* 2741 * General 32-bit SGET handler. 2742 * 2743 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2744 */ 2745 /* op vAA, field@BBBB */ 2746 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2747 FETCH(r1, 1) @ r1<- field ref BBBB 2748 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2749 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2750 cmp r0, #0 @ is resolved entry null? 2751 beq .LOP_SGET_OBJECT_resolve @ yes, do resolve 2752 .LOP_SGET_OBJECT_finish: @ field ptr in r0 2753 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2754 @ no-op @ acquiring load 2755 mov r2, rINST, lsr #8 @ r2<- AA 2756 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2757 SET_VREG(r1, r2) @ fp[AA]<- r1 2758 GET_INST_OPCODE(ip) @ extract opcode from rINST 2759 GOTO_OPCODE(ip) @ jump to next instruction 2760 2761 2762 /* ------------------------------ */ 2763 .balign 64 2764 .L_OP_SGET_BOOLEAN: /* 0x63 */ 2765 /* File: armv5te/OP_SGET_BOOLEAN.S */ 2766 /* File: armv5te/OP_SGET.S */ 2767 /* 2768 * General 32-bit SGET handler. 2769 * 2770 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2771 */ 2772 /* op vAA, field@BBBB */ 2773 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2774 FETCH(r1, 1) @ r1<- field ref BBBB 2775 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2776 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2777 cmp r0, #0 @ is resolved entry null? 2778 beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve 2779 .LOP_SGET_BOOLEAN_finish: @ field ptr in r0 2780 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2781 @ no-op @ acquiring load 2782 mov r2, rINST, lsr #8 @ r2<- AA 2783 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2784 SET_VREG(r1, r2) @ fp[AA]<- r1 2785 GET_INST_OPCODE(ip) @ extract opcode from rINST 2786 GOTO_OPCODE(ip) @ jump to next instruction 2787 2788 2789 /* ------------------------------ */ 2790 .balign 64 2791 .L_OP_SGET_BYTE: /* 0x64 */ 2792 /* File: armv5te/OP_SGET_BYTE.S */ 2793 /* File: armv5te/OP_SGET.S */ 2794 /* 2795 * General 32-bit SGET handler. 2796 * 2797 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2798 */ 2799 /* op vAA, field@BBBB */ 2800 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2801 FETCH(r1, 1) @ r1<- field ref BBBB 2802 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2803 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2804 cmp r0, #0 @ is resolved entry null? 2805 beq .LOP_SGET_BYTE_resolve @ yes, do resolve 2806 .LOP_SGET_BYTE_finish: @ field ptr in r0 2807 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2808 @ no-op @ acquiring load 2809 mov r2, rINST, lsr #8 @ r2<- AA 2810 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2811 SET_VREG(r1, r2) @ fp[AA]<- r1 2812 GET_INST_OPCODE(ip) @ extract opcode from rINST 2813 GOTO_OPCODE(ip) @ jump to next instruction 2814 2815 2816 /* ------------------------------ */ 2817 .balign 64 2818 .L_OP_SGET_CHAR: /* 0x65 */ 2819 /* File: armv5te/OP_SGET_CHAR.S */ 2820 /* File: armv5te/OP_SGET.S */ 2821 /* 2822 * General 32-bit SGET handler. 2823 * 2824 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2825 */ 2826 /* op vAA, field@BBBB */ 2827 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2828 FETCH(r1, 1) @ r1<- field ref BBBB 2829 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2830 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2831 cmp r0, #0 @ is resolved entry null? 2832 beq .LOP_SGET_CHAR_resolve @ yes, do resolve 2833 .LOP_SGET_CHAR_finish: @ field ptr in r0 2834 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2835 @ no-op @ acquiring load 2836 mov r2, rINST, lsr #8 @ r2<- AA 2837 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2838 SET_VREG(r1, r2) @ fp[AA]<- r1 2839 GET_INST_OPCODE(ip) @ extract opcode from rINST 2840 GOTO_OPCODE(ip) @ jump to next instruction 2841 2842 2843 /* ------------------------------ */ 2844 .balign 64 2845 .L_OP_SGET_SHORT: /* 0x66 */ 2846 /* File: armv5te/OP_SGET_SHORT.S */ 2847 /* File: armv5te/OP_SGET.S */ 2848 /* 2849 * General 32-bit SGET handler. 2850 * 2851 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2852 */ 2853 /* op vAA, field@BBBB */ 2854 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2855 FETCH(r1, 1) @ r1<- field ref BBBB 2856 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2857 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2858 cmp r0, #0 @ is resolved entry null? 2859 beq .LOP_SGET_SHORT_resolve @ yes, do resolve 2860 .LOP_SGET_SHORT_finish: @ field ptr in r0 2861 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2862 @ no-op @ acquiring load 2863 mov r2, rINST, lsr #8 @ r2<- AA 2864 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2865 SET_VREG(r1, r2) @ fp[AA]<- r1 2866 GET_INST_OPCODE(ip) @ extract opcode from rINST 2867 GOTO_OPCODE(ip) @ jump to next instruction 2868 2869 2870 /* ------------------------------ */ 2871 .balign 64 2872 .L_OP_SPUT: /* 0x67 */ 2873 /* File: armv5te/OP_SPUT.S */ 2874 /* 2875 * General 32-bit SPUT handler. 2876 * 2877 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2878 */ 2879 /* op vAA, field@BBBB */ 2880 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2881 FETCH(r1, 1) @ r1<- field ref BBBB 2882 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2883 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2884 cmp r0, #0 @ is resolved entry null? 2885 beq .LOP_SPUT_resolve @ yes, do resolve 2886 .LOP_SPUT_finish: @ field ptr in r0 2887 mov r2, rINST, lsr #8 @ r2<- AA 2888 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2889 GET_VREG(r1, r2) @ r1<- fp[AA] 2890 GET_INST_OPCODE(ip) @ extract opcode from rINST 2891 @ no-op @ releasing store 2892 str r1, [r0, #offStaticField_value] @ field<- vAA 2893 @ no-op 2894 GOTO_OPCODE(ip) @ jump to next instruction 2895 2896 /* ------------------------------ */ 2897 .balign 64 2898 .L_OP_SPUT_WIDE: /* 0x68 */ 2899 /* File: armv5te/OP_SPUT_WIDE.S */ 2900 /* 2901 * 64-bit SPUT handler. 2902 */ 2903 /* sput-wide vAA, field@BBBB */ 2904 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- DvmDex 2905 FETCH(r1, 1) @ r1<- field ref BBBB 2906 ldr r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2907 mov r9, rINST, lsr #8 @ r9<- AA 2908 ldr r2, [r10, r1, lsl #2] @ r2<- resolved StaticField ptr 2909 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2910 cmp r2, #0 @ is resolved entry null? 2911 beq .LOP_SPUT_WIDE_resolve @ yes, do resolve 2912 .LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9 2913 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2914 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 2915 GET_INST_OPCODE(r10) @ extract opcode from rINST 2916 .if 0 2917 add r2, r2, #offStaticField_value @ r2<- pointer to data 2918 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 2919 .else 2920 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 2921 .endif 2922 GOTO_OPCODE(r10) @ jump to next instruction 2923 2924 /* ------------------------------ */ 2925 .balign 64 2926 .L_OP_SPUT_OBJECT: /* 0x69 */ 2927 /* File: armv5te/OP_SPUT_OBJECT.S */ 2928 /* 2929 * 32-bit SPUT handler for objects 2930 * 2931 * for: sput-object, sput-object-volatile 2932 */ 2933 /* op vAA, field@BBBB */ 2934 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2935 FETCH(r1, 1) @ r1<- field ref BBBB 2936 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2937 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2938 cmp r0, #0 @ is resolved entry null? 2939 beq .LOP_SPUT_OBJECT_resolve @ yes, do resolve 2940 .LOP_SPUT_OBJECT_finish: @ field ptr in r0 2941 mov r2, rINST, lsr #8 @ r2<- AA 2942 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2943 GET_VREG(r1, r2) @ r1<- fp[AA] 2944 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 2945 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 2946 GET_INST_OPCODE(ip) @ extract opcode from rINST 2947 @ no-op @ releasing store 2948 b .LOP_SPUT_OBJECT_end 2949 2950 /* ------------------------------ */ 2951 .balign 64 2952 .L_OP_SPUT_BOOLEAN: /* 0x6a */ 2953 /* File: armv5te/OP_SPUT_BOOLEAN.S */ 2954 /* File: armv5te/OP_SPUT.S */ 2955 /* 2956 * General 32-bit SPUT handler. 2957 * 2958 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2959 */ 2960 /* op vAA, field@BBBB */ 2961 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2962 FETCH(r1, 1) @ r1<- field ref BBBB 2963 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2964 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2965 cmp r0, #0 @ is resolved entry null? 2966 beq .LOP_SPUT_BOOLEAN_resolve @ yes, do resolve 2967 .LOP_SPUT_BOOLEAN_finish: @ field ptr in r0 2968 mov r2, rINST, lsr #8 @ r2<- AA 2969 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2970 GET_VREG(r1, r2) @ r1<- fp[AA] 2971 GET_INST_OPCODE(ip) @ extract opcode from rINST 2972 @ no-op @ releasing store 2973 str r1, [r0, #offStaticField_value] @ field<- vAA 2974 @ no-op 2975 GOTO_OPCODE(ip) @ jump to next instruction 2976 2977 2978 /* ------------------------------ */ 2979 .balign 64 2980 .L_OP_SPUT_BYTE: /* 0x6b */ 2981 /* File: armv5te/OP_SPUT_BYTE.S */ 2982 /* File: armv5te/OP_SPUT.S */ 2983 /* 2984 * General 32-bit SPUT handler. 2985 * 2986 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2987 */ 2988 /* op vAA, field@BBBB */ 2989 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2990 FETCH(r1, 1) @ r1<- field ref BBBB 2991 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2992 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2993 cmp r0, #0 @ is resolved entry null? 2994 beq .LOP_SPUT_BYTE_resolve @ yes, do resolve 2995 .LOP_SPUT_BYTE_finish: @ field ptr in r0 2996 mov r2, rINST, lsr #8 @ r2<- AA 2997 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2998 GET_VREG(r1, r2) @ r1<- fp[AA] 2999 GET_INST_OPCODE(ip) @ extract opcode from rINST 3000 @ no-op @ releasing store 3001 str r1, [r0, #offStaticField_value] @ field<- vAA 3002 @ no-op 3003 GOTO_OPCODE(ip) @ jump to next instruction 3004 3005 3006 /* ------------------------------ */ 3007 .balign 64 3008 .L_OP_SPUT_CHAR: /* 0x6c */ 3009 /* File: armv5te/OP_SPUT_CHAR.S */ 3010 /* File: armv5te/OP_SPUT.S */ 3011 /* 3012 * General 32-bit SPUT handler. 3013 * 3014 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3015 */ 3016 /* op vAA, field@BBBB */ 3017 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3018 FETCH(r1, 1) @ r1<- field ref BBBB 3019 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 3020 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 3021 cmp r0, #0 @ is resolved entry null? 3022 beq .LOP_SPUT_CHAR_resolve @ yes, do resolve 3023 .LOP_SPUT_CHAR_finish: @ field ptr in r0 3024 mov r2, rINST, lsr #8 @ r2<- AA 3025 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3026 GET_VREG(r1, r2) @ r1<- fp[AA] 3027 GET_INST_OPCODE(ip) @ extract opcode from rINST 3028 @ no-op @ releasing store 3029 str r1, [r0, #offStaticField_value] @ field<- vAA 3030 @ no-op 3031 GOTO_OPCODE(ip) @ jump to next instruction 3032 3033 3034 /* ------------------------------ */ 3035 .balign 64 3036 .L_OP_SPUT_SHORT: /* 0x6d */ 3037 /* File: armv5te/OP_SPUT_SHORT.S */ 3038 /* File: armv5te/OP_SPUT.S */ 3039 /* 3040 * General 32-bit SPUT handler. 3041 * 3042 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3043 */ 3044 /* op vAA, field@BBBB */ 3045 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3046 FETCH(r1, 1) @ r1<- field ref BBBB 3047 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 3048 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 3049 cmp r0, #0 @ is resolved entry null? 3050 beq .LOP_SPUT_SHORT_resolve @ yes, do resolve 3051 .LOP_SPUT_SHORT_finish: @ field ptr in r0 3052 mov r2, rINST, lsr #8 @ r2<- AA 3053 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3054 GET_VREG(r1, r2) @ r1<- fp[AA] 3055 GET_INST_OPCODE(ip) @ extract opcode from rINST 3056 @ no-op @ releasing store 3057 str r1, [r0, #offStaticField_value] @ field<- vAA 3058 @ no-op 3059 GOTO_OPCODE(ip) @ jump to next instruction 3060 3061 3062 /* ------------------------------ */ 3063 .balign 64 3064 .L_OP_INVOKE_VIRTUAL: /* 0x6e */ 3065 /* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3066 /* 3067 * Handle a virtual method call. 3068 * 3069 * for: invoke-virtual, invoke-virtual/range 3070 */ 3071 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3072 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3073 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3074 FETCH(r1, 1) @ r1<- BBBB 3075 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3076 FETCH(r10, 2) @ r10<- GFED or CCCC 3077 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3078 .if (!0) 3079 and r10, r10, #15 @ r10<- D (or stays CCCC) 3080 .endif 3081 cmp r0, #0 @ already resolved? 3082 EXPORT_PC() @ must export for invoke 3083 bne .LOP_INVOKE_VIRTUAL_continue @ yes, continue on 3084 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3085 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3086 mov r2, #METHOD_VIRTUAL @ resolver method type 3087 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3088 cmp r0, #0 @ got null? 3089 bne .LOP_INVOKE_VIRTUAL_continue @ no, continue 3090 b common_exceptionThrown @ yes, handle exception 3091 3092 /* ------------------------------ */ 3093 .balign 64 3094 .L_OP_INVOKE_SUPER: /* 0x6f */ 3095 /* File: armv5te/OP_INVOKE_SUPER.S */ 3096 /* 3097 * Handle a "super" method call. 3098 * 3099 * for: invoke-super, invoke-super/range 3100 */ 3101 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3102 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3103 FETCH(r10, 2) @ r10<- GFED or CCCC 3104 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3105 .if (!0) 3106 and r10, r10, #15 @ r10<- D (or stays CCCC) 3107 .endif 3108 FETCH(r1, 1) @ r1<- BBBB 3109 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3110 GET_VREG(r9, r10) @ r9<- "this" ptr 3111 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3112 cmp r9, #0 @ null "this"? 3113 ldr r10, [rSELF, #offThread_method] @ r10<- current method 3114 beq common_errNullObject @ null "this", throw exception 3115 cmp r0, #0 @ already resolved? 3116 ldr r10, [r10, #offMethod_clazz] @ r10<- method->clazz 3117 EXPORT_PC() @ must export for invoke 3118 bne .LOP_INVOKE_SUPER_continue @ resolved, continue on 3119 b .LOP_INVOKE_SUPER_resolve @ do resolve now 3120 3121 /* ------------------------------ */ 3122 .balign 64 3123 .L_OP_INVOKE_DIRECT: /* 0x70 */ 3124 /* File: armv5te/OP_INVOKE_DIRECT.S */ 3125 /* 3126 * Handle a direct method call. 3127 * 3128 * (We could defer the "is 'this' pointer null" test to the common 3129 * method invocation code, and use a flag to indicate that static 3130 * calls don't count. If we do this as part of copying the arguments 3131 * out we could avoiding loading the first arg twice.) 3132 * 3133 * for: invoke-direct, invoke-direct/range 3134 */ 3135 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3136 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3137 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3138 FETCH(r1, 1) @ r1<- BBBB 3139 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3140 FETCH(r10, 2) @ r10<- GFED or CCCC 3141 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3142 .if (!0) 3143 and r10, r10, #15 @ r10<- D (or stays CCCC) 3144 .endif 3145 cmp r0, #0 @ already resolved? 3146 EXPORT_PC() @ must export for invoke 3147 GET_VREG(r9, r10) @ r9<- "this" ptr 3148 beq .LOP_INVOKE_DIRECT_resolve @ not resolved, do it now 3149 .LOP_INVOKE_DIRECT_finish: 3150 cmp r9, #0 @ null "this" ref? 3151 bne common_invokeMethodNoRange @ r0=method, r9="this" 3152 b common_errNullObject @ yes, throw exception 3153 3154 /* ------------------------------ */ 3155 .balign 64 3156 .L_OP_INVOKE_STATIC: /* 0x71 */ 3157 /* File: armv5te/OP_INVOKE_STATIC.S */ 3158 /* 3159 * Handle a static method call. 3160 * 3161 * for: invoke-static, invoke-static/range 3162 */ 3163 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3164 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3165 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3166 FETCH(r1, 1) @ r1<- BBBB 3167 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3168 mov r9, #0 @ null "this" in delay slot 3169 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3170 #if defined(WITH_JIT) 3171 add r10, r3, r1, lsl #2 @ r10<- &resolved_methodToCall 3172 #endif 3173 cmp r0, #0 @ already resolved? 3174 EXPORT_PC() @ must export for invoke 3175 bne common_invokeMethodNoRange @ yes, continue on 3176 b .LOP_INVOKE_STATIC_resolve 3177 3178 /* ------------------------------ */ 3179 .balign 64 3180 .L_OP_INVOKE_INTERFACE: /* 0x72 */ 3181 /* File: armv5te/OP_INVOKE_INTERFACE.S */ 3182 /* 3183 * Handle an interface method call. 3184 * 3185 * for: invoke-interface, invoke-interface/range 3186 */ 3187 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3188 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3189 FETCH(r2, 2) @ r2<- FEDC or CCCC 3190 FETCH(r1, 1) @ r1<- BBBB 3191 .if (!0) 3192 and r2, r2, #15 @ r2<- C (or stays CCCC) 3193 .endif 3194 EXPORT_PC() @ must export for invoke 3195 GET_VREG(r9, r2) @ r9<- first arg ("this") 3196 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- methodClassDex 3197 cmp r9, #0 @ null obj? 3198 ldr r2, [rSELF, #offThread_method] @ r2<- method 3199 beq common_errNullObject @ yes, fail 3200 ldr r0, [r9, #offObject_clazz] @ r0<- thisPtr->clazz 3201 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3202 cmp r0, #0 @ failed? 3203 beq common_exceptionThrown @ yes, handle exception 3204 b common_invokeMethodNoRange @ (r0=method, r9="this") 3205 3206 /* ------------------------------ */ 3207 .balign 64 3208 .L_OP_UNUSED_73: /* 0x73 */ 3209 /* File: armv5te/OP_UNUSED_73.S */ 3210 /* File: armv5te/unused.S */ 3211 bl common_abort 3212 3213 3214 /* ------------------------------ */ 3215 .balign 64 3216 .L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 3217 /* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */ 3218 /* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3219 /* 3220 * Handle a virtual method call. 3221 * 3222 * for: invoke-virtual, invoke-virtual/range 3223 */ 3224 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3225 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3226 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3227 FETCH(r1, 1) @ r1<- BBBB 3228 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3229 FETCH(r10, 2) @ r10<- GFED or CCCC 3230 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3231 .if (!1) 3232 and r10, r10, #15 @ r10<- D (or stays CCCC) 3233 .endif 3234 cmp r0, #0 @ already resolved? 3235 EXPORT_PC() @ must export for invoke 3236 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ yes, continue on 3237 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3238 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3239 mov r2, #METHOD_VIRTUAL @ resolver method type 3240 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3241 cmp r0, #0 @ got null? 3242 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ no, continue 3243 b common_exceptionThrown @ yes, handle exception 3244 3245 3246 /* ------------------------------ */ 3247 .balign 64 3248 .L_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 3249 /* File: armv5te/OP_INVOKE_SUPER_RANGE.S */ 3250 /* File: armv5te/OP_INVOKE_SUPER.S */ 3251 /* 3252 * Handle a "super" method call. 3253 * 3254 * for: invoke-super, invoke-super/range 3255 */ 3256 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3257 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3258 FETCH(r10, 2) @ r10<- GFED or CCCC 3259 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3260 .if (!1) 3261 and r10, r10, #15 @ r10<- D (or stays CCCC) 3262 .endif 3263 FETCH(r1, 1) @ r1<- BBBB 3264 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3265 GET_VREG(r9, r10) @ r9<- "this" ptr 3266 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3267 cmp r9, #0 @ null "this"? 3268 ldr r10, [rSELF, #offThread_method] @ r10<- current method 3269 beq common_errNullObject @ null "this", throw exception 3270 cmp r0, #0 @ already resolved? 3271 ldr r10, [r10, #offMethod_clazz] @ r10<- method->clazz 3272 EXPORT_PC() @ must export for invoke 3273 bne .LOP_INVOKE_SUPER_RANGE_continue @ resolved, continue on 3274 b .LOP_INVOKE_SUPER_RANGE_resolve @ do resolve now 3275 3276 3277 /* ------------------------------ */ 3278 .balign 64 3279 .L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 3280 /* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */ 3281 /* File: armv5te/OP_INVOKE_DIRECT.S */ 3282 /* 3283 * Handle a direct method call. 3284 * 3285 * (We could defer the "is 'this' pointer null" test to the common 3286 * method invocation code, and use a flag to indicate that static 3287 * calls don't count. If we do this as part of copying the arguments 3288 * out we could avoiding loading the first arg twice.) 3289 * 3290 * for: invoke-direct, invoke-direct/range 3291 */ 3292 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3293 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3294 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3295 FETCH(r1, 1) @ r1<- BBBB 3296 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3297 FETCH(r10, 2) @ r10<- GFED or CCCC 3298 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3299 .if (!1) 3300 and r10, r10, #15 @ r10<- D (or stays CCCC) 3301 .endif 3302 cmp r0, #0 @ already resolved? 3303 EXPORT_PC() @ must export for invoke 3304 GET_VREG(r9, r10) @ r9<- "this" ptr 3305 beq .LOP_INVOKE_DIRECT_RANGE_resolve @ not resolved, do it now 3306 .LOP_INVOKE_DIRECT_RANGE_finish: 3307 cmp r9, #0 @ null "this" ref? 3308 bne common_invokeMethodRange @ r0=method, r9="this" 3309 b common_errNullObject @ yes, throw exception 3310 3311 3312 /* ------------------------------ */ 3313 .balign 64 3314 .L_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 3315 /* File: armv5te/OP_INVOKE_STATIC_RANGE.S */ 3316 /* File: armv5te/OP_INVOKE_STATIC.S */ 3317 /* 3318 * Handle a static method call. 3319 * 3320 * for: invoke-static, invoke-static/range 3321 */ 3322 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3323 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3324 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3325 FETCH(r1, 1) @ r1<- BBBB 3326 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3327 mov r9, #0 @ null "this" in delay slot 3328 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3329 #if defined(WITH_JIT) 3330 add r10, r3, r1, lsl #2 @ r10<- &resolved_methodToCall 3331 #endif 3332 cmp r0, #0 @ already resolved? 3333 EXPORT_PC() @ must export for invoke 3334 bne common_invokeMethodRange @ yes, continue on 3335 b .LOP_INVOKE_STATIC_RANGE_resolve 3336 3337 3338 /* ------------------------------ */ 3339 .balign 64 3340 .L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 3341 /* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */ 3342 /* File: armv5te/OP_INVOKE_INTERFACE.S */ 3343 /* 3344 * Handle an interface method call. 3345 * 3346 * for: invoke-interface, invoke-interface/range 3347 */ 3348 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3349 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3350 FETCH(r2, 2) @ r2<- FEDC or CCCC 3351 FETCH(r1, 1) @ r1<- BBBB 3352 .if (!1) 3353 and r2, r2, #15 @ r2<- C (or stays CCCC) 3354 .endif 3355 EXPORT_PC() @ must export for invoke 3356 GET_VREG(r9, r2) @ r9<- first arg ("this") 3357 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- methodClassDex 3358 cmp r9, #0 @ null obj? 3359 ldr r2, [rSELF, #offThread_method] @ r2<- method 3360 beq common_errNullObject @ yes, fail 3361 ldr r0, [r9, #offObject_clazz] @ r0<- thisPtr->clazz 3362 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3363 cmp r0, #0 @ failed? 3364 beq common_exceptionThrown @ yes, handle exception 3365 b common_invokeMethodRange @ (r0=method, r9="this") 3366 3367 3368 /* ------------------------------ */ 3369 .balign 64 3370 .L_OP_UNUSED_79: /* 0x79 */ 3371 /* File: armv5te/OP_UNUSED_79.S */ 3372 /* File: armv5te/unused.S */ 3373 bl common_abort 3374 3375 3376 /* ------------------------------ */ 3377 .balign 64 3378 .L_OP_UNUSED_7A: /* 0x7a */ 3379 /* File: armv5te/OP_UNUSED_7A.S */ 3380 /* File: armv5te/unused.S */ 3381 bl common_abort 3382 3383 3384 /* ------------------------------ */ 3385 .balign 64 3386 .L_OP_NEG_INT: /* 0x7b */ 3387 /* File: armv5te/OP_NEG_INT.S */ 3388 /* File: armv5te/unop.S */ 3389 /* 3390 * Generic 32-bit unary operation. Provide an "instr" line that 3391 * specifies an instruction that performs "result = op r0". 3392 * This could be an ARM instruction or a function call. 3393 * 3394 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3395 * int-to-byte, int-to-char, int-to-short 3396 */ 3397 /* unop vA, vB */ 3398 mov r3, rINST, lsr #12 @ r3<- B 3399 mov r9, rINST, lsr #8 @ r9<- A+ 3400 GET_VREG(r0, r3) @ r0<- vB 3401 and r9, r9, #15 3402 @ optional op; may set condition codes 3403 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3404 rsb r0, r0, #0 @ r0<- op, r0-r3 changed 3405 GET_INST_OPCODE(ip) @ extract opcode from rINST 3406 SET_VREG(r0, r9) @ vAA<- r0 3407 GOTO_OPCODE(ip) @ jump to next instruction 3408 /* 9-10 instructions */ 3409 3410 3411 /* ------------------------------ */ 3412 .balign 64 3413 .L_OP_NOT_INT: /* 0x7c */ 3414 /* File: armv5te/OP_NOT_INT.S */ 3415 /* File: armv5te/unop.S */ 3416 /* 3417 * Generic 32-bit unary operation. Provide an "instr" line that 3418 * specifies an instruction that performs "result = op r0". 3419 * This could be an ARM instruction or a function call. 3420 * 3421 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3422 * int-to-byte, int-to-char, int-to-short 3423 */ 3424 /* unop vA, vB */ 3425 mov r3, rINST, lsr #12 @ r3<- B 3426 mov r9, rINST, lsr #8 @ r9<- A+ 3427 GET_VREG(r0, r3) @ r0<- vB 3428 and r9, r9, #15 3429 @ optional op; may set condition codes 3430 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3431 mvn r0, r0 @ r0<- op, r0-r3 changed 3432 GET_INST_OPCODE(ip) @ extract opcode from rINST 3433 SET_VREG(r0, r9) @ vAA<- r0 3434 GOTO_OPCODE(ip) @ jump to next instruction 3435 /* 9-10 instructions */ 3436 3437 3438 /* ------------------------------ */ 3439 .balign 64 3440 .L_OP_NEG_LONG: /* 0x7d */ 3441 /* File: armv5te/OP_NEG_LONG.S */ 3442 /* File: armv5te/unopWide.S */ 3443 /* 3444 * Generic 64-bit unary operation. Provide an "instr" line that 3445 * specifies an instruction that performs "result = op r0/r1". 3446 * This could be an ARM instruction or a function call. 3447 * 3448 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3449 */ 3450 /* unop vA, vB */ 3451 mov r9, rINST, lsr #8 @ r9<- A+ 3452 mov r3, rINST, lsr #12 @ r3<- B 3453 and r9, r9, #15 3454 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3455 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3456 ldmia r3, {r0-r1} @ r0/r1<- vAA 3457 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3458 rsbs r0, r0, #0 @ optional op; may set condition codes 3459 rsc r1, r1, #0 @ r0/r1<- op, r2-r3 changed 3460 GET_INST_OPCODE(ip) @ extract opcode from rINST 3461 stmia r9, {r0-r1} @ vAA<- r0/r1 3462 GOTO_OPCODE(ip) @ jump to next instruction 3463 /* 12-13 instructions */ 3464 3465 3466 /* ------------------------------ */ 3467 .balign 64 3468 .L_OP_NOT_LONG: /* 0x7e */ 3469 /* File: armv5te/OP_NOT_LONG.S */ 3470 /* File: armv5te/unopWide.S */ 3471 /* 3472 * Generic 64-bit unary operation. Provide an "instr" line that 3473 * specifies an instruction that performs "result = op r0/r1". 3474 * This could be an ARM instruction or a function call. 3475 * 3476 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3477 */ 3478 /* unop vA, vB */ 3479 mov r9, rINST, lsr #8 @ r9<- A+ 3480 mov r3, rINST, lsr #12 @ r3<- B 3481 and r9, r9, #15 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 /* 12-13 instructions */ 3492 3493 3494 /* ------------------------------ */ 3495 .balign 64 3496 .L_OP_NEG_FLOAT: /* 0x7f */ 3497 /* File: armv5te/OP_NEG_FLOAT.S */ 3498 /* File: armv5te/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 mov r9, rINST, lsr #8 @ r9<- A+ 3510 GET_VREG(r0, r3) @ r0<- vB 3511 and r9, r9, #15 3512 @ optional op; may set condition codes 3513 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3514 add r0, r0, #0x80000000 @ r0<- op, r0-r3 changed 3515 GET_INST_OPCODE(ip) @ extract opcode from rINST 3516 SET_VREG(r0, r9) @ vAA<- r0 3517 GOTO_OPCODE(ip) @ jump to next instruction 3518 /* 9-10 instructions */ 3519 3520 3521 /* ------------------------------ */ 3522 .balign 64 3523 .L_OP_NEG_DOUBLE: /* 0x80 */ 3524 /* File: armv5te/OP_NEG_DOUBLE.S */ 3525 /* File: armv5te/unopWide.S */ 3526 /* 3527 * Generic 64-bit unary operation. Provide an "instr" line that 3528 * specifies an instruction that performs "result = op r0/r1". 3529 * This could be an ARM instruction or a function call. 3530 * 3531 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3532 */ 3533 /* unop vA, vB */ 3534 mov r9, rINST, lsr #8 @ r9<- A+ 3535 mov r3, rINST, lsr #12 @ r3<- B 3536 and r9, r9, #15 3537 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3538 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3539 ldmia r3, {r0-r1} @ r0/r1<- vAA 3540 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3541 @ optional op; may set condition codes 3542 add r1, r1, #0x80000000 @ r0/r1<- op, r2-r3 changed 3543 GET_INST_OPCODE(ip) @ extract opcode from rINST 3544 stmia r9, {r0-r1} @ vAA<- r0/r1 3545 GOTO_OPCODE(ip) @ jump to next instruction 3546 /* 12-13 instructions */ 3547 3548 3549 /* ------------------------------ */ 3550 .balign 64 3551 .L_OP_INT_TO_LONG: /* 0x81 */ 3552 /* File: armv5te/OP_INT_TO_LONG.S */ 3553 /* File: armv5te/unopWider.S */ 3554 /* 3555 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3556 * that specifies an instruction that performs "result = op r0", where 3557 * "result" is a 64-bit quantity in r0/r1. 3558 * 3559 * For: int-to-long, int-to-double, float-to-long, float-to-double 3560 */ 3561 /* unop vA, vB */ 3562 mov r9, rINST, lsr #8 @ r9<- A+ 3563 mov r3, rINST, lsr #12 @ r3<- B 3564 and r9, r9, #15 3565 GET_VREG(r0, r3) @ r0<- vB 3566 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3567 @ optional op; may set condition codes 3568 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3569 mov r1, r0, asr #31 @ r0<- op, r0-r3 changed 3570 GET_INST_OPCODE(ip) @ extract opcode from rINST 3571 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3572 GOTO_OPCODE(ip) @ jump to next instruction 3573 /* 10-11 instructions */ 3574 3575 3576 /* ------------------------------ */ 3577 .balign 64 3578 .L_OP_INT_TO_FLOAT: /* 0x82 */ 3579 /* File: arm-vfp/OP_INT_TO_FLOAT.S */ 3580 /* File: arm-vfp/funop.S */ 3581 /* 3582 * Generic 32-bit unary floating-point operation. Provide an "instr" 3583 * line that specifies an instruction that performs "s1 = op s0". 3584 * 3585 * for: int-to-float, float-to-int 3586 */ 3587 /* unop vA, vB */ 3588 mov r3, rINST, lsr #12 @ r3<- B 3589 mov r9, rINST, lsr #8 @ r9<- A+ 3590 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3591 flds s0, [r3] @ s0<- vB 3592 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3593 and r9, r9, #15 @ r9<- A 3594 fsitos s1, s0 @ s1<- op 3595 GET_INST_OPCODE(ip) @ extract opcode from rINST 3596 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3597 fsts s1, [r9] @ vA<- s1 3598 GOTO_OPCODE(ip) @ jump to next instruction 3599 3600 3601 /* ------------------------------ */ 3602 .balign 64 3603 .L_OP_INT_TO_DOUBLE: /* 0x83 */ 3604 /* File: arm-vfp/OP_INT_TO_DOUBLE.S */ 3605 /* File: arm-vfp/funopWider.S */ 3606 /* 3607 * Generic 32bit-to-64bit floating point unary operation. Provide an 3608 * "instr" line that specifies an instruction that performs "d0 = op s0". 3609 * 3610 * For: int-to-double, float-to-double 3611 */ 3612 /* unop vA, vB */ 3613 mov r3, rINST, lsr #12 @ r3<- B 3614 mov r9, rINST, lsr #8 @ r9<- A+ 3615 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3616 flds s0, [r3] @ s0<- vB 3617 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3618 and r9, r9, #15 @ r9<- A 3619 fsitod d0, s0 @ d0<- op 3620 GET_INST_OPCODE(ip) @ extract opcode from rINST 3621 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3622 fstd d0, [r9] @ vA<- d0 3623 GOTO_OPCODE(ip) @ jump to next instruction 3624 3625 3626 /* ------------------------------ */ 3627 .balign 64 3628 .L_OP_LONG_TO_INT: /* 0x84 */ 3629 /* File: armv5te/OP_LONG_TO_INT.S */ 3630 /* we ignore the high word, making this equivalent to a 32-bit reg move */ 3631 /* File: armv5te/OP_MOVE.S */ 3632 /* for move, move-object, long-to-int */ 3633 /* op vA, vB */ 3634 mov r1, rINST, lsr #12 @ r1<- B from 15:12 3635 mov r0, rINST, lsr #8 @ r0<- A from 11:8 3636 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3637 GET_VREG(r2, r1) @ r2<- fp[B] 3638 and r0, r0, #15 3639 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 3640 SET_VREG(r2, r0) @ fp[A]<- r2 3641 GOTO_OPCODE(ip) @ execute next instruction 3642 3643 3644 /* ------------------------------ */ 3645 .balign 64 3646 .L_OP_LONG_TO_FLOAT: /* 0x85 */ 3647 /* File: armv5te/OP_LONG_TO_FLOAT.S */ 3648 /* File: armv5te/unopNarrower.S */ 3649 /* 3650 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 3651 * that specifies an instruction that performs "result = op r0/r1", where 3652 * "result" is a 32-bit quantity in r0. 3653 * 3654 * For: long-to-float, double-to-int, double-to-float 3655 * 3656 * (This would work for long-to-int, but that instruction is actually 3657 * an exact match for OP_MOVE.) 3658 */ 3659 /* unop vA, vB */ 3660 mov r3, rINST, lsr #12 @ r3<- B 3661 mov r9, rINST, lsr #8 @ r9<- A+ 3662 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3663 and r9, r9, #15 3664 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 3665 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3666 @ optional op; may set condition codes 3667 bl __aeabi_l2f @ r0<- op, r0-r3 changed 3668 GET_INST_OPCODE(ip) @ extract opcode from rINST 3669 SET_VREG(r0, r9) @ vA<- r0 3670 GOTO_OPCODE(ip) @ jump to next instruction 3671 /* 10-11 instructions */ 3672 3673 3674 /* ------------------------------ */ 3675 .balign 64 3676 .L_OP_LONG_TO_DOUBLE: /* 0x86 */ 3677 /* File: armv5te/OP_LONG_TO_DOUBLE.S */ 3678 /* File: armv5te/unopWide.S */ 3679 /* 3680 * Generic 64-bit unary operation. Provide an "instr" line that 3681 * specifies an instruction that performs "result = op r0/r1". 3682 * This could be an ARM instruction or a function call. 3683 * 3684 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3685 */ 3686 /* unop vA, vB */ 3687 mov r9, rINST, lsr #8 @ r9<- A+ 3688 mov r3, rINST, lsr #12 @ r3<- B 3689 and r9, r9, #15 3690 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3691 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3692 ldmia r3, {r0-r1} @ r0/r1<- vAA 3693 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3694 @ optional op; may set condition codes 3695 bl __aeabi_l2d @ r0/r1<- op, r2-r3 changed 3696 GET_INST_OPCODE(ip) @ extract opcode from rINST 3697 stmia r9, {r0-r1} @ vAA<- r0/r1 3698 GOTO_OPCODE(ip) @ jump to next instruction 3699 /* 12-13 instructions */ 3700 3701 3702 /* ------------------------------ */ 3703 .balign 64 3704 .L_OP_FLOAT_TO_INT: /* 0x87 */ 3705 /* File: arm-vfp/OP_FLOAT_TO_INT.S */ 3706 /* File: arm-vfp/funop.S */ 3707 /* 3708 * Generic 32-bit unary floating-point operation. Provide an "instr" 3709 * line that specifies an instruction that performs "s1 = op s0". 3710 * 3711 * for: int-to-float, float-to-int 3712 */ 3713 /* unop vA, vB */ 3714 mov r3, rINST, lsr #12 @ r3<- B 3715 mov r9, rINST, lsr #8 @ r9<- A+ 3716 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3717 flds s0, [r3] @ s0<- vB 3718 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3719 and r9, r9, #15 @ r9<- A 3720 ftosizs s1, s0 @ s1<- op 3721 GET_INST_OPCODE(ip) @ extract opcode from rINST 3722 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3723 fsts s1, [r9] @ vA<- s1 3724 GOTO_OPCODE(ip) @ jump to next instruction 3725 3726 3727 /* ------------------------------ */ 3728 .balign 64 3729 .L_OP_FLOAT_TO_LONG: /* 0x88 */ 3730 /* File: armv5te/OP_FLOAT_TO_LONG.S */ 3731 @include "armv5te/unopWider.S" {"instr":"bl __aeabi_f2lz"} 3732 /* File: armv5te/unopWider.S */ 3733 /* 3734 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3735 * that specifies an instruction that performs "result = op r0", where 3736 * "result" is a 64-bit quantity in r0/r1. 3737 * 3738 * For: int-to-long, int-to-double, float-to-long, float-to-double 3739 */ 3740 /* unop vA, vB */ 3741 mov r9, rINST, lsr #8 @ r9<- A+ 3742 mov r3, rINST, lsr #12 @ r3<- B 3743 and r9, r9, #15 3744 GET_VREG(r0, r3) @ r0<- vB 3745 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3746 @ optional op; may set condition codes 3747 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3748 bl f2l_doconv @ r0<- op, r0-r3 changed 3749 GET_INST_OPCODE(ip) @ extract opcode from rINST 3750 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3751 GOTO_OPCODE(ip) @ jump to next instruction 3752 /* 10-11 instructions */ 3753 3754 3755 3756 /* ------------------------------ */ 3757 .balign 64 3758 .L_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 3759 /* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */ 3760 /* File: arm-vfp/funopWider.S */ 3761 /* 3762 * Generic 32bit-to-64bit floating point unary operation. Provide an 3763 * "instr" line that specifies an instruction that performs "d0 = op s0". 3764 * 3765 * For: int-to-double, float-to-double 3766 */ 3767 /* unop vA, vB */ 3768 mov r3, rINST, lsr #12 @ r3<- B 3769 mov r9, rINST, lsr #8 @ r9<- A+ 3770 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3771 flds s0, [r3] @ s0<- vB 3772 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3773 and r9, r9, #15 @ r9<- A 3774 fcvtds d0, s0 @ d0<- op 3775 GET_INST_OPCODE(ip) @ extract opcode from rINST 3776 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3777 fstd d0, [r9] @ vA<- d0 3778 GOTO_OPCODE(ip) @ jump to next instruction 3779 3780 3781 /* ------------------------------ */ 3782 .balign 64 3783 .L_OP_DOUBLE_TO_INT: /* 0x8a */ 3784 /* File: arm-vfp/OP_DOUBLE_TO_INT.S */ 3785 /* File: arm-vfp/funopNarrower.S */ 3786 /* 3787 * Generic 64bit-to-32bit unary floating point operation. Provide an 3788 * "instr" line that specifies an instruction that performs "s0 = op d0". 3789 * 3790 * For: double-to-int, double-to-float 3791 */ 3792 /* unop vA, vB */ 3793 mov r3, rINST, lsr #12 @ r3<- B 3794 mov r9, rINST, lsr #8 @ r9<- A+ 3795 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3796 fldd d0, [r3] @ d0<- vB 3797 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3798 and r9, r9, #15 @ r9<- A 3799 ftosizd s0, d0 @ s0<- op 3800 GET_INST_OPCODE(ip) @ extract opcode from rINST 3801 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3802 fsts s0, [r9] @ vA<- s0 3803 GOTO_OPCODE(ip) @ jump to next instruction 3804 3805 3806 /* ------------------------------ */ 3807 .balign 64 3808 .L_OP_DOUBLE_TO_LONG: /* 0x8b */ 3809 /* File: armv5te/OP_DOUBLE_TO_LONG.S */ 3810 @include "armv5te/unopWide.S" {"instr":"bl __aeabi_d2lz"} 3811 /* File: armv5te/unopWide.S */ 3812 /* 3813 * Generic 64-bit unary operation. Provide an "instr" line that 3814 * specifies an instruction that performs "result = op r0/r1". 3815 * This could be an ARM instruction or a function call. 3816 * 3817 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3818 */ 3819 /* unop vA, vB */ 3820 mov r9, rINST, lsr #8 @ r9<- A+ 3821 mov r3, rINST, lsr #12 @ r3<- B 3822 and r9, r9, #15 3823 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3824 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3825 ldmia r3, {r0-r1} @ r0/r1<- vAA 3826 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3827 @ optional op; may set condition codes 3828 bl d2l_doconv @ r0/r1<- op, r2-r3 changed 3829 GET_INST_OPCODE(ip) @ extract opcode from rINST 3830 stmia r9, {r0-r1} @ vAA<- r0/r1 3831 GOTO_OPCODE(ip) @ jump to next instruction 3832 /* 12-13 instructions */ 3833 3834 3835 3836 /* ------------------------------ */ 3837 .balign 64 3838 .L_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 3839 /* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */ 3840 /* File: arm-vfp/funopNarrower.S */ 3841 /* 3842 * Generic 64bit-to-32bit unary floating point operation. Provide an 3843 * "instr" line that specifies an instruction that performs "s0 = op d0". 3844 * 3845 * For: double-to-int, double-to-float 3846 */ 3847 /* unop vA, vB */ 3848 mov r3, rINST, lsr #12 @ r3<- B 3849 mov r9, rINST, lsr #8 @ r9<- A+ 3850 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3851 fldd d0, [r3] @ d0<- vB 3852 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3853 and r9, r9, #15 @ r9<- A 3854 fcvtsd s0, d0 @ s0<- op 3855 GET_INST_OPCODE(ip) @ extract opcode from rINST 3856 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3857 fsts s0, [r9] @ vA<- s0 3858 GOTO_OPCODE(ip) @ jump to next instruction 3859 3860 3861 /* ------------------------------ */ 3862 .balign 64 3863 .L_OP_INT_TO_BYTE: /* 0x8d */ 3864 /* File: armv5te/OP_INT_TO_BYTE.S */ 3865 /* File: armv5te/unop.S */ 3866 /* 3867 * Generic 32-bit unary operation. Provide an "instr" line that 3868 * specifies an instruction that performs "result = op r0". 3869 * This could be an ARM instruction or a function call. 3870 * 3871 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3872 * int-to-byte, int-to-char, int-to-short 3873 */ 3874 /* unop vA, vB */ 3875 mov r3, rINST, lsr #12 @ r3<- B 3876 mov r9, rINST, lsr #8 @ r9<- A+ 3877 GET_VREG(r0, r3) @ r0<- vB 3878 and r9, r9, #15 3879 mov r0, r0, asl #24 @ optional op; may set condition codes 3880 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3881 mov r0, r0, asr #24 @ r0<- op, r0-r3 changed 3882 GET_INST_OPCODE(ip) @ extract opcode from rINST 3883 SET_VREG(r0, r9) @ vAA<- r0 3884 GOTO_OPCODE(ip) @ jump to next instruction 3885 /* 9-10 instructions */ 3886 3887 3888 /* ------------------------------ */ 3889 .balign 64 3890 .L_OP_INT_TO_CHAR: /* 0x8e */ 3891 /* File: armv5te/OP_INT_TO_CHAR.S */ 3892 /* File: armv5te/unop.S */ 3893 /* 3894 * Generic 32-bit unary operation. Provide an "instr" line that 3895 * specifies an instruction that performs "result = op r0". 3896 * This could be an ARM instruction or a function call. 3897 * 3898 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3899 * int-to-byte, int-to-char, int-to-short 3900 */ 3901 /* unop vA, vB */ 3902 mov r3, rINST, lsr #12 @ r3<- B 3903 mov r9, rINST, lsr #8 @ r9<- A+ 3904 GET_VREG(r0, r3) @ r0<- vB 3905 and r9, r9, #15 3906 mov r0, r0, asl #16 @ optional op; may set condition codes 3907 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3908 mov r0, r0, lsr #16 @ r0<- op, r0-r3 changed 3909 GET_INST_OPCODE(ip) @ extract opcode from rINST 3910 SET_VREG(r0, r9) @ vAA<- r0 3911 GOTO_OPCODE(ip) @ jump to next instruction 3912 /* 9-10 instructions */ 3913 3914 3915 /* ------------------------------ */ 3916 .balign 64 3917 .L_OP_INT_TO_SHORT: /* 0x8f */ 3918 /* File: armv5te/OP_INT_TO_SHORT.S */ 3919 /* File: armv5te/unop.S */ 3920 /* 3921 * Generic 32-bit unary operation. Provide an "instr" line that 3922 * specifies an instruction that performs "result = op r0". 3923 * This could be an ARM instruction or a function call. 3924 * 3925 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3926 * int-to-byte, int-to-char, int-to-short 3927 */ 3928 /* unop vA, vB */ 3929 mov r3, rINST, lsr #12 @ r3<- B 3930 mov r9, rINST, lsr #8 @ r9<- A+ 3931 GET_VREG(r0, r3) @ r0<- vB 3932 and r9, r9, #15 3933 mov r0, r0, asl #16 @ optional op; may set condition codes 3934 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3935 mov r0, r0, asr #16 @ r0<- op, r0-r3 changed 3936 GET_INST_OPCODE(ip) @ extract opcode from rINST 3937 SET_VREG(r0, r9) @ vAA<- r0 3938 GOTO_OPCODE(ip) @ jump to next instruction 3939 /* 9-10 instructions */ 3940 3941 3942 /* ------------------------------ */ 3943 .balign 64 3944 .L_OP_ADD_INT: /* 0x90 */ 3945 /* File: armv5te/OP_ADD_INT.S */ 3946 /* File: armv5te/binop.S */ 3947 /* 3948 * Generic 32-bit binary operation. Provide an "instr" line that 3949 * specifies an instruction that performs "result = r0 op r1". 3950 * This could be an ARM instruction or a function call. (If the result 3951 * comes back in a register other than r0, you can override "result".) 3952 * 3953 * If "chkzero" is set to 1, we perform a divide-by-zero check on 3954 * vCC (r1). Useful for integer division and modulus. Note that we 3955 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 3956 * handles it correctly. 3957 * 3958 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 3959 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 3960 * mul-float, div-float, rem-float 3961 */ 3962 /* binop vAA, vBB, vCC */ 3963 FETCH(r0, 1) @ r0<- CCBB 3964 mov r9, rINST, lsr #8 @ r9<- AA 3965 mov r3, r0, lsr #8 @ r3<- CC 3966 and r2, r0, #255 @ r2<- BB 3967 GET_VREG(r1, r3) @ r1<- vCC 3968 GET_VREG(r0, r2) @ r0<- vBB 3969 .if 0 3970 cmp r1, #0 @ is second operand zero? 3971 beq common_errDivideByZero 3972 .endif 3973 3974 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3975 @ optional op; may set condition codes 3976 add r0, r0, r1 @ r0<- op, r0-r3 changed 3977 GET_INST_OPCODE(ip) @ extract opcode from rINST 3978 SET_VREG(r0, r9) @ vAA<- r0 3979 GOTO_OPCODE(ip) @ jump to next instruction 3980 /* 11-14 instructions */ 3981 3982 3983 /* ------------------------------ */ 3984 .balign 64 3985 .L_OP_SUB_INT: /* 0x91 */ 3986 /* File: armv5te/OP_SUB_INT.S */ 3987 /* File: armv5te/binop.S */ 3988 /* 3989 * Generic 32-bit binary operation. Provide an "instr" line that 3990 * specifies an instruction that performs "result = r0 op r1". 3991 * This could be an ARM instruction or a function call. (If the result 3992 * comes back in a register other than r0, you can override "result".) 3993 * 3994 * If "chkzero" is set to 1, we perform a divide-by-zero check on 3995 * vCC (r1). Useful for integer division and modulus. Note that we 3996 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 3997 * handles it correctly. 3998 * 3999 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4000 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4001 * mul-float, div-float, rem-float 4002 */ 4003 /* binop vAA, vBB, vCC */ 4004 FETCH(r0, 1) @ r0<- CCBB 4005 mov r9, rINST, lsr #8 @ r9<- AA 4006 mov r3, r0, lsr #8 @ r3<- CC 4007 and r2, r0, #255 @ r2<- BB 4008 GET_VREG(r1, r3) @ r1<- vCC 4009 GET_VREG(r0, r2) @ r0<- vBB 4010 .if 0 4011 cmp r1, #0 @ is second operand zero? 4012 beq common_errDivideByZero 4013 .endif 4014 4015 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4016 @ optional op; may set condition codes 4017 sub r0, r0, r1 @ r0<- op, r0-r3 changed 4018 GET_INST_OPCODE(ip) @ extract opcode from rINST 4019 SET_VREG(r0, r9) @ vAA<- r0 4020 GOTO_OPCODE(ip) @ jump to next instruction 4021 /* 11-14 instructions */ 4022 4023 4024 /* ------------------------------ */ 4025 .balign 64 4026 .L_OP_MUL_INT: /* 0x92 */ 4027 /* File: armv5te/OP_MUL_INT.S */ 4028 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 4029 /* File: armv5te/binop.S */ 4030 /* 4031 * Generic 32-bit binary operation. Provide an "instr" line that 4032 * specifies an instruction that performs "result = r0 op r1". 4033 * This could be an ARM instruction or a function call. (If the result 4034 * comes back in a register other than r0, you can override "result".) 4035 * 4036 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4037 * vCC (r1). Useful for integer division and modulus. Note that we 4038 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4039 * handles it correctly. 4040 * 4041 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4042 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4043 * mul-float, div-float, rem-float 4044 */ 4045 /* binop vAA, vBB, vCC */ 4046 FETCH(r0, 1) @ r0<- CCBB 4047 mov r9, rINST, lsr #8 @ r9<- AA 4048 mov r3, r0, lsr #8 @ r3<- CC 4049 and r2, r0, #255 @ r2<- BB 4050 GET_VREG(r1, r3) @ r1<- vCC 4051 GET_VREG(r0, r2) @ r0<- vBB 4052 .if 0 4053 cmp r1, #0 @ is second operand zero? 4054 beq common_errDivideByZero 4055 .endif 4056 4057 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4058 @ optional op; may set condition codes 4059 mul r0, r1, r0 @ r0<- op, r0-r3 changed 4060 GET_INST_OPCODE(ip) @ extract opcode from rINST 4061 SET_VREG(r0, r9) @ vAA<- r0 4062 GOTO_OPCODE(ip) @ jump to next instruction 4063 /* 11-14 instructions */ 4064 4065 4066 /* ------------------------------ */ 4067 .balign 64 4068 .L_OP_DIV_INT: /* 0x93 */ 4069 /* File: armv5te/OP_DIV_INT.S */ 4070 /* File: armv5te/binop.S */ 4071 /* 4072 * Generic 32-bit binary operation. Provide an "instr" line that 4073 * specifies an instruction that performs "result = r0 op r1". 4074 * This could be an ARM instruction or a function call. (If the result 4075 * comes back in a register other than r0, you can override "result".) 4076 * 4077 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4078 * vCC (r1). Useful for integer division and modulus. Note that we 4079 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4080 * handles it correctly. 4081 * 4082 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4083 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4084 * mul-float, div-float, rem-float 4085 */ 4086 /* binop vAA, vBB, vCC */ 4087 FETCH(r0, 1) @ r0<- CCBB 4088 mov r9, rINST, lsr #8 @ r9<- AA 4089 mov r3, r0, lsr #8 @ r3<- CC 4090 and r2, r0, #255 @ r2<- BB 4091 GET_VREG(r1, r3) @ r1<- vCC 4092 GET_VREG(r0, r2) @ r0<- vBB 4093 .if 1 4094 cmp r1, #0 @ is second operand zero? 4095 beq common_errDivideByZero 4096 .endif 4097 4098 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4099 @ optional op; may set condition codes 4100 bl __aeabi_idiv @ r0<- op, r0-r3 changed 4101 GET_INST_OPCODE(ip) @ extract opcode from rINST 4102 SET_VREG(r0, r9) @ vAA<- r0 4103 GOTO_OPCODE(ip) @ jump to next instruction 4104 /* 11-14 instructions */ 4105 4106 4107 /* ------------------------------ */ 4108 .balign 64 4109 .L_OP_REM_INT: /* 0x94 */ 4110 /* File: armv5te/OP_REM_INT.S */ 4111 /* idivmod returns quotient in r0 and remainder in r1 */ 4112 /* File: armv5te/binop.S */ 4113 /* 4114 * Generic 32-bit binary operation. Provide an "instr" line that 4115 * specifies an instruction that performs "result = r0 op r1". 4116 * This could be an ARM instruction or a function call. (If the result 4117 * comes back in a register other than r0, you can override "result".) 4118 * 4119 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4120 * vCC (r1). Useful for integer division and modulus. Note that we 4121 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4122 * handles it correctly. 4123 * 4124 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4125 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4126 * mul-float, div-float, rem-float 4127 */ 4128 /* binop vAA, vBB, vCC */ 4129 FETCH(r0, 1) @ r0<- CCBB 4130 mov r9, rINST, lsr #8 @ r9<- AA 4131 mov r3, r0, lsr #8 @ r3<- CC 4132 and r2, r0, #255 @ r2<- BB 4133 GET_VREG(r1, r3) @ r1<- vCC 4134 GET_VREG(r0, r2) @ r0<- vBB 4135 .if 1 4136 cmp r1, #0 @ is second operand zero? 4137 beq common_errDivideByZero 4138 .endif 4139 4140 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4141 @ optional op; may set condition codes 4142 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 4143 GET_INST_OPCODE(ip) @ extract opcode from rINST 4144 SET_VREG(r1, r9) @ vAA<- r1 4145 GOTO_OPCODE(ip) @ jump to next instruction 4146 /* 11-14 instructions */ 4147 4148 4149 /* ------------------------------ */ 4150 .balign 64 4151 .L_OP_AND_INT: /* 0x95 */ 4152 /* File: armv5te/OP_AND_INT.S */ 4153 /* File: armv5te/binop.S */ 4154 /* 4155 * Generic 32-bit binary operation. Provide an "instr" line that 4156 * specifies an instruction that performs "result = r0 op r1". 4157 * This could be an ARM instruction or a function call. (If the result 4158 * comes back in a register other than r0, you can override "result".) 4159 * 4160 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4161 * vCC (r1). Useful for integer division and modulus. Note that we 4162 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4163 * handles it correctly. 4164 * 4165 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4166 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4167 * mul-float, div-float, rem-float 4168 */ 4169 /* binop vAA, vBB, vCC */ 4170 FETCH(r0, 1) @ r0<- CCBB 4171 mov r9, rINST, lsr #8 @ r9<- AA 4172 mov r3, r0, lsr #8 @ r3<- CC 4173 and r2, r0, #255 @ r2<- BB 4174 GET_VREG(r1, r3) @ r1<- vCC 4175 GET_VREG(r0, r2) @ r0<- vBB 4176 .if 0 4177 cmp r1, #0 @ is second operand zero? 4178 beq common_errDivideByZero 4179 .endif 4180 4181 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4182 @ optional op; may set condition codes 4183 and r0, r0, r1 @ r0<- op, r0-r3 changed 4184 GET_INST_OPCODE(ip) @ extract opcode from rINST 4185 SET_VREG(r0, r9) @ vAA<- r0 4186 GOTO_OPCODE(ip) @ jump to next instruction 4187 /* 11-14 instructions */ 4188 4189 4190 /* ------------------------------ */ 4191 .balign 64 4192 .L_OP_OR_INT: /* 0x96 */ 4193 /* File: armv5te/OP_OR_INT.S */ 4194 /* File: armv5te/binop.S */ 4195 /* 4196 * Generic 32-bit binary operation. Provide an "instr" line that 4197 * specifies an instruction that performs "result = r0 op r1". 4198 * This could be an ARM instruction or a function call. (If the result 4199 * comes back in a register other than r0, you can override "result".) 4200 * 4201 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4202 * vCC (r1). Useful for integer division and modulus. Note that we 4203 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4204 * handles it correctly. 4205 * 4206 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4207 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4208 * mul-float, div-float, rem-float 4209 */ 4210 /* binop vAA, vBB, vCC */ 4211 FETCH(r0, 1) @ r0<- CCBB 4212 mov r9, rINST, lsr #8 @ r9<- AA 4213 mov r3, r0, lsr #8 @ r3<- CC 4214 and r2, r0, #255 @ r2<- BB 4215 GET_VREG(r1, r3) @ r1<- vCC 4216 GET_VREG(r0, r2) @ r0<- vBB 4217 .if 0 4218 cmp r1, #0 @ is second operand zero? 4219 beq common_errDivideByZero 4220 .endif 4221 4222 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4223 @ optional op; may set condition codes 4224 orr r0, r0, r1 @ r0<- op, r0-r3 changed 4225 GET_INST_OPCODE(ip) @ extract opcode from rINST 4226 SET_VREG(r0, r9) @ vAA<- r0 4227 GOTO_OPCODE(ip) @ jump to next instruction 4228 /* 11-14 instructions */ 4229 4230 4231 /* ------------------------------ */ 4232 .balign 64 4233 .L_OP_XOR_INT: /* 0x97 */ 4234 /* File: armv5te/OP_XOR_INT.S */ 4235 /* File: armv5te/binop.S */ 4236 /* 4237 * Generic 32-bit binary operation. Provide an "instr" line that 4238 * specifies an instruction that performs "result = r0 op r1". 4239 * This could be an ARM instruction or a function call. (If the result 4240 * comes back in a register other than r0, you can override "result".) 4241 * 4242 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4243 * vCC (r1). Useful for integer division and modulus. Note that we 4244 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4245 * handles it correctly. 4246 * 4247 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4248 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4249 * mul-float, div-float, rem-float 4250 */ 4251 /* binop vAA, vBB, vCC */ 4252 FETCH(r0, 1) @ r0<- CCBB 4253 mov r9, rINST, lsr #8 @ r9<- AA 4254 mov r3, r0, lsr #8 @ r3<- CC 4255 and r2, r0, #255 @ r2<- BB 4256 GET_VREG(r1, r3) @ r1<- vCC 4257 GET_VREG(r0, r2) @ r0<- vBB 4258 .if 0 4259 cmp r1, #0 @ is second operand zero? 4260 beq common_errDivideByZero 4261 .endif 4262 4263 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4264 @ optional op; may set condition codes 4265 eor r0, r0, r1 @ r0<- op, r0-r3 changed 4266 GET_INST_OPCODE(ip) @ extract opcode from rINST 4267 SET_VREG(r0, r9) @ vAA<- r0 4268 GOTO_OPCODE(ip) @ jump to next instruction 4269 /* 11-14 instructions */ 4270 4271 4272 /* ------------------------------ */ 4273 .balign 64 4274 .L_OP_SHL_INT: /* 0x98 */ 4275 /* File: armv5te/OP_SHL_INT.S */ 4276 /* File: armv5te/binop.S */ 4277 /* 4278 * Generic 32-bit binary operation. Provide an "instr" line that 4279 * specifies an instruction that performs "result = r0 op r1". 4280 * This could be an ARM instruction or a function call. (If the result 4281 * comes back in a register other than r0, you can override "result".) 4282 * 4283 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4284 * vCC (r1). Useful for integer division and modulus. Note that we 4285 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4286 * handles it correctly. 4287 * 4288 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4289 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4290 * mul-float, div-float, rem-float 4291 */ 4292 /* binop vAA, vBB, vCC */ 4293 FETCH(r0, 1) @ r0<- CCBB 4294 mov r9, rINST, lsr #8 @ r9<- AA 4295 mov r3, r0, lsr #8 @ r3<- CC 4296 and r2, r0, #255 @ r2<- BB 4297 GET_VREG(r1, r3) @ r1<- vCC 4298 GET_VREG(r0, r2) @ r0<- vBB 4299 .if 0 4300 cmp r1, #0 @ is second operand zero? 4301 beq common_errDivideByZero 4302 .endif 4303 4304 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4305 and r1, r1, #31 @ optional op; may set condition codes 4306 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 4307 GET_INST_OPCODE(ip) @ extract opcode from rINST 4308 SET_VREG(r0, r9) @ vAA<- r0 4309 GOTO_OPCODE(ip) @ jump to next instruction 4310 /* 11-14 instructions */ 4311 4312 4313 /* ------------------------------ */ 4314 .balign 64 4315 .L_OP_SHR_INT: /* 0x99 */ 4316 /* File: armv5te/OP_SHR_INT.S */ 4317 /* File: armv5te/binop.S */ 4318 /* 4319 * Generic 32-bit binary operation. Provide an "instr" line that 4320 * specifies an instruction that performs "result = r0 op r1". 4321 * This could be an ARM instruction or a function call. (If the result 4322 * comes back in a register other than r0, you can override "result".) 4323 * 4324 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4325 * vCC (r1). Useful for integer division and modulus. Note that we 4326 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4327 * handles it correctly. 4328 * 4329 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4330 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4331 * mul-float, div-float, rem-float 4332 */ 4333 /* binop vAA, vBB, vCC */ 4334 FETCH(r0, 1) @ r0<- CCBB 4335 mov r9, rINST, lsr #8 @ r9<- AA 4336 mov r3, r0, lsr #8 @ r3<- CC 4337 and r2, r0, #255 @ r2<- BB 4338 GET_VREG(r1, r3) @ r1<- vCC 4339 GET_VREG(r0, r2) @ r0<- vBB 4340 .if 0 4341 cmp r1, #0 @ is second operand zero? 4342 beq common_errDivideByZero 4343 .endif 4344 4345 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4346 and r1, r1, #31 @ optional op; may set condition codes 4347 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 4348 GET_INST_OPCODE(ip) @ extract opcode from rINST 4349 SET_VREG(r0, r9) @ vAA<- r0 4350 GOTO_OPCODE(ip) @ jump to next instruction 4351 /* 11-14 instructions */ 4352 4353 4354 /* ------------------------------ */ 4355 .balign 64 4356 .L_OP_USHR_INT: /* 0x9a */ 4357 /* File: armv5te/OP_USHR_INT.S */ 4358 /* File: armv5te/binop.S */ 4359 /* 4360 * Generic 32-bit binary operation. Provide an "instr" line that 4361 * specifies an instruction that performs "result = r0 op r1". 4362 * This could be an ARM instruction or a function call. (If the result 4363 * comes back in a register other than r0, you can override "result".) 4364 * 4365 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4366 * vCC (r1). Useful for integer division and modulus. Note that we 4367 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4368 * handles it correctly. 4369 * 4370 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4371 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4372 * mul-float, div-float, rem-float 4373 */ 4374 /* binop vAA, vBB, vCC */ 4375 FETCH(r0, 1) @ r0<- CCBB 4376 mov r9, rINST, lsr #8 @ r9<- AA 4377 mov r3, r0, lsr #8 @ r3<- CC 4378 and r2, r0, #255 @ r2<- BB 4379 GET_VREG(r1, r3) @ r1<- vCC 4380 GET_VREG(r0, r2) @ r0<- vBB 4381 .if 0 4382 cmp r1, #0 @ is second operand zero? 4383 beq common_errDivideByZero 4384 .endif 4385 4386 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4387 and r1, r1, #31 @ optional op; may set condition codes 4388 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 4389 GET_INST_OPCODE(ip) @ extract opcode from rINST 4390 SET_VREG(r0, r9) @ vAA<- r0 4391 GOTO_OPCODE(ip) @ jump to next instruction 4392 /* 11-14 instructions */ 4393 4394 4395 /* ------------------------------ */ 4396 .balign 64 4397 .L_OP_ADD_LONG: /* 0x9b */ 4398 /* File: armv5te/OP_ADD_LONG.S */ 4399 /* File: armv5te/binopWide.S */ 4400 /* 4401 * Generic 64-bit binary operation. Provide an "instr" line that 4402 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4403 * This could be an ARM instruction or a function call. (If the result 4404 * comes back in a register other than r0, you can override "result".) 4405 * 4406 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4407 * vCC (r1). Useful for integer division and modulus. 4408 * 4409 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4410 * xor-long, add-double, sub-double, mul-double, div-double, 4411 * rem-double 4412 * 4413 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4414 */ 4415 /* binop vAA, vBB, vCC */ 4416 FETCH(r0, 1) @ r0<- CCBB 4417 mov r9, rINST, lsr #8 @ r9<- AA 4418 and r2, r0, #255 @ r2<- BB 4419 mov r3, r0, lsr #8 @ r3<- CC 4420 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4421 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4422 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4423 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4424 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4425 .if 0 4426 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4427 beq common_errDivideByZero 4428 .endif 4429 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4430 4431 adds r0, r0, r2 @ optional op; may set condition codes 4432 adc r1, r1, r3 @ result<- op, r0-r3 changed 4433 GET_INST_OPCODE(ip) @ extract opcode from rINST 4434 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4435 GOTO_OPCODE(ip) @ jump to next instruction 4436 /* 14-17 instructions */ 4437 4438 4439 /* ------------------------------ */ 4440 .balign 64 4441 .L_OP_SUB_LONG: /* 0x9c */ 4442 /* File: armv5te/OP_SUB_LONG.S */ 4443 /* File: armv5te/binopWide.S */ 4444 /* 4445 * Generic 64-bit binary operation. Provide an "instr" line that 4446 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4447 * This could be an ARM instruction or a function call. (If the result 4448 * comes back in a register other than r0, you can override "result".) 4449 * 4450 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4451 * vCC (r1). Useful for integer division and modulus. 4452 * 4453 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4454 * xor-long, add-double, sub-double, mul-double, div-double, 4455 * rem-double 4456 * 4457 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4458 */ 4459 /* binop vAA, vBB, vCC */ 4460 FETCH(r0, 1) @ r0<- CCBB 4461 mov r9, rINST, lsr #8 @ r9<- AA 4462 and r2, r0, #255 @ r2<- BB 4463 mov r3, r0, lsr #8 @ r3<- CC 4464 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4465 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4466 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4467 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4468 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4469 .if 0 4470 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4471 beq common_errDivideByZero 4472 .endif 4473 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4474 4475 subs r0, r0, r2 @ optional op; may set condition codes 4476 sbc r1, r1, r3 @ result<- op, r0-r3 changed 4477 GET_INST_OPCODE(ip) @ extract opcode from rINST 4478 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4479 GOTO_OPCODE(ip) @ jump to next instruction 4480 /* 14-17 instructions */ 4481 4482 4483 /* ------------------------------ */ 4484 .balign 64 4485 .L_OP_MUL_LONG: /* 0x9d */ 4486 /* File: armv5te/OP_MUL_LONG.S */ 4487 /* 4488 * Signed 64-bit integer multiply. 4489 * 4490 * Consider WXxYZ (r1r0 x r3r2) with a long multiply: 4491 * WX 4492 * x YZ 4493 * -------- 4494 * ZW ZX 4495 * YW YX 4496 * 4497 * The low word of the result holds ZX, the high word holds 4498 * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because 4499 * it doesn't fit in the low 64 bits. 4500 * 4501 * Unlike most ARM math operations, multiply instructions have 4502 * restrictions on using the same register more than once (Rd and Rm 4503 * cannot be the same). 4504 */ 4505 /* mul-long vAA, vBB, vCC */ 4506 FETCH(r0, 1) @ r0<- CCBB 4507 and r2, r0, #255 @ r2<- BB 4508 mov r3, r0, lsr #8 @ r3<- CC 4509 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4510 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4511 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4512 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4513 mul ip, r2, r1 @ ip<- ZxW 4514 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 4515 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 4516 mov r0, rINST, lsr #8 @ r0<- AA 4517 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 4518 add r0, rFP, r0, lsl #2 @ r0<- &fp[AA] 4519 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4520 b .LOP_MUL_LONG_finish 4521 4522 /* ------------------------------ */ 4523 .balign 64 4524 .L_OP_DIV_LONG: /* 0x9e */ 4525 /* File: armv5te/OP_DIV_LONG.S */ 4526 /* File: armv5te/binopWide.S */ 4527 /* 4528 * Generic 64-bit binary operation. Provide an "instr" line that 4529 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4530 * This could be an ARM instruction or a function call. (If the result 4531 * comes back in a register other than r0, you can override "result".) 4532 * 4533 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4534 * vCC (r1). Useful for integer division and modulus. 4535 * 4536 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4537 * xor-long, add-double, sub-double, mul-double, div-double, 4538 * rem-double 4539 * 4540 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4541 */ 4542 /* binop vAA, vBB, vCC */ 4543 FETCH(r0, 1) @ r0<- CCBB 4544 mov r9, rINST, lsr #8 @ r9<- AA 4545 and r2, r0, #255 @ r2<- BB 4546 mov r3, r0, lsr #8 @ r3<- CC 4547 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4548 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4549 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4550 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4551 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4552 .if 1 4553 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4554 beq common_errDivideByZero 4555 .endif 4556 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4557 4558 @ optional op; may set condition codes 4559 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4560 GET_INST_OPCODE(ip) @ extract opcode from rINST 4561 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4562 GOTO_OPCODE(ip) @ jump to next instruction 4563 /* 14-17 instructions */ 4564 4565 4566 /* ------------------------------ */ 4567 .balign 64 4568 .L_OP_REM_LONG: /* 0x9f */ 4569 /* File: armv5te/OP_REM_LONG.S */ 4570 /* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 4571 /* File: armv5te/binopWide.S */ 4572 /* 4573 * Generic 64-bit binary operation. Provide an "instr" line that 4574 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4575 * This could be an ARM instruction or a function call. (If the result 4576 * comes back in a register other than r0, you can override "result".) 4577 * 4578 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4579 * vCC (r1). Useful for integer division and modulus. 4580 * 4581 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4582 * xor-long, add-double, sub-double, mul-double, div-double, 4583 * rem-double 4584 * 4585 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4586 */ 4587 /* binop vAA, vBB, vCC */ 4588 FETCH(r0, 1) @ r0<- CCBB 4589 mov r9, rINST, lsr #8 @ r9<- AA 4590 and r2, r0, #255 @ r2<- BB 4591 mov r3, r0, lsr #8 @ r3<- CC 4592 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4593 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4594 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4595 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4596 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4597 .if 1 4598 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4599 beq common_errDivideByZero 4600 .endif 4601 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4602 4603 @ optional op; may set condition codes 4604 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4605 GET_INST_OPCODE(ip) @ extract opcode from rINST 4606 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 4607 GOTO_OPCODE(ip) @ jump to next instruction 4608 /* 14-17 instructions */ 4609 4610 4611 /* ------------------------------ */ 4612 .balign 64 4613 .L_OP_AND_LONG: /* 0xa0 */ 4614 /* File: armv5te/OP_AND_LONG.S */ 4615 /* File: armv5te/binopWide.S */ 4616 /* 4617 * Generic 64-bit binary operation. Provide an "instr" line that 4618 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4619 * This could be an ARM instruction or a function call. (If the result 4620 * comes back in a register other than r0, you can override "result".) 4621 * 4622 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4623 * vCC (r1). Useful for integer division and modulus. 4624 * 4625 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4626 * xor-long, add-double, sub-double, mul-double, div-double, 4627 * rem-double 4628 * 4629 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4630 */ 4631 /* binop vAA, vBB, vCC */ 4632 FETCH(r0, 1) @ r0<- CCBB 4633 mov r9, rINST, lsr #8 @ r9<- AA 4634 and r2, r0, #255 @ r2<- BB 4635 mov r3, r0, lsr #8 @ r3<- CC 4636 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4637 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4638 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4639 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4640 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4641 .if 0 4642 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4643 beq common_errDivideByZero 4644 .endif 4645 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4646 4647 and r0, r0, r2 @ optional op; may set condition codes 4648 and r1, r1, r3 @ result<- op, r0-r3 changed 4649 GET_INST_OPCODE(ip) @ extract opcode from rINST 4650 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4651 GOTO_OPCODE(ip) @ jump to next instruction 4652 /* 14-17 instructions */ 4653 4654 4655 /* ------------------------------ */ 4656 .balign 64 4657 .L_OP_OR_LONG: /* 0xa1 */ 4658 /* File: armv5te/OP_OR_LONG.S */ 4659 /* File: armv5te/binopWide.S */ 4660 /* 4661 * Generic 64-bit binary operation. Provide an "instr" line that 4662 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4663 * This could be an ARM instruction or a function call. (If the result 4664 * comes back in a register other than r0, you can override "result".) 4665 * 4666 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4667 * vCC (r1). Useful for integer division and modulus. 4668 * 4669 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4670 * xor-long, add-double, sub-double, mul-double, div-double, 4671 * rem-double 4672 * 4673 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4674 */ 4675 /* binop vAA, vBB, vCC */ 4676 FETCH(r0, 1) @ r0<- CCBB 4677 mov r9, rINST, lsr #8 @ r9<- AA 4678 and r2, r0, #255 @ r2<- BB 4679 mov r3, r0, lsr #8 @ r3<- CC 4680 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4681 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4682 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4683 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4684 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4685 .if 0 4686 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4687 beq common_errDivideByZero 4688 .endif 4689 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4690 4691 orr r0, r0, r2 @ optional op; may set condition codes 4692 orr r1, r1, r3 @ result<- op, r0-r3 changed 4693 GET_INST_OPCODE(ip) @ extract opcode from rINST 4694 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4695 GOTO_OPCODE(ip) @ jump to next instruction 4696 /* 14-17 instructions */ 4697 4698 4699 /* ------------------------------ */ 4700 .balign 64 4701 .L_OP_XOR_LONG: /* 0xa2 */ 4702 /* File: armv5te/OP_XOR_LONG.S */ 4703 /* File: armv5te/binopWide.S */ 4704 /* 4705 * Generic 64-bit binary operation. Provide an "instr" line that 4706 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4707 * This could be an ARM instruction or a function call. (If the result 4708 * comes back in a register other than r0, you can override "result".) 4709 * 4710 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4711 * vCC (r1). Useful for integer division and modulus. 4712 * 4713 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4714 * xor-long, add-double, sub-double, mul-double, div-double, 4715 * rem-double 4716 * 4717 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4718 */ 4719 /* binop vAA, vBB, vCC */ 4720 FETCH(r0, 1) @ r0<- CCBB 4721 mov r9, rINST, lsr #8 @ r9<- AA 4722 and r2, r0, #255 @ r2<- BB 4723 mov r3, r0, lsr #8 @ r3<- CC 4724 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4725 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4726 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4727 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4728 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4729 .if 0 4730 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4731 beq common_errDivideByZero 4732 .endif 4733 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4734 4735 eor r0, r0, r2 @ optional op; may set condition codes 4736 eor r1, r1, r3 @ result<- op, r0-r3 changed 4737 GET_INST_OPCODE(ip) @ extract opcode from rINST 4738 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4739 GOTO_OPCODE(ip) @ jump to next instruction 4740 /* 14-17 instructions */ 4741 4742 4743 /* ------------------------------ */ 4744 .balign 64 4745 .L_OP_SHL_LONG: /* 0xa3 */ 4746 /* File: armv5te/OP_SHL_LONG.S */ 4747 /* 4748 * Long integer shift. This is different from the generic 32/64-bit 4749 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4750 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4751 * 6 bits of the shift distance. 4752 */ 4753 /* shl-long vAA, vBB, vCC */ 4754 FETCH(r0, 1) @ r0<- CCBB 4755 mov r9, rINST, lsr #8 @ r9<- AA 4756 and r3, r0, #255 @ r3<- BB 4757 mov r0, r0, lsr #8 @ r0<- CC 4758 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4759 GET_VREG(r2, r0) @ r2<- vCC 4760 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4761 and r2, r2, #63 @ r2<- r2 & 0x3f 4762 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4763 4764 mov r1, r1, asl r2 @ r1<- r1 << r2 4765 rsb r3, r2, #32 @ r3<- 32 - r2 4766 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 4767 subs ip, r2, #32 @ ip<- r2 - 32 4768 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 4769 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4770 b .LOP_SHL_LONG_finish 4771 4772 /* ------------------------------ */ 4773 .balign 64 4774 .L_OP_SHR_LONG: /* 0xa4 */ 4775 /* File: armv5te/OP_SHR_LONG.S */ 4776 /* 4777 * Long integer shift. This is different from the generic 32/64-bit 4778 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4779 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4780 * 6 bits of the shift distance. 4781 */ 4782 /* shr-long vAA, vBB, vCC */ 4783 FETCH(r0, 1) @ r0<- CCBB 4784 mov r9, rINST, lsr #8 @ r9<- AA 4785 and r3, r0, #255 @ r3<- BB 4786 mov r0, r0, lsr #8 @ r0<- CC 4787 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4788 GET_VREG(r2, r0) @ r2<- vCC 4789 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4790 and r2, r2, #63 @ r0<- r0 & 0x3f 4791 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4792 4793 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4794 rsb r3, r2, #32 @ r3<- 32 - r2 4795 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4796 subs ip, r2, #32 @ ip<- r2 - 32 4797 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 4798 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4799 b .LOP_SHR_LONG_finish 4800 4801 /* ------------------------------ */ 4802 .balign 64 4803 .L_OP_USHR_LONG: /* 0xa5 */ 4804 /* File: armv5te/OP_USHR_LONG.S */ 4805 /* 4806 * Long integer shift. This is different from the generic 32/64-bit 4807 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4808 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4809 * 6 bits of the shift distance. 4810 */ 4811 /* ushr-long vAA, vBB, vCC */ 4812 FETCH(r0, 1) @ r0<- CCBB 4813 mov r9, rINST, lsr #8 @ r9<- AA 4814 and r3, r0, #255 @ r3<- BB 4815 mov r0, r0, lsr #8 @ r0<- CC 4816 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4817 GET_VREG(r2, r0) @ r2<- vCC 4818 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4819 and r2, r2, #63 @ r0<- r0 & 0x3f 4820 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4821 4822 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4823 rsb r3, r2, #32 @ r3<- 32 - r2 4824 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4825 subs ip, r2, #32 @ ip<- r2 - 32 4826 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 4827 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4828 b .LOP_USHR_LONG_finish 4829 4830 /* ------------------------------ */ 4831 .balign 64 4832 .L_OP_ADD_FLOAT: /* 0xa6 */ 4833 /* File: arm-vfp/OP_ADD_FLOAT.S */ 4834 /* File: arm-vfp/fbinop.S */ 4835 /* 4836 * Generic 32-bit floating-point operation. Provide an "instr" line that 4837 * specifies an instruction that performs "s2 = s0 op s1". Because we 4838 * use the "softfp" ABI, this must be an instruction, not a function call. 4839 * 4840 * For: add-float, sub-float, mul-float, div-float 4841 */ 4842 /* floatop vAA, vBB, vCC */ 4843 FETCH(r0, 1) @ r0<- CCBB 4844 mov r9, rINST, lsr #8 @ r9<- AA 4845 mov r3, r0, lsr #8 @ r3<- CC 4846 and r2, r0, #255 @ r2<- BB 4847 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4848 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4849 flds s1, [r3] @ s1<- vCC 4850 flds s0, [r2] @ s0<- vBB 4851 4852 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4853 fadds s2, s0, s1 @ s2<- op 4854 GET_INST_OPCODE(ip) @ extract opcode from rINST 4855 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4856 fsts s2, [r9] @ vAA<- s2 4857 GOTO_OPCODE(ip) @ jump to next instruction 4858 4859 4860 /* ------------------------------ */ 4861 .balign 64 4862 .L_OP_SUB_FLOAT: /* 0xa7 */ 4863 /* File: arm-vfp/OP_SUB_FLOAT.S */ 4864 /* File: arm-vfp/fbinop.S */ 4865 /* 4866 * Generic 32-bit floating-point operation. Provide an "instr" line that 4867 * specifies an instruction that performs "s2 = s0 op s1". Because we 4868 * use the "softfp" ABI, this must be an instruction, not a function call. 4869 * 4870 * For: add-float, sub-float, mul-float, div-float 4871 */ 4872 /* floatop vAA, vBB, vCC */ 4873 FETCH(r0, 1) @ r0<- CCBB 4874 mov r9, rINST, lsr #8 @ r9<- AA 4875 mov r3, r0, lsr #8 @ r3<- CC 4876 and r2, r0, #255 @ r2<- BB 4877 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4878 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4879 flds s1, [r3] @ s1<- vCC 4880 flds s0, [r2] @ s0<- vBB 4881 4882 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4883 fsubs s2, s0, s1 @ s2<- op 4884 GET_INST_OPCODE(ip) @ extract opcode from rINST 4885 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4886 fsts s2, [r9] @ vAA<- s2 4887 GOTO_OPCODE(ip) @ jump to next instruction 4888 4889 4890 /* ------------------------------ */ 4891 .balign 64 4892 .L_OP_MUL_FLOAT: /* 0xa8 */ 4893 /* File: arm-vfp/OP_MUL_FLOAT.S */ 4894 /* File: arm-vfp/fbinop.S */ 4895 /* 4896 * Generic 32-bit floating-point operation. Provide an "instr" line that 4897 * specifies an instruction that performs "s2 = s0 op s1". Because we 4898 * use the "softfp" ABI, this must be an instruction, not a function call. 4899 * 4900 * For: add-float, sub-float, mul-float, div-float 4901 */ 4902 /* floatop vAA, vBB, vCC */ 4903 FETCH(r0, 1) @ r0<- CCBB 4904 mov r9, rINST, lsr #8 @ r9<- AA 4905 mov r3, r0, lsr #8 @ r3<- CC 4906 and r2, r0, #255 @ r2<- BB 4907 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4908 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4909 flds s1, [r3] @ s1<- vCC 4910 flds s0, [r2] @ s0<- vBB 4911 4912 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4913 fmuls s2, s0, s1 @ s2<- op 4914 GET_INST_OPCODE(ip) @ extract opcode from rINST 4915 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4916 fsts s2, [r9] @ vAA<- s2 4917 GOTO_OPCODE(ip) @ jump to next instruction 4918 4919 4920 /* ------------------------------ */ 4921 .balign 64 4922 .L_OP_DIV_FLOAT: /* 0xa9 */ 4923 /* File: arm-vfp/OP_DIV_FLOAT.S */ 4924 /* File: arm-vfp/fbinop.S */ 4925 /* 4926 * Generic 32-bit floating-point operation. Provide an "instr" line that 4927 * specifies an instruction that performs "s2 = s0 op s1". Because we 4928 * use the "softfp" ABI, this must be an instruction, not a function call. 4929 * 4930 * For: add-float, sub-float, mul-float, div-float 4931 */ 4932 /* floatop vAA, vBB, vCC */ 4933 FETCH(r0, 1) @ r0<- CCBB 4934 mov r9, rINST, lsr #8 @ r9<- AA 4935 mov r3, r0, lsr #8 @ r3<- CC 4936 and r2, r0, #255 @ r2<- BB 4937 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4938 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4939 flds s1, [r3] @ s1<- vCC 4940 flds s0, [r2] @ s0<- vBB 4941 4942 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4943 fdivs s2, s0, s1 @ s2<- op 4944 GET_INST_OPCODE(ip) @ extract opcode from rINST 4945 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4946 fsts s2, [r9] @ vAA<- s2 4947 GOTO_OPCODE(ip) @ jump to next instruction 4948 4949 4950 /* ------------------------------ */ 4951 .balign 64 4952 .L_OP_REM_FLOAT: /* 0xaa */ 4953 /* File: armv5te/OP_REM_FLOAT.S */ 4954 /* EABI doesn't define a float remainder function, but libm does */ 4955 /* File: armv5te/binop.S */ 4956 /* 4957 * Generic 32-bit binary operation. Provide an "instr" line that 4958 * specifies an instruction that performs "result = r0 op r1". 4959 * This could be an ARM instruction or a function call. (If the result 4960 * comes back in a register other than r0, you can override "result".) 4961 * 4962 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4963 * vCC (r1). Useful for integer division and modulus. Note that we 4964 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4965 * handles it correctly. 4966 * 4967 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4968 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4969 * mul-float, div-float, rem-float 4970 */ 4971 /* binop vAA, vBB, vCC */ 4972 FETCH(r0, 1) @ r0<- CCBB 4973 mov r9, rINST, lsr #8 @ r9<- AA 4974 mov r3, r0, lsr #8 @ r3<- CC 4975 and r2, r0, #255 @ r2<- BB 4976 GET_VREG(r1, r3) @ r1<- vCC 4977 GET_VREG(r0, r2) @ r0<- vBB 4978 .if 0 4979 cmp r1, #0 @ is second operand zero? 4980 beq common_errDivideByZero 4981 .endif 4982 4983 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4984 @ optional op; may set condition codes 4985 bl fmodf @ r0<- op, r0-r3 changed 4986 GET_INST_OPCODE(ip) @ extract opcode from rINST 4987 SET_VREG(r0, r9) @ vAA<- r0 4988 GOTO_OPCODE(ip) @ jump to next instruction 4989 /* 11-14 instructions */ 4990 4991 4992 /* ------------------------------ */ 4993 .balign 64 4994 .L_OP_ADD_DOUBLE: /* 0xab */ 4995 /* File: arm-vfp/OP_ADD_DOUBLE.S */ 4996 /* File: arm-vfp/fbinopWide.S */ 4997 /* 4998 * Generic 64-bit double-precision floating point binary operation. 4999 * Provide an "instr" line that specifies an instruction that performs 5000 * "d2 = d0 op d1". 5001 * 5002 * for: add-double, sub-double, mul-double, div-double 5003 */ 5004 /* doubleop vAA, vBB, vCC */ 5005 FETCH(r0, 1) @ r0<- CCBB 5006 mov r9, rINST, lsr #8 @ r9<- AA 5007 mov r3, r0, lsr #8 @ r3<- CC 5008 and r2, r0, #255 @ r2<- BB 5009 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5010 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5011 fldd d1, [r3] @ d1<- vCC 5012 fldd d0, [r2] @ d0<- vBB 5013 5014 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5015 faddd d2, d0, d1 @ s2<- op 5016 GET_INST_OPCODE(ip) @ extract opcode from rINST 5017 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5018 fstd d2, [r9] @ vAA<- d2 5019 GOTO_OPCODE(ip) @ jump to next instruction 5020 5021 5022 /* ------------------------------ */ 5023 .balign 64 5024 .L_OP_SUB_DOUBLE: /* 0xac */ 5025 /* File: arm-vfp/OP_SUB_DOUBLE.S */ 5026 /* File: arm-vfp/fbinopWide.S */ 5027 /* 5028 * Generic 64-bit double-precision floating point binary operation. 5029 * Provide an "instr" line that specifies an instruction that performs 5030 * "d2 = d0 op d1". 5031 * 5032 * for: add-double, sub-double, mul-double, div-double 5033 */ 5034 /* doubleop vAA, vBB, vCC */ 5035 FETCH(r0, 1) @ r0<- CCBB 5036 mov r9, rINST, lsr #8 @ r9<- AA 5037 mov r3, r0, lsr #8 @ r3<- CC 5038 and r2, r0, #255 @ r2<- BB 5039 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5040 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5041 fldd d1, [r3] @ d1<- vCC 5042 fldd d0, [r2] @ d0<- vBB 5043 5044 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5045 fsubd d2, d0, d1 @ s2<- op 5046 GET_INST_OPCODE(ip) @ extract opcode from rINST 5047 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5048 fstd d2, [r9] @ vAA<- d2 5049 GOTO_OPCODE(ip) @ jump to next instruction 5050 5051 5052 /* ------------------------------ */ 5053 .balign 64 5054 .L_OP_MUL_DOUBLE: /* 0xad */ 5055 /* File: arm-vfp/OP_MUL_DOUBLE.S */ 5056 /* File: arm-vfp/fbinopWide.S */ 5057 /* 5058 * Generic 64-bit double-precision floating point binary operation. 5059 * Provide an "instr" line that specifies an instruction that performs 5060 * "d2 = d0 op d1". 5061 * 5062 * for: add-double, sub-double, mul-double, div-double 5063 */ 5064 /* doubleop vAA, vBB, vCC */ 5065 FETCH(r0, 1) @ r0<- CCBB 5066 mov r9, rINST, lsr #8 @ r9<- AA 5067 mov r3, r0, lsr #8 @ r3<- CC 5068 and r2, r0, #255 @ r2<- BB 5069 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5070 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5071 fldd d1, [r3] @ d1<- vCC 5072 fldd d0, [r2] @ d0<- vBB 5073 5074 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5075 fmuld d2, d0, d1 @ s2<- op 5076 GET_INST_OPCODE(ip) @ extract opcode from rINST 5077 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5078 fstd d2, [r9] @ vAA<- d2 5079 GOTO_OPCODE(ip) @ jump to next instruction 5080 5081 5082 /* ------------------------------ */ 5083 .balign 64 5084 .L_OP_DIV_DOUBLE: /* 0xae */ 5085 /* File: arm-vfp/OP_DIV_DOUBLE.S */ 5086 /* File: arm-vfp/fbinopWide.S */ 5087 /* 5088 * Generic 64-bit double-precision floating point binary operation. 5089 * Provide an "instr" line that specifies an instruction that performs 5090 * "d2 = d0 op d1". 5091 * 5092 * for: add-double, sub-double, mul-double, div-double 5093 */ 5094 /* doubleop vAA, vBB, vCC */ 5095 FETCH(r0, 1) @ r0<- CCBB 5096 mov r9, rINST, lsr #8 @ r9<- AA 5097 mov r3, r0, lsr #8 @ r3<- CC 5098 and r2, r0, #255 @ r2<- BB 5099 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5100 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5101 fldd d1, [r3] @ d1<- vCC 5102 fldd d0, [r2] @ d0<- vBB 5103 5104 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5105 fdivd d2, d0, d1 @ s2<- op 5106 GET_INST_OPCODE(ip) @ extract opcode from rINST 5107 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5108 fstd d2, [r9] @ vAA<- d2 5109 GOTO_OPCODE(ip) @ jump to next instruction 5110 5111 5112 /* ------------------------------ */ 5113 .balign 64 5114 .L_OP_REM_DOUBLE: /* 0xaf */ 5115 /* File: armv5te/OP_REM_DOUBLE.S */ 5116 /* EABI doesn't define a double remainder function, but libm does */ 5117 /* File: armv5te/binopWide.S */ 5118 /* 5119 * Generic 64-bit binary operation. Provide an "instr" line that 5120 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5121 * This could be an ARM instruction or a function call. (If the result 5122 * comes back in a register other than r0, you can override "result".) 5123 * 5124 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5125 * vCC (r1). Useful for integer division and modulus. 5126 * 5127 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5128 * xor-long, add-double, sub-double, mul-double, div-double, 5129 * rem-double 5130 * 5131 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5132 */ 5133 /* binop vAA, vBB, vCC */ 5134 FETCH(r0, 1) @ r0<- CCBB 5135 mov r9, rINST, lsr #8 @ r9<- AA 5136 and r2, r0, #255 @ r2<- BB 5137 mov r3, r0, lsr #8 @ r3<- CC 5138 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5139 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5140 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5141 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5142 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5143 .if 0 5144 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5145 beq common_errDivideByZero 5146 .endif 5147 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5148 5149 @ optional op; may set condition codes 5150 bl fmod @ result<- op, r0-r3 changed 5151 GET_INST_OPCODE(ip) @ extract opcode from rINST 5152 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5153 GOTO_OPCODE(ip) @ jump to next instruction 5154 /* 14-17 instructions */ 5155 5156 5157 /* ------------------------------ */ 5158 .balign 64 5159 .L_OP_ADD_INT_2ADDR: /* 0xb0 */ 5160 /* File: armv5te/OP_ADD_INT_2ADDR.S */ 5161 /* File: armv5te/binop2addr.S */ 5162 /* 5163 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5164 * that specifies an instruction that performs "result = r0 op r1". 5165 * This could be an ARM instruction or a function call. (If the result 5166 * comes back in a register other than r0, you can override "result".) 5167 * 5168 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5169 * vCC (r1). Useful for integer division and modulus. 5170 * 5171 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5172 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5173 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5174 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5175 */ 5176 /* binop/2addr vA, vB */ 5177 mov r9, rINST, lsr #8 @ r9<- A+ 5178 mov r3, rINST, lsr #12 @ r3<- B 5179 and r9, r9, #15 5180 GET_VREG(r1, r3) @ r1<- vB 5181 GET_VREG(r0, r9) @ r0<- vA 5182 .if 0 5183 cmp r1, #0 @ is second operand zero? 5184 beq common_errDivideByZero 5185 .endif 5186 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5187 5188 @ optional op; may set condition codes 5189 add r0, r0, r1 @ r0<- op, r0-r3 changed 5190 GET_INST_OPCODE(ip) @ extract opcode from rINST 5191 SET_VREG(r0, r9) @ vAA<- r0 5192 GOTO_OPCODE(ip) @ jump to next instruction 5193 /* 10-13 instructions */ 5194 5195 5196 /* ------------------------------ */ 5197 .balign 64 5198 .L_OP_SUB_INT_2ADDR: /* 0xb1 */ 5199 /* File: armv5te/OP_SUB_INT_2ADDR.S */ 5200 /* File: armv5te/binop2addr.S */ 5201 /* 5202 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5203 * that specifies an instruction that performs "result = r0 op r1". 5204 * This could be an ARM instruction or a function call. (If the result 5205 * comes back in a register other than r0, you can override "result".) 5206 * 5207 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5208 * vCC (r1). Useful for integer division and modulus. 5209 * 5210 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5211 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5212 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5213 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5214 */ 5215 /* binop/2addr vA, vB */ 5216 mov r9, rINST, lsr #8 @ r9<- A+ 5217 mov r3, rINST, lsr #12 @ r3<- B 5218 and r9, r9, #15 5219 GET_VREG(r1, r3) @ r1<- vB 5220 GET_VREG(r0, r9) @ r0<- vA 5221 .if 0 5222 cmp r1, #0 @ is second operand zero? 5223 beq common_errDivideByZero 5224 .endif 5225 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5226 5227 @ optional op; may set condition codes 5228 sub r0, r0, r1 @ r0<- op, r0-r3 changed 5229 GET_INST_OPCODE(ip) @ extract opcode from rINST 5230 SET_VREG(r0, r9) @ vAA<- r0 5231 GOTO_OPCODE(ip) @ jump to next instruction 5232 /* 10-13 instructions */ 5233 5234 5235 /* ------------------------------ */ 5236 .balign 64 5237 .L_OP_MUL_INT_2ADDR: /* 0xb2 */ 5238 /* File: armv5te/OP_MUL_INT_2ADDR.S */ 5239 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 5240 /* File: armv5te/binop2addr.S */ 5241 /* 5242 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5243 * that specifies an instruction that performs "result = r0 op r1". 5244 * This could be an ARM instruction or a function call. (If the result 5245 * comes back in a register other than r0, you can override "result".) 5246 * 5247 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5248 * vCC (r1). Useful for integer division and modulus. 5249 * 5250 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5251 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5252 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5253 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5254 */ 5255 /* binop/2addr vA, vB */ 5256 mov r9, rINST, lsr #8 @ r9<- A+ 5257 mov r3, rINST, lsr #12 @ r3<- B 5258 and r9, r9, #15 5259 GET_VREG(r1, r3) @ r1<- vB 5260 GET_VREG(r0, r9) @ r0<- vA 5261 .if 0 5262 cmp r1, #0 @ is second operand zero? 5263 beq common_errDivideByZero 5264 .endif 5265 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5266 5267 @ optional op; may set condition codes 5268 mul r0, r1, r0 @ r0<- op, r0-r3 changed 5269 GET_INST_OPCODE(ip) @ extract opcode from rINST 5270 SET_VREG(r0, r9) @ vAA<- r0 5271 GOTO_OPCODE(ip) @ jump to next instruction 5272 /* 10-13 instructions */ 5273 5274 5275 /* ------------------------------ */ 5276 .balign 64 5277 .L_OP_DIV_INT_2ADDR: /* 0xb3 */ 5278 /* File: armv5te/OP_DIV_INT_2ADDR.S */ 5279 /* File: armv5te/binop2addr.S */ 5280 /* 5281 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5282 * that specifies an instruction that performs "result = r0 op r1". 5283 * This could be an ARM instruction or a function call. (If the result 5284 * comes back in a register other than r0, you can override "result".) 5285 * 5286 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5287 * vCC (r1). Useful for integer division and modulus. 5288 * 5289 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5290 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5291 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5292 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5293 */ 5294 /* binop/2addr vA, vB */ 5295 mov r9, rINST, lsr #8 @ r9<- A+ 5296 mov r3, rINST, lsr #12 @ r3<- B 5297 and r9, r9, #15 5298 GET_VREG(r1, r3) @ r1<- vB 5299 GET_VREG(r0, r9) @ r0<- vA 5300 .if 1 5301 cmp r1, #0 @ is second operand zero? 5302 beq common_errDivideByZero 5303 .endif 5304 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5305 5306 @ optional op; may set condition codes 5307 bl __aeabi_idiv @ r0<- op, r0-r3 changed 5308 GET_INST_OPCODE(ip) @ extract opcode from rINST 5309 SET_VREG(r0, r9) @ vAA<- r0 5310 GOTO_OPCODE(ip) @ jump to next instruction 5311 /* 10-13 instructions */ 5312 5313 5314 /* ------------------------------ */ 5315 .balign 64 5316 .L_OP_REM_INT_2ADDR: /* 0xb4 */ 5317 /* File: armv5te/OP_REM_INT_2ADDR.S */ 5318 /* idivmod returns quotient in r0 and remainder in r1 */ 5319 /* File: armv5te/binop2addr.S */ 5320 /* 5321 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5322 * that specifies an instruction that performs "result = r0 op r1". 5323 * This could be an ARM instruction or a function call. (If the result 5324 * comes back in a register other than r0, you can override "result".) 5325 * 5326 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5327 * vCC (r1). Useful for integer division and modulus. 5328 * 5329 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5330 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5331 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5332 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5333 */ 5334 /* binop/2addr vA, vB */ 5335 mov r9, rINST, lsr #8 @ r9<- A+ 5336 mov r3, rINST, lsr #12 @ r3<- B 5337 and r9, r9, #15 5338 GET_VREG(r1, r3) @ r1<- vB 5339 GET_VREG(r0, r9) @ r0<- vA 5340 .if 1 5341 cmp r1, #0 @ is second operand zero? 5342 beq common_errDivideByZero 5343 .endif 5344 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5345 5346 @ optional op; may set condition codes 5347 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 5348 GET_INST_OPCODE(ip) @ extract opcode from rINST 5349 SET_VREG(r1, r9) @ vAA<- r1 5350 GOTO_OPCODE(ip) @ jump to next instruction 5351 /* 10-13 instructions */ 5352 5353 5354 /* ------------------------------ */ 5355 .balign 64 5356 .L_OP_AND_INT_2ADDR: /* 0xb5 */ 5357 /* File: armv5te/OP_AND_INT_2ADDR.S */ 5358 /* File: armv5te/binop2addr.S */ 5359 /* 5360 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5361 * that specifies an instruction that performs "result = r0 op r1". 5362 * This could be an ARM instruction or a function call. (If the result 5363 * comes back in a register other than r0, you can override "result".) 5364 * 5365 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5366 * vCC (r1). Useful for integer division and modulus. 5367 * 5368 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5369 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5370 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5371 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5372 */ 5373 /* binop/2addr vA, vB */ 5374 mov r9, rINST, lsr #8 @ r9<- A+ 5375 mov r3, rINST, lsr #12 @ r3<- B 5376 and r9, r9, #15 5377 GET_VREG(r1, r3) @ r1<- vB 5378 GET_VREG(r0, r9) @ r0<- vA 5379 .if 0 5380 cmp r1, #0 @ is second operand zero? 5381 beq common_errDivideByZero 5382 .endif 5383 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5384 5385 @ optional op; may set condition codes 5386 and r0, r0, r1 @ r0<- op, r0-r3 changed 5387 GET_INST_OPCODE(ip) @ extract opcode from rINST 5388 SET_VREG(r0, r9) @ vAA<- r0 5389 GOTO_OPCODE(ip) @ jump to next instruction 5390 /* 10-13 instructions */ 5391 5392 5393 /* ------------------------------ */ 5394 .balign 64 5395 .L_OP_OR_INT_2ADDR: /* 0xb6 */ 5396 /* File: armv5te/OP_OR_INT_2ADDR.S */ 5397 /* File: armv5te/binop2addr.S */ 5398 /* 5399 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5400 * that specifies an instruction that performs "result = r0 op r1". 5401 * This could be an ARM instruction or a function call. (If the result 5402 * comes back in a register other than r0, you can override "result".) 5403 * 5404 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5405 * vCC (r1). Useful for integer division and modulus. 5406 * 5407 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5408 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5409 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5410 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5411 */ 5412 /* binop/2addr vA, vB */ 5413 mov r9, rINST, lsr #8 @ r9<- A+ 5414 mov r3, rINST, lsr #12 @ r3<- B 5415 and r9, r9, #15 5416 GET_VREG(r1, r3) @ r1<- vB 5417 GET_VREG(r0, r9) @ r0<- vA 5418 .if 0 5419 cmp r1, #0 @ is second operand zero? 5420 beq common_errDivideByZero 5421 .endif 5422 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5423 5424 @ optional op; may set condition codes 5425 orr r0, r0, r1 @ r0<- op, r0-r3 changed 5426 GET_INST_OPCODE(ip) @ extract opcode from rINST 5427 SET_VREG(r0, r9) @ vAA<- r0 5428 GOTO_OPCODE(ip) @ jump to next instruction 5429 /* 10-13 instructions */ 5430 5431 5432 /* ------------------------------ */ 5433 .balign 64 5434 .L_OP_XOR_INT_2ADDR: /* 0xb7 */ 5435 /* File: armv5te/OP_XOR_INT_2ADDR.S */ 5436 /* File: armv5te/binop2addr.S */ 5437 /* 5438 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5439 * that specifies an instruction that performs "result = r0 op r1". 5440 * This could be an ARM instruction or a function call. (If the result 5441 * comes back in a register other than r0, you can override "result".) 5442 * 5443 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5444 * vCC (r1). Useful for integer division and modulus. 5445 * 5446 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5447 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5448 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5449 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5450 */ 5451 /* binop/2addr vA, vB */ 5452 mov r9, rINST, lsr #8 @ r9<- A+ 5453 mov r3, rINST, lsr #12 @ r3<- B 5454 and r9, r9, #15 5455 GET_VREG(r1, r3) @ r1<- vB 5456 GET_VREG(r0, r9) @ r0<- vA 5457 .if 0 5458 cmp r1, #0 @ is second operand zero? 5459 beq common_errDivideByZero 5460 .endif 5461 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5462 5463 @ optional op; may set condition codes 5464 eor r0, r0, r1 @ r0<- op, r0-r3 changed 5465 GET_INST_OPCODE(ip) @ extract opcode from rINST 5466 SET_VREG(r0, r9) @ vAA<- r0 5467 GOTO_OPCODE(ip) @ jump to next instruction 5468 /* 10-13 instructions */ 5469 5470 5471 /* ------------------------------ */ 5472 .balign 64 5473 .L_OP_SHL_INT_2ADDR: /* 0xb8 */ 5474 /* File: armv5te/OP_SHL_INT_2ADDR.S */ 5475 /* File: armv5te/binop2addr.S */ 5476 /* 5477 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5478 * that specifies an instruction that performs "result = r0 op r1". 5479 * This could be an ARM instruction or a function call. (If the result 5480 * comes back in a register other than r0, you can override "result".) 5481 * 5482 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5483 * vCC (r1). Useful for integer division and modulus. 5484 * 5485 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5486 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5487 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5488 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5489 */ 5490 /* binop/2addr vA, vB */ 5491 mov r9, rINST, lsr #8 @ r9<- A+ 5492 mov r3, rINST, lsr #12 @ r3<- B 5493 and r9, r9, #15 5494 GET_VREG(r1, r3) @ r1<- vB 5495 GET_VREG(r0, r9) @ r0<- vA 5496 .if 0 5497 cmp r1, #0 @ is second operand zero? 5498 beq common_errDivideByZero 5499 .endif 5500 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5501 5502 and r1, r1, #31 @ optional op; may set condition codes 5503 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 5504 GET_INST_OPCODE(ip) @ extract opcode from rINST 5505 SET_VREG(r0, r9) @ vAA<- r0 5506 GOTO_OPCODE(ip) @ jump to next instruction 5507 /* 10-13 instructions */ 5508 5509 5510 /* ------------------------------ */ 5511 .balign 64 5512 .L_OP_SHR_INT_2ADDR: /* 0xb9 */ 5513 /* File: armv5te/OP_SHR_INT_2ADDR.S */ 5514 /* File: armv5te/binop2addr.S */ 5515 /* 5516 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5517 * that specifies an instruction that performs "result = r0 op r1". 5518 * This could be an ARM instruction or a function call. (If the result 5519 * comes back in a register other than r0, you can override "result".) 5520 * 5521 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5522 * vCC (r1). Useful for integer division and modulus. 5523 * 5524 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5525 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5526 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5527 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5528 */ 5529 /* binop/2addr vA, vB */ 5530 mov r9, rINST, lsr #8 @ r9<- A+ 5531 mov r3, rINST, lsr #12 @ r3<- B 5532 and r9, r9, #15 5533 GET_VREG(r1, r3) @ r1<- vB 5534 GET_VREG(r0, r9) @ r0<- vA 5535 .if 0 5536 cmp r1, #0 @ is second operand zero? 5537 beq common_errDivideByZero 5538 .endif 5539 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5540 5541 and r1, r1, #31 @ optional op; may set condition codes 5542 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 5543 GET_INST_OPCODE(ip) @ extract opcode from rINST 5544 SET_VREG(r0, r9) @ vAA<- r0 5545 GOTO_OPCODE(ip) @ jump to next instruction 5546 /* 10-13 instructions */ 5547 5548 5549 /* ------------------------------ */ 5550 .balign 64 5551 .L_OP_USHR_INT_2ADDR: /* 0xba */ 5552 /* File: armv5te/OP_USHR_INT_2ADDR.S */ 5553 /* File: armv5te/binop2addr.S */ 5554 /* 5555 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5556 * that specifies an instruction that performs "result = r0 op r1". 5557 * This could be an ARM instruction or a function call. (If the result 5558 * comes back in a register other than r0, you can override "result".) 5559 * 5560 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5561 * vCC (r1). Useful for integer division and modulus. 5562 * 5563 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5564 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5565 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5566 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5567 */ 5568 /* binop/2addr vA, vB */ 5569 mov r9, rINST, lsr #8 @ r9<- A+ 5570 mov r3, rINST, lsr #12 @ r3<- B 5571 and r9, r9, #15 5572 GET_VREG(r1, r3) @ r1<- vB 5573 GET_VREG(r0, r9) @ r0<- vA 5574 .if 0 5575 cmp r1, #0 @ is second operand zero? 5576 beq common_errDivideByZero 5577 .endif 5578 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5579 5580 and r1, r1, #31 @ optional op; may set condition codes 5581 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 5582 GET_INST_OPCODE(ip) @ extract opcode from rINST 5583 SET_VREG(r0, r9) @ vAA<- r0 5584 GOTO_OPCODE(ip) @ jump to next instruction 5585 /* 10-13 instructions */ 5586 5587 5588 /* ------------------------------ */ 5589 .balign 64 5590 .L_OP_ADD_LONG_2ADDR: /* 0xbb */ 5591 /* File: armv5te/OP_ADD_LONG_2ADDR.S */ 5592 /* File: armv5te/binopWide2addr.S */ 5593 /* 5594 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5595 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5596 * This could be an ARM instruction or a function call. (If the result 5597 * comes back in a register other than r0, you can override "result".) 5598 * 5599 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5600 * vCC (r1). Useful for integer division and modulus. 5601 * 5602 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5603 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5604 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5605 * rem-double/2addr 5606 */ 5607 /* binop/2addr vA, vB */ 5608 mov r9, rINST, lsr #8 @ r9<- A+ 5609 mov r1, rINST, lsr #12 @ r1<- B 5610 and r9, r9, #15 5611 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5612 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5613 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5614 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5615 .if 0 5616 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5617 beq common_errDivideByZero 5618 .endif 5619 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5620 5621 adds r0, r0, r2 @ optional op; may set condition codes 5622 adc r1, r1, r3 @ result<- op, r0-r3 changed 5623 GET_INST_OPCODE(ip) @ extract opcode from rINST 5624 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5625 GOTO_OPCODE(ip) @ jump to next instruction 5626 /* 12-15 instructions */ 5627 5628 5629 /* ------------------------------ */ 5630 .balign 64 5631 .L_OP_SUB_LONG_2ADDR: /* 0xbc */ 5632 /* File: armv5te/OP_SUB_LONG_2ADDR.S */ 5633 /* File: armv5te/binopWide2addr.S */ 5634 /* 5635 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5636 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5637 * This could be an ARM instruction or a function call. (If the result 5638 * comes back in a register other than r0, you can override "result".) 5639 * 5640 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5641 * vCC (r1). Useful for integer division and modulus. 5642 * 5643 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5644 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5645 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5646 * rem-double/2addr 5647 */ 5648 /* binop/2addr vA, vB */ 5649 mov r9, rINST, lsr #8 @ r9<- A+ 5650 mov r1, rINST, lsr #12 @ r1<- B 5651 and r9, r9, #15 5652 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5653 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5654 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5655 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5656 .if 0 5657 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5658 beq common_errDivideByZero 5659 .endif 5660 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5661 5662 subs r0, r0, r2 @ optional op; may set condition codes 5663 sbc r1, r1, r3 @ result<- op, r0-r3 changed 5664 GET_INST_OPCODE(ip) @ extract opcode from rINST 5665 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5666 GOTO_OPCODE(ip) @ jump to next instruction 5667 /* 12-15 instructions */ 5668 5669 5670 /* ------------------------------ */ 5671 .balign 64 5672 .L_OP_MUL_LONG_2ADDR: /* 0xbd */ 5673 /* File: armv5te/OP_MUL_LONG_2ADDR.S */ 5674 /* 5675 * Signed 64-bit integer multiply, "/2addr" version. 5676 * 5677 * See OP_MUL_LONG for an explanation. 5678 * 5679 * We get a little tight on registers, so to avoid looking up &fp[A] 5680 * again we stuff it into rINST. 5681 */ 5682 /* mul-long/2addr vA, vB */ 5683 mov r9, rINST, lsr #8 @ r9<- A+ 5684 mov r1, rINST, lsr #12 @ r1<- B 5685 and r9, r9, #15 5686 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5687 add rINST, rFP, r9, lsl #2 @ rINST<- &fp[A] 5688 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5689 ldmia rINST, {r0-r1} @ r0/r1<- vAA/vAA+1 5690 mul ip, r2, r1 @ ip<- ZxW 5691 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 5692 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 5693 mov r0, rINST @ r0<- &fp[A] (free up rINST) 5694 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5695 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 5696 GET_INST_OPCODE(ip) @ extract opcode from rINST 5697 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 5698 GOTO_OPCODE(ip) @ jump to next instruction 5699 5700 /* ------------------------------ */ 5701 .balign 64 5702 .L_OP_DIV_LONG_2ADDR: /* 0xbe */ 5703 /* File: armv5te/OP_DIV_LONG_2ADDR.S */ 5704 /* File: armv5te/binopWide2addr.S */ 5705 /* 5706 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5707 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5708 * This could be an ARM instruction or a function call. (If the result 5709 * comes back in a register other than r0, you can override "result".) 5710 * 5711 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5712 * vCC (r1). Useful for integer division and modulus. 5713 * 5714 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5715 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5716 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5717 * rem-double/2addr 5718 */ 5719 /* binop/2addr vA, vB */ 5720 mov r9, rINST, lsr #8 @ r9<- A+ 5721 mov r1, rINST, lsr #12 @ r1<- B 5722 and r9, r9, #15 5723 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5724 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5725 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5726 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5727 .if 1 5728 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5729 beq common_errDivideByZero 5730 .endif 5731 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5732 5733 @ optional op; may set condition codes 5734 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5735 GET_INST_OPCODE(ip) @ extract opcode from rINST 5736 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5737 GOTO_OPCODE(ip) @ jump to next instruction 5738 /* 12-15 instructions */ 5739 5740 5741 /* ------------------------------ */ 5742 .balign 64 5743 .L_OP_REM_LONG_2ADDR: /* 0xbf */ 5744 /* File: armv5te/OP_REM_LONG_2ADDR.S */ 5745 /* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 5746 /* File: armv5te/binopWide2addr.S */ 5747 /* 5748 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5749 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5750 * This could be an ARM instruction or a function call. (If the result 5751 * comes back in a register other than r0, you can override "result".) 5752 * 5753 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5754 * vCC (r1). Useful for integer division and modulus. 5755 * 5756 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5757 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5758 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5759 * rem-double/2addr 5760 */ 5761 /* binop/2addr vA, vB */ 5762 mov r9, rINST, lsr #8 @ r9<- A+ 5763 mov r1, rINST, lsr #12 @ r1<- B 5764 and r9, r9, #15 5765 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5766 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5767 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5768 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5769 .if 1 5770 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5771 beq common_errDivideByZero 5772 .endif 5773 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5774 5775 @ optional op; may set condition codes 5776 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5777 GET_INST_OPCODE(ip) @ extract opcode from rINST 5778 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 5779 GOTO_OPCODE(ip) @ jump to next instruction 5780 /* 12-15 instructions */ 5781 5782 5783 /* ------------------------------ */ 5784 .balign 64 5785 .L_OP_AND_LONG_2ADDR: /* 0xc0 */ 5786 /* File: armv5te/OP_AND_LONG_2ADDR.S */ 5787 /* File: armv5te/binopWide2addr.S */ 5788 /* 5789 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5790 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5791 * This could be an ARM instruction or a function call. (If the result 5792 * comes back in a register other than r0, you can override "result".) 5793 * 5794 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5795 * vCC (r1). Useful for integer division and modulus. 5796 * 5797 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5798 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5799 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5800 * rem-double/2addr 5801 */ 5802 /* binop/2addr vA, vB */ 5803 mov r9, rINST, lsr #8 @ r9<- A+ 5804 mov r1, rINST, lsr #12 @ r1<- B 5805 and r9, r9, #15 5806 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5807 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5808 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5809 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5810 .if 0 5811 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5812 beq common_errDivideByZero 5813 .endif 5814 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5815 5816 and r0, r0, r2 @ optional op; may set condition codes 5817 and r1, r1, r3 @ result<- op, r0-r3 changed 5818 GET_INST_OPCODE(ip) @ extract opcode from rINST 5819 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5820 GOTO_OPCODE(ip) @ jump to next instruction 5821 /* 12-15 instructions */ 5822 5823 5824 /* ------------------------------ */ 5825 .balign 64 5826 .L_OP_OR_LONG_2ADDR: /* 0xc1 */ 5827 /* File: armv5te/OP_OR_LONG_2ADDR.S */ 5828 /* File: armv5te/binopWide2addr.S */ 5829 /* 5830 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5831 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5832 * This could be an ARM instruction or a function call. (If the result 5833 * comes back in a register other than r0, you can override "result".) 5834 * 5835 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5836 * vCC (r1). Useful for integer division and modulus. 5837 * 5838 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5839 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5840 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5841 * rem-double/2addr 5842 */ 5843 /* binop/2addr vA, vB */ 5844 mov r9, rINST, lsr #8 @ r9<- A+ 5845 mov r1, rINST, lsr #12 @ r1<- B 5846 and r9, r9, #15 5847 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5848 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5849 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5850 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5851 .if 0 5852 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5853 beq common_errDivideByZero 5854 .endif 5855 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5856 5857 orr r0, r0, r2 @ optional op; may set condition codes 5858 orr r1, r1, r3 @ result<- op, r0-r3 changed 5859 GET_INST_OPCODE(ip) @ extract opcode from rINST 5860 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5861 GOTO_OPCODE(ip) @ jump to next instruction 5862 /* 12-15 instructions */ 5863 5864 5865 /* ------------------------------ */ 5866 .balign 64 5867 .L_OP_XOR_LONG_2ADDR: /* 0xc2 */ 5868 /* File: armv5te/OP_XOR_LONG_2ADDR.S */ 5869 /* File: armv5te/binopWide2addr.S */ 5870 /* 5871 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5872 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5873 * This could be an ARM instruction or a function call. (If the result 5874 * comes back in a register other than r0, you can override "result".) 5875 * 5876 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5877 * vCC (r1). Useful for integer division and modulus. 5878 * 5879 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5880 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5881 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5882 * rem-double/2addr 5883 */ 5884 /* binop/2addr vA, vB */ 5885 mov r9, rINST, lsr #8 @ r9<- A+ 5886 mov r1, rINST, lsr #12 @ r1<- B 5887 and r9, r9, #15 5888 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5889 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5890 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5891 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5892 .if 0 5893 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5894 beq common_errDivideByZero 5895 .endif 5896 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5897 5898 eor r0, r0, r2 @ optional op; may set condition codes 5899 eor r1, r1, r3 @ result<- op, r0-r3 changed 5900 GET_INST_OPCODE(ip) @ extract opcode from rINST 5901 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5902 GOTO_OPCODE(ip) @ jump to next instruction 5903 /* 12-15 instructions */ 5904 5905 5906 /* ------------------------------ */ 5907 .balign 64 5908 .L_OP_SHL_LONG_2ADDR: /* 0xc3 */ 5909 /* File: armv5te/OP_SHL_LONG_2ADDR.S */ 5910 /* 5911 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5912 * 32-bit shift distance. 5913 */ 5914 /* shl-long/2addr vA, vB */ 5915 mov r9, rINST, lsr #8 @ r9<- A+ 5916 mov r3, rINST, lsr #12 @ r3<- B 5917 and r9, r9, #15 5918 GET_VREG(r2, r3) @ r2<- vB 5919 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5920 and r2, r2, #63 @ r2<- r2 & 0x3f 5921 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5922 5923 mov r1, r1, asl r2 @ r1<- r1 << r2 5924 rsb r3, r2, #32 @ r3<- 32 - r2 5925 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 5926 subs ip, r2, #32 @ ip<- r2 - 32 5927 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5928 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 5929 mov r0, r0, asl r2 @ r0<- r0 << r2 5930 b .LOP_SHL_LONG_2ADDR_finish 5931 5932 /* ------------------------------ */ 5933 .balign 64 5934 .L_OP_SHR_LONG_2ADDR: /* 0xc4 */ 5935 /* File: armv5te/OP_SHR_LONG_2ADDR.S */ 5936 /* 5937 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5938 * 32-bit shift distance. 5939 */ 5940 /* shr-long/2addr vA, vB */ 5941 mov r9, rINST, lsr #8 @ r9<- A+ 5942 mov r3, rINST, lsr #12 @ r3<- B 5943 and r9, r9, #15 5944 GET_VREG(r2, r3) @ r2<- vB 5945 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5946 and r2, r2, #63 @ r2<- r2 & 0x3f 5947 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5948 5949 mov r0, r0, lsr r2 @ r0<- r2 >> r2 5950 rsb r3, r2, #32 @ r3<- 32 - r2 5951 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 5952 subs ip, r2, #32 @ ip<- r2 - 32 5953 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5954 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 5955 mov r1, r1, asr r2 @ r1<- r1 >> r2 5956 b .LOP_SHR_LONG_2ADDR_finish 5957 5958 /* ------------------------------ */ 5959 .balign 64 5960 .L_OP_USHR_LONG_2ADDR: /* 0xc5 */ 5961 /* File: armv5te/OP_USHR_LONG_2ADDR.S */ 5962 /* 5963 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5964 * 32-bit shift distance. 5965 */ 5966 /* ushr-long/2addr vA, vB */ 5967 mov r9, rINST, lsr #8 @ r9<- A+ 5968 mov r3, rINST, lsr #12 @ r3<- B 5969 and r9, r9, #15 5970 GET_VREG(r2, r3) @ r2<- vB 5971 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5972 and r2, r2, #63 @ r2<- r2 & 0x3f 5973 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5974 5975 mov r0, r0, lsr r2 @ r0<- r2 >> r2 5976 rsb r3, r2, #32 @ r3<- 32 - r2 5977 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 5978 subs ip, r2, #32 @ ip<- r2 - 32 5979 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5980 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 5981 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 5982 b .LOP_USHR_LONG_2ADDR_finish 5983 5984 /* ------------------------------ */ 5985 .balign 64 5986 .L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 5987 /* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */ 5988 /* File: arm-vfp/fbinop2addr.S */ 5989 /* 5990 * Generic 32-bit floating point "/2addr" binary operation. Provide 5991 * an "instr" line that specifies an instruction that performs 5992 * "s2 = s0 op s1". 5993 * 5994 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 5995 */ 5996 /* binop/2addr vA, vB */ 5997 mov r3, rINST, lsr #12 @ r3<- B 5998 mov r9, rINST, lsr #8 @ r9<- A+ 5999 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6000 and r9, r9, #15 @ r9<- A 6001 flds s1, [r3] @ s1<- vB 6002 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6003 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6004 flds s0, [r9] @ s0<- vA 6005 6006 fadds s2, s0, s1 @ s2<- op 6007 GET_INST_OPCODE(ip) @ extract opcode from rINST 6008 fsts s2, [r9] @ vAA<- s2 6009 GOTO_OPCODE(ip) @ jump to next instruction 6010 6011 6012 /* ------------------------------ */ 6013 .balign 64 6014 .L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 6015 /* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */ 6016 /* File: arm-vfp/fbinop2addr.S */ 6017 /* 6018 * Generic 32-bit floating point "/2addr" binary operation. Provide 6019 * an "instr" line that specifies an instruction that performs 6020 * "s2 = s0 op s1". 6021 * 6022 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6023 */ 6024 /* binop/2addr vA, vB */ 6025 mov r3, rINST, lsr #12 @ r3<- B 6026 mov r9, rINST, lsr #8 @ r9<- A+ 6027 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6028 and r9, r9, #15 @ r9<- A 6029 flds s1, [r3] @ s1<- vB 6030 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6031 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6032 flds s0, [r9] @ s0<- vA 6033 6034 fsubs s2, s0, s1 @ s2<- op 6035 GET_INST_OPCODE(ip) @ extract opcode from rINST 6036 fsts s2, [r9] @ vAA<- s2 6037 GOTO_OPCODE(ip) @ jump to next instruction 6038 6039 6040 /* ------------------------------ */ 6041 .balign 64 6042 .L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 6043 /* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */ 6044 /* File: arm-vfp/fbinop2addr.S */ 6045 /* 6046 * Generic 32-bit floating point "/2addr" binary operation. Provide 6047 * an "instr" line that specifies an instruction that performs 6048 * "s2 = s0 op s1". 6049 * 6050 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6051 */ 6052 /* binop/2addr vA, vB */ 6053 mov r3, rINST, lsr #12 @ r3<- B 6054 mov r9, rINST, lsr #8 @ r9<- A+ 6055 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6056 and r9, r9, #15 @ r9<- A 6057 flds s1, [r3] @ s1<- vB 6058 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6059 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6060 flds s0, [r9] @ s0<- vA 6061 6062 fmuls s2, s0, s1 @ s2<- op 6063 GET_INST_OPCODE(ip) @ extract opcode from rINST 6064 fsts s2, [r9] @ vAA<- s2 6065 GOTO_OPCODE(ip) @ jump to next instruction 6066 6067 6068 /* ------------------------------ */ 6069 .balign 64 6070 .L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 6071 /* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */ 6072 /* File: arm-vfp/fbinop2addr.S */ 6073 /* 6074 * Generic 32-bit floating point "/2addr" binary operation. Provide 6075 * an "instr" line that specifies an instruction that performs 6076 * "s2 = s0 op s1". 6077 * 6078 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6079 */ 6080 /* binop/2addr vA, vB */ 6081 mov r3, rINST, lsr #12 @ r3<- B 6082 mov r9, rINST, lsr #8 @ r9<- A+ 6083 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6084 and r9, r9, #15 @ r9<- A 6085 flds s1, [r3] @ s1<- vB 6086 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6087 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6088 flds s0, [r9] @ s0<- vA 6089 6090 fdivs s2, s0, s1 @ s2<- op 6091 GET_INST_OPCODE(ip) @ extract opcode from rINST 6092 fsts s2, [r9] @ vAA<- s2 6093 GOTO_OPCODE(ip) @ jump to next instruction 6094 6095 6096 /* ------------------------------ */ 6097 .balign 64 6098 .L_OP_REM_FLOAT_2ADDR: /* 0xca */ 6099 /* File: armv5te/OP_REM_FLOAT_2ADDR.S */ 6100 /* EABI doesn't define a float remainder function, but libm does */ 6101 /* File: armv5te/binop2addr.S */ 6102 /* 6103 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6104 * that specifies an instruction that performs "result = r0 op r1". 6105 * This could be an ARM instruction or a function call. (If the result 6106 * comes back in a register other than r0, you can override "result".) 6107 * 6108 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6109 * vCC (r1). Useful for integer division and modulus. 6110 * 6111 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6112 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6113 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6114 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6115 */ 6116 /* binop/2addr vA, vB */ 6117 mov r9, rINST, lsr #8 @ r9<- A+ 6118 mov r3, rINST, lsr #12 @ r3<- B 6119 and r9, r9, #15 6120 GET_VREG(r1, r3) @ r1<- vB 6121 GET_VREG(r0, r9) @ r0<- vA 6122 .if 0 6123 cmp r1, #0 @ is second operand zero? 6124 beq common_errDivideByZero 6125 .endif 6126 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6127 6128 @ optional op; may set condition codes 6129 bl fmodf @ r0<- op, r0-r3 changed 6130 GET_INST_OPCODE(ip) @ extract opcode from rINST 6131 SET_VREG(r0, r9) @ vAA<- r0 6132 GOTO_OPCODE(ip) @ jump to next instruction 6133 /* 10-13 instructions */ 6134 6135 6136 /* ------------------------------ */ 6137 .balign 64 6138 .L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 6139 /* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */ 6140 /* File: arm-vfp/fbinopWide2addr.S */ 6141 /* 6142 * Generic 64-bit floating point "/2addr" binary operation. Provide 6143 * an "instr" line that specifies an instruction that performs 6144 * "d2 = d0 op d1". 6145 * 6146 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6147 * div-double/2addr 6148 */ 6149 /* binop/2addr vA, vB */ 6150 mov r3, rINST, lsr #12 @ r3<- B 6151 mov r9, rINST, lsr #8 @ r9<- A+ 6152 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6153 and r9, r9, #15 @ r9<- A 6154 fldd d1, [r3] @ d1<- vB 6155 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6156 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6157 fldd d0, [r9] @ d0<- vA 6158 6159 faddd d2, d0, d1 @ d2<- op 6160 GET_INST_OPCODE(ip) @ extract opcode from rINST 6161 fstd d2, [r9] @ vAA<- d2 6162 GOTO_OPCODE(ip) @ jump to next instruction 6163 6164 6165 /* ------------------------------ */ 6166 .balign 64 6167 .L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 6168 /* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */ 6169 /* File: arm-vfp/fbinopWide2addr.S */ 6170 /* 6171 * Generic 64-bit floating point "/2addr" binary operation. Provide 6172 * an "instr" line that specifies an instruction that performs 6173 * "d2 = d0 op d1". 6174 * 6175 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6176 * div-double/2addr 6177 */ 6178 /* binop/2addr vA, vB */ 6179 mov r3, rINST, lsr #12 @ r3<- B 6180 mov r9, rINST, lsr #8 @ r9<- A+ 6181 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6182 and r9, r9, #15 @ r9<- A 6183 fldd d1, [r3] @ d1<- vB 6184 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6185 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6186 fldd d0, [r9] @ d0<- vA 6187 6188 fsubd d2, d0, d1 @ d2<- op 6189 GET_INST_OPCODE(ip) @ extract opcode from rINST 6190 fstd d2, [r9] @ vAA<- d2 6191 GOTO_OPCODE(ip) @ jump to next instruction 6192 6193 6194 /* ------------------------------ */ 6195 .balign 64 6196 .L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 6197 /* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */ 6198 /* File: arm-vfp/fbinopWide2addr.S */ 6199 /* 6200 * Generic 64-bit floating point "/2addr" binary operation. Provide 6201 * an "instr" line that specifies an instruction that performs 6202 * "d2 = d0 op d1". 6203 * 6204 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6205 * div-double/2addr 6206 */ 6207 /* binop/2addr vA, vB */ 6208 mov r3, rINST, lsr #12 @ r3<- B 6209 mov r9, rINST, lsr #8 @ r9<- A+ 6210 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6211 and r9, r9, #15 @ r9<- A 6212 fldd d1, [r3] @ d1<- vB 6213 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6214 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6215 fldd d0, [r9] @ d0<- vA 6216 6217 fmuld d2, d0, d1 @ d2<- op 6218 GET_INST_OPCODE(ip) @ extract opcode from rINST 6219 fstd d2, [r9] @ vAA<- d2 6220 GOTO_OPCODE(ip) @ jump to next instruction 6221 6222 6223 /* ------------------------------ */ 6224 .balign 64 6225 .L_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 6226 /* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */ 6227 /* File: arm-vfp/fbinopWide2addr.S */ 6228 /* 6229 * Generic 64-bit floating point "/2addr" binary operation. Provide 6230 * an "instr" line that specifies an instruction that performs 6231 * "d2 = d0 op d1". 6232 * 6233 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6234 * div-double/2addr 6235 */ 6236 /* binop/2addr vA, vB */ 6237 mov r3, rINST, lsr #12 @ r3<- B 6238 mov r9, rINST, lsr #8 @ r9<- A+ 6239 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6240 and r9, r9, #15 @ r9<- A 6241 fldd d1, [r3] @ d1<- vB 6242 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6243 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6244 fldd d0, [r9] @ d0<- vA 6245 6246 fdivd d2, d0, d1 @ d2<- op 6247 GET_INST_OPCODE(ip) @ extract opcode from rINST 6248 fstd d2, [r9] @ vAA<- d2 6249 GOTO_OPCODE(ip) @ jump to next instruction 6250 6251 6252 /* ------------------------------ */ 6253 .balign 64 6254 .L_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 6255 /* File: armv5te/OP_REM_DOUBLE_2ADDR.S */ 6256 /* EABI doesn't define a double remainder function, but libm does */ 6257 /* File: armv5te/binopWide2addr.S */ 6258 /* 6259 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6260 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6261 * This could be an ARM instruction or a function call. (If the result 6262 * comes back in a register other than r0, you can override "result".) 6263 * 6264 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6265 * vCC (r1). Useful for integer division and modulus. 6266 * 6267 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6268 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6269 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6270 * rem-double/2addr 6271 */ 6272 /* binop/2addr vA, vB */ 6273 mov r9, rINST, lsr #8 @ r9<- A+ 6274 mov r1, rINST, lsr #12 @ r1<- B 6275 and r9, r9, #15 6276 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6277 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6278 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6279 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6280 .if 0 6281 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6282 beq common_errDivideByZero 6283 .endif 6284 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6285 6286 @ optional op; may set condition codes 6287 bl fmod @ result<- op, r0-r3 changed 6288 GET_INST_OPCODE(ip) @ extract opcode from rINST 6289 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6290 GOTO_OPCODE(ip) @ jump to next instruction 6291 /* 12-15 instructions */ 6292 6293 6294 /* ------------------------------ */ 6295 .balign 64 6296 .L_OP_ADD_INT_LIT16: /* 0xd0 */ 6297 /* File: armv5te/OP_ADD_INT_LIT16.S */ 6298 /* File: armv5te/binopLit16.S */ 6299 /* 6300 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6301 * that specifies an instruction that performs "result = r0 op r1". 6302 * This could be an ARM instruction or a function call. (If the result 6303 * comes back in a register other than r0, you can override "result".) 6304 * 6305 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6306 * vCC (r1). Useful for integer division and modulus. 6307 * 6308 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6309 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6310 */ 6311 /* binop/lit16 vA, vB, #+CCCC */ 6312 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6313 mov r2, rINST, lsr #12 @ r2<- B 6314 mov r9, rINST, lsr #8 @ r9<- A+ 6315 GET_VREG(r0, r2) @ r0<- vB 6316 and r9, r9, #15 6317 .if 0 6318 cmp r1, #0 @ is second operand zero? 6319 beq common_errDivideByZero 6320 .endif 6321 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6322 6323 add r0, r0, r1 @ r0<- op, r0-r3 changed 6324 GET_INST_OPCODE(ip) @ extract opcode from rINST 6325 SET_VREG(r0, r9) @ vAA<- r0 6326 GOTO_OPCODE(ip) @ jump to next instruction 6327 /* 10-13 instructions */ 6328 6329 6330 /* ------------------------------ */ 6331 .balign 64 6332 .L_OP_RSUB_INT: /* 0xd1 */ 6333 /* File: armv5te/OP_RSUB_INT.S */ 6334 /* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */ 6335 /* File: armv5te/binopLit16.S */ 6336 /* 6337 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6338 * that specifies an instruction that performs "result = r0 op r1". 6339 * This could be an ARM instruction or a function call. (If the result 6340 * comes back in a register other than r0, you can override "result".) 6341 * 6342 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6343 * vCC (r1). Useful for integer division and modulus. 6344 * 6345 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6346 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6347 */ 6348 /* binop/lit16 vA, vB, #+CCCC */ 6349 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6350 mov r2, rINST, lsr #12 @ r2<- B 6351 mov r9, rINST, lsr #8 @ r9<- A+ 6352 GET_VREG(r0, r2) @ r0<- vB 6353 and r9, r9, #15 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 rsb r0, r0, r1 @ 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_MUL_INT_LIT16: /* 0xd2 */ 6370 /* File: armv5te/OP_MUL_INT_LIT16.S */ 6371 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6372 /* File: armv5te/binopLit16.S */ 6373 /* 6374 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6375 * that specifies an instruction that performs "result = r0 op r1". 6376 * This could be an ARM instruction or a function call. (If the result 6377 * comes back in a register other than r0, you can override "result".) 6378 * 6379 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6380 * vCC (r1). Useful for integer division and modulus. 6381 * 6382 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6383 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6384 */ 6385 /* binop/lit16 vA, vB, #+CCCC */ 6386 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6387 mov r2, rINST, lsr #12 @ r2<- B 6388 mov r9, rINST, lsr #8 @ r9<- A+ 6389 GET_VREG(r0, r2) @ r0<- vB 6390 and r9, r9, #15 6391 .if 0 6392 cmp r1, #0 @ is second operand zero? 6393 beq common_errDivideByZero 6394 .endif 6395 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6396 6397 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6398 GET_INST_OPCODE(ip) @ extract opcode from rINST 6399 SET_VREG(r0, r9) @ vAA<- r0 6400 GOTO_OPCODE(ip) @ jump to next instruction 6401 /* 10-13 instructions */ 6402 6403 6404 /* ------------------------------ */ 6405 .balign 64 6406 .L_OP_DIV_INT_LIT16: /* 0xd3 */ 6407 /* File: armv5te/OP_DIV_INT_LIT16.S */ 6408 /* File: armv5te/binopLit16.S */ 6409 /* 6410 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6411 * that specifies an instruction that performs "result = r0 op r1". 6412 * This could be an ARM instruction or a function call. (If the result 6413 * comes back in a register other than r0, you can override "result".) 6414 * 6415 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6416 * vCC (r1). Useful for integer division and modulus. 6417 * 6418 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6419 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6420 */ 6421 /* binop/lit16 vA, vB, #+CCCC */ 6422 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6423 mov r2, rINST, lsr #12 @ r2<- B 6424 mov r9, rINST, lsr #8 @ r9<- A+ 6425 GET_VREG(r0, r2) @ r0<- vB 6426 and r9, r9, #15 6427 .if 1 6428 cmp r1, #0 @ is second operand zero? 6429 beq common_errDivideByZero 6430 .endif 6431 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6432 6433 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6434 GET_INST_OPCODE(ip) @ extract opcode from rINST 6435 SET_VREG(r0, r9) @ vAA<- r0 6436 GOTO_OPCODE(ip) @ jump to next instruction 6437 /* 10-13 instructions */ 6438 6439 6440 /* ------------------------------ */ 6441 .balign 64 6442 .L_OP_REM_INT_LIT16: /* 0xd4 */ 6443 /* File: armv5te/OP_REM_INT_LIT16.S */ 6444 /* idivmod returns quotient in r0 and remainder in r1 */ 6445 /* File: armv5te/binopLit16.S */ 6446 /* 6447 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6448 * that specifies an instruction that performs "result = r0 op r1". 6449 * This could be an ARM instruction or a function call. (If the result 6450 * comes back in a register other than r0, you can override "result".) 6451 * 6452 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6453 * vCC (r1). Useful for integer division and modulus. 6454 * 6455 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6456 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6457 */ 6458 /* binop/lit16 vA, vB, #+CCCC */ 6459 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6460 mov r2, rINST, lsr #12 @ r2<- B 6461 mov r9, rINST, lsr #8 @ r9<- A+ 6462 GET_VREG(r0, r2) @ r0<- vB 6463 and r9, r9, #15 6464 .if 1 6465 cmp r1, #0 @ is second operand zero? 6466 beq common_errDivideByZero 6467 .endif 6468 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6469 6470 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6471 GET_INST_OPCODE(ip) @ extract opcode from rINST 6472 SET_VREG(r1, r9) @ vAA<- r1 6473 GOTO_OPCODE(ip) @ jump to next instruction 6474 /* 10-13 instructions */ 6475 6476 6477 /* ------------------------------ */ 6478 .balign 64 6479 .L_OP_AND_INT_LIT16: /* 0xd5 */ 6480 /* File: armv5te/OP_AND_INT_LIT16.S */ 6481 /* File: armv5te/binopLit16.S */ 6482 /* 6483 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6484 * that specifies an instruction that performs "result = r0 op r1". 6485 * This could be an ARM instruction or a function call. (If the result 6486 * comes back in a register other than r0, you can override "result".) 6487 * 6488 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6489 * vCC (r1). Useful for integer division and modulus. 6490 * 6491 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6492 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6493 */ 6494 /* binop/lit16 vA, vB, #+CCCC */ 6495 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6496 mov r2, rINST, lsr #12 @ r2<- B 6497 mov r9, rINST, lsr #8 @ r9<- A+ 6498 GET_VREG(r0, r2) @ r0<- vB 6499 and r9, r9, #15 6500 .if 0 6501 cmp r1, #0 @ is second operand zero? 6502 beq common_errDivideByZero 6503 .endif 6504 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6505 6506 and r0, r0, r1 @ r0<- op, r0-r3 changed 6507 GET_INST_OPCODE(ip) @ extract opcode from rINST 6508 SET_VREG(r0, r9) @ vAA<- r0 6509 GOTO_OPCODE(ip) @ jump to next instruction 6510 /* 10-13 instructions */ 6511 6512 6513 /* ------------------------------ */ 6514 .balign 64 6515 .L_OP_OR_INT_LIT16: /* 0xd6 */ 6516 /* File: armv5te/OP_OR_INT_LIT16.S */ 6517 /* File: armv5te/binopLit16.S */ 6518 /* 6519 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6520 * that specifies an instruction that performs "result = r0 op r1". 6521 * This could be an ARM instruction or a function call. (If the result 6522 * comes back in a register other than r0, you can override "result".) 6523 * 6524 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6525 * vCC (r1). Useful for integer division and modulus. 6526 * 6527 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6528 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6529 */ 6530 /* binop/lit16 vA, vB, #+CCCC */ 6531 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6532 mov r2, rINST, lsr #12 @ r2<- B 6533 mov r9, rINST, lsr #8 @ r9<- A+ 6534 GET_VREG(r0, r2) @ r0<- vB 6535 and r9, r9, #15 6536 .if 0 6537 cmp r1, #0 @ is second operand zero? 6538 beq common_errDivideByZero 6539 .endif 6540 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6541 6542 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6543 GET_INST_OPCODE(ip) @ extract opcode from rINST 6544 SET_VREG(r0, r9) @ vAA<- r0 6545 GOTO_OPCODE(ip) @ jump to next instruction 6546 /* 10-13 instructions */ 6547 6548 6549 /* ------------------------------ */ 6550 .balign 64 6551 .L_OP_XOR_INT_LIT16: /* 0xd7 */ 6552 /* File: armv5te/OP_XOR_INT_LIT16.S */ 6553 /* File: armv5te/binopLit16.S */ 6554 /* 6555 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6556 * that specifies an instruction that performs "result = r0 op r1". 6557 * This could be an ARM instruction or a function call. (If the result 6558 * comes back in a register other than r0, you can override "result".) 6559 * 6560 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6561 * vCC (r1). Useful for integer division and modulus. 6562 * 6563 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6564 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6565 */ 6566 /* binop/lit16 vA, vB, #+CCCC */ 6567 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6568 mov r2, rINST, lsr #12 @ r2<- B 6569 mov r9, rINST, lsr #8 @ r9<- A+ 6570 GET_VREG(r0, r2) @ r0<- vB 6571 and r9, r9, #15 6572 .if 0 6573 cmp r1, #0 @ is second operand zero? 6574 beq common_errDivideByZero 6575 .endif 6576 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6577 6578 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6579 GET_INST_OPCODE(ip) @ extract opcode from rINST 6580 SET_VREG(r0, r9) @ vAA<- r0 6581 GOTO_OPCODE(ip) @ jump to next instruction 6582 /* 10-13 instructions */ 6583 6584 6585 /* ------------------------------ */ 6586 .balign 64 6587 .L_OP_ADD_INT_LIT8: /* 0xd8 */ 6588 /* File: armv5te/OP_ADD_INT_LIT8.S */ 6589 /* File: armv5te/binopLit8.S */ 6590 /* 6591 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6592 * that specifies an instruction that performs "result = r0 op r1". 6593 * This could be an ARM instruction or a function call. (If the result 6594 * comes back in a register other than r0, you can override "result".) 6595 * 6596 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6597 * vCC (r1). Useful for integer division and modulus. 6598 * 6599 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6600 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6601 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6602 */ 6603 /* binop/lit8 vAA, vBB, #+CC */ 6604 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6605 mov r9, rINST, lsr #8 @ r9<- AA 6606 and r2, r3, #255 @ r2<- BB 6607 GET_VREG(r0, r2) @ r0<- vBB 6608 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6609 .if 0 6610 @cmp r1, #0 @ is second operand zero? 6611 beq common_errDivideByZero 6612 .endif 6613 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6614 6615 @ optional op; may set condition codes 6616 add r0, r0, r1 @ r0<- op, r0-r3 changed 6617 GET_INST_OPCODE(ip) @ extract opcode from rINST 6618 SET_VREG(r0, r9) @ vAA<- r0 6619 GOTO_OPCODE(ip) @ jump to next instruction 6620 /* 10-12 instructions */ 6621 6622 6623 /* ------------------------------ */ 6624 .balign 64 6625 .L_OP_RSUB_INT_LIT8: /* 0xd9 */ 6626 /* File: armv5te/OP_RSUB_INT_LIT8.S */ 6627 /* File: armv5te/binopLit8.S */ 6628 /* 6629 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6630 * that specifies an instruction that performs "result = r0 op r1". 6631 * This could be an ARM instruction or a function call. (If the result 6632 * comes back in a register other than r0, you can override "result".) 6633 * 6634 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6635 * vCC (r1). Useful for integer division and modulus. 6636 * 6637 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6638 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6639 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6640 */ 6641 /* binop/lit8 vAA, vBB, #+CC */ 6642 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6643 mov r9, rINST, lsr #8 @ r9<- AA 6644 and r2, r3, #255 @ r2<- BB 6645 GET_VREG(r0, r2) @ r0<- vBB 6646 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6647 .if 0 6648 @cmp r1, #0 @ is second operand zero? 6649 beq common_errDivideByZero 6650 .endif 6651 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6652 6653 @ optional op; may set condition codes 6654 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6655 GET_INST_OPCODE(ip) @ extract opcode from rINST 6656 SET_VREG(r0, r9) @ vAA<- r0 6657 GOTO_OPCODE(ip) @ jump to next instruction 6658 /* 10-12 instructions */ 6659 6660 6661 /* ------------------------------ */ 6662 .balign 64 6663 .L_OP_MUL_INT_LIT8: /* 0xda */ 6664 /* File: armv5te/OP_MUL_INT_LIT8.S */ 6665 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6666 /* File: armv5te/binopLit8.S */ 6667 /* 6668 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6669 * that specifies an instruction that performs "result = r0 op r1". 6670 * This could be an ARM instruction or a function call. (If the result 6671 * comes back in a register other than r0, you can override "result".) 6672 * 6673 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6674 * vCC (r1). Useful for integer division and modulus. 6675 * 6676 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6677 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6678 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6679 */ 6680 /* binop/lit8 vAA, vBB, #+CC */ 6681 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6682 mov r9, rINST, lsr #8 @ r9<- AA 6683 and r2, r3, #255 @ r2<- BB 6684 GET_VREG(r0, r2) @ r0<- vBB 6685 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6686 .if 0 6687 @cmp r1, #0 @ is second operand zero? 6688 beq common_errDivideByZero 6689 .endif 6690 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6691 6692 @ optional op; may set condition codes 6693 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6694 GET_INST_OPCODE(ip) @ extract opcode from rINST 6695 SET_VREG(r0, r9) @ vAA<- r0 6696 GOTO_OPCODE(ip) @ jump to next instruction 6697 /* 10-12 instructions */ 6698 6699 6700 /* ------------------------------ */ 6701 .balign 64 6702 .L_OP_DIV_INT_LIT8: /* 0xdb */ 6703 /* File: armv5te/OP_DIV_INT_LIT8.S */ 6704 /* File: armv5te/binopLit8.S */ 6705 /* 6706 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6707 * that specifies an instruction that performs "result = r0 op r1". 6708 * This could be an ARM instruction or a function call. (If the result 6709 * comes back in a register other than r0, you can override "result".) 6710 * 6711 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6712 * vCC (r1). Useful for integer division and modulus. 6713 * 6714 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6715 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6716 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6717 */ 6718 /* binop/lit8 vAA, vBB, #+CC */ 6719 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6720 mov r9, rINST, lsr #8 @ r9<- AA 6721 and r2, r3, #255 @ r2<- BB 6722 GET_VREG(r0, r2) @ r0<- vBB 6723 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6724 .if 1 6725 @cmp r1, #0 @ is second operand zero? 6726 beq common_errDivideByZero 6727 .endif 6728 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6729 6730 @ optional op; may set condition codes 6731 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6732 GET_INST_OPCODE(ip) @ extract opcode from rINST 6733 SET_VREG(r0, r9) @ vAA<- r0 6734 GOTO_OPCODE(ip) @ jump to next instruction 6735 /* 10-12 instructions */ 6736 6737 6738 /* ------------------------------ */ 6739 .balign 64 6740 .L_OP_REM_INT_LIT8: /* 0xdc */ 6741 /* File: armv5te/OP_REM_INT_LIT8.S */ 6742 /* idivmod returns quotient in r0 and remainder in r1 */ 6743 /* File: armv5te/binopLit8.S */ 6744 /* 6745 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6746 * that specifies an instruction that performs "result = r0 op r1". 6747 * This could be an ARM instruction or a function call. (If the result 6748 * comes back in a register other than r0, you can override "result".) 6749 * 6750 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6751 * vCC (r1). Useful for integer division and modulus. 6752 * 6753 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6754 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6755 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6756 */ 6757 /* binop/lit8 vAA, vBB, #+CC */ 6758 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6759 mov r9, rINST, lsr #8 @ r9<- AA 6760 and r2, r3, #255 @ r2<- BB 6761 GET_VREG(r0, r2) @ r0<- vBB 6762 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6763 .if 1 6764 @cmp r1, #0 @ is second operand zero? 6765 beq common_errDivideByZero 6766 .endif 6767 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6768 6769 @ optional op; may set condition codes 6770 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6771 GET_INST_OPCODE(ip) @ extract opcode from rINST 6772 SET_VREG(r1, r9) @ vAA<- r1 6773 GOTO_OPCODE(ip) @ jump to next instruction 6774 /* 10-12 instructions */ 6775 6776 6777 /* ------------------------------ */ 6778 .balign 64 6779 .L_OP_AND_INT_LIT8: /* 0xdd */ 6780 /* File: armv5te/OP_AND_INT_LIT8.S */ 6781 /* File: armv5te/binopLit8.S */ 6782 /* 6783 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6784 * that specifies an instruction that performs "result = r0 op r1". 6785 * This could be an ARM instruction or a function call. (If the result 6786 * comes back in a register other than r0, you can override "result".) 6787 * 6788 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6789 * vCC (r1). Useful for integer division and modulus. 6790 * 6791 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6792 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6793 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6794 */ 6795 /* binop/lit8 vAA, vBB, #+CC */ 6796 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6797 mov r9, rINST, lsr #8 @ r9<- AA 6798 and r2, r3, #255 @ r2<- BB 6799 GET_VREG(r0, r2) @ r0<- vBB 6800 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6801 .if 0 6802 @cmp r1, #0 @ is second operand zero? 6803 beq common_errDivideByZero 6804 .endif 6805 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6806 6807 @ optional op; may set condition codes 6808 and r0, r0, r1 @ r0<- op, r0-r3 changed 6809 GET_INST_OPCODE(ip) @ extract opcode from rINST 6810 SET_VREG(r0, r9) @ vAA<- r0 6811 GOTO_OPCODE(ip) @ jump to next instruction 6812 /* 10-12 instructions */ 6813 6814 6815 /* ------------------------------ */ 6816 .balign 64 6817 .L_OP_OR_INT_LIT8: /* 0xde */ 6818 /* File: armv5te/OP_OR_INT_LIT8.S */ 6819 /* File: armv5te/binopLit8.S */ 6820 /* 6821 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6822 * that specifies an instruction that performs "result = r0 op r1". 6823 * This could be an ARM instruction or a function call. (If the result 6824 * comes back in a register other than r0, you can override "result".) 6825 * 6826 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6827 * vCC (r1). Useful for integer division and modulus. 6828 * 6829 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6830 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6831 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6832 */ 6833 /* binop/lit8 vAA, vBB, #+CC */ 6834 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6835 mov r9, rINST, lsr #8 @ r9<- AA 6836 and r2, r3, #255 @ r2<- BB 6837 GET_VREG(r0, r2) @ r0<- vBB 6838 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6839 .if 0 6840 @cmp r1, #0 @ is second operand zero? 6841 beq common_errDivideByZero 6842 .endif 6843 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6844 6845 @ optional op; may set condition codes 6846 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6847 GET_INST_OPCODE(ip) @ extract opcode from rINST 6848 SET_VREG(r0, r9) @ vAA<- r0 6849 GOTO_OPCODE(ip) @ jump to next instruction 6850 /* 10-12 instructions */ 6851 6852 6853 /* ------------------------------ */ 6854 .balign 64 6855 .L_OP_XOR_INT_LIT8: /* 0xdf */ 6856 /* File: armv5te/OP_XOR_INT_LIT8.S */ 6857 /* File: armv5te/binopLit8.S */ 6858 /* 6859 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6860 * that specifies an instruction that performs "result = r0 op r1". 6861 * This could be an ARM instruction or a function call. (If the result 6862 * comes back in a register other than r0, you can override "result".) 6863 * 6864 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6865 * vCC (r1). Useful for integer division and modulus. 6866 * 6867 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6868 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6869 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6870 */ 6871 /* binop/lit8 vAA, vBB, #+CC */ 6872 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6873 mov r9, rINST, lsr #8 @ r9<- AA 6874 and r2, r3, #255 @ r2<- BB 6875 GET_VREG(r0, r2) @ r0<- vBB 6876 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6877 .if 0 6878 @cmp r1, #0 @ is second operand zero? 6879 beq common_errDivideByZero 6880 .endif 6881 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6882 6883 @ optional op; may set condition codes 6884 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6885 GET_INST_OPCODE(ip) @ extract opcode from rINST 6886 SET_VREG(r0, r9) @ vAA<- r0 6887 GOTO_OPCODE(ip) @ jump to next instruction 6888 /* 10-12 instructions */ 6889 6890 6891 /* ------------------------------ */ 6892 .balign 64 6893 .L_OP_SHL_INT_LIT8: /* 0xe0 */ 6894 /* File: armv5te/OP_SHL_INT_LIT8.S */ 6895 /* File: armv5te/binopLit8.S */ 6896 /* 6897 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6898 * that specifies an instruction that performs "result = r0 op r1". 6899 * This could be an ARM instruction or a function call. (If the result 6900 * comes back in a register other than r0, you can override "result".) 6901 * 6902 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6903 * vCC (r1). Useful for integer division and modulus. 6904 * 6905 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6906 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6907 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6908 */ 6909 /* binop/lit8 vAA, vBB, #+CC */ 6910 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6911 mov r9, rINST, lsr #8 @ r9<- AA 6912 and r2, r3, #255 @ r2<- BB 6913 GET_VREG(r0, r2) @ r0<- vBB 6914 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6915 .if 0 6916 @cmp r1, #0 @ is second operand zero? 6917 beq common_errDivideByZero 6918 .endif 6919 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6920 6921 and r1, r1, #31 @ optional op; may set condition codes 6922 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 6923 GET_INST_OPCODE(ip) @ extract opcode from rINST 6924 SET_VREG(r0, r9) @ vAA<- r0 6925 GOTO_OPCODE(ip) @ jump to next instruction 6926 /* 10-12 instructions */ 6927 6928 6929 /* ------------------------------ */ 6930 .balign 64 6931 .L_OP_SHR_INT_LIT8: /* 0xe1 */ 6932 /* File: armv5te/OP_SHR_INT_LIT8.S */ 6933 /* File: armv5te/binopLit8.S */ 6934 /* 6935 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6936 * that specifies an instruction that performs "result = r0 op r1". 6937 * This could be an ARM instruction or a function call. (If the result 6938 * comes back in a register other than r0, you can override "result".) 6939 * 6940 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6941 * vCC (r1). Useful for integer division and modulus. 6942 * 6943 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6944 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6945 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6946 */ 6947 /* binop/lit8 vAA, vBB, #+CC */ 6948 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6949 mov r9, rINST, lsr #8 @ r9<- AA 6950 and r2, r3, #255 @ r2<- BB 6951 GET_VREG(r0, r2) @ r0<- vBB 6952 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6953 .if 0 6954 @cmp r1, #0 @ is second operand zero? 6955 beq common_errDivideByZero 6956 .endif 6957 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6958 6959 and r1, r1, #31 @ optional op; may set condition codes 6960 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 6961 GET_INST_OPCODE(ip) @ extract opcode from rINST 6962 SET_VREG(r0, r9) @ vAA<- r0 6963 GOTO_OPCODE(ip) @ jump to next instruction 6964 /* 10-12 instructions */ 6965 6966 6967 /* ------------------------------ */ 6968 .balign 64 6969 .L_OP_USHR_INT_LIT8: /* 0xe2 */ 6970 /* File: armv5te/OP_USHR_INT_LIT8.S */ 6971 /* File: armv5te/binopLit8.S */ 6972 /* 6973 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6974 * that specifies an instruction that performs "result = r0 op r1". 6975 * This could be an ARM instruction or a function call. (If the result 6976 * comes back in a register other than r0, you can override "result".) 6977 * 6978 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6979 * vCC (r1). Useful for integer division and modulus. 6980 * 6981 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6982 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6983 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6984 */ 6985 /* binop/lit8 vAA, vBB, #+CC */ 6986 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6987 mov r9, rINST, lsr #8 @ r9<- AA 6988 and r2, r3, #255 @ r2<- BB 6989 GET_VREG(r0, r2) @ r0<- vBB 6990 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6991 .if 0 6992 @cmp r1, #0 @ is second operand zero? 6993 beq common_errDivideByZero 6994 .endif 6995 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6996 6997 and r1, r1, #31 @ optional op; may set condition codes 6998 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 6999 GET_INST_OPCODE(ip) @ extract opcode from rINST 7000 SET_VREG(r0, r9) @ vAA<- r0 7001 GOTO_OPCODE(ip) @ jump to next instruction 7002 /* 10-12 instructions */ 7003 7004 7005 /* ------------------------------ */ 7006 .balign 64 7007 .L_OP_IGET_VOLATILE: /* 0xe3 */ 7008 /* File: armv5te/OP_IGET_VOLATILE.S */ 7009 /* File: armv5te/OP_IGET.S */ 7010 /* 7011 * General 32-bit instance field get. 7012 * 7013 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7014 */ 7015 /* op vA, vB, field@CCCC */ 7016 mov r0, rINST, lsr #12 @ r0<- B 7017 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7018 FETCH(r1, 1) @ r1<- field ref CCCC 7019 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7020 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7021 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7022 cmp r0, #0 @ is resolved entry null? 7023 bne .LOP_IGET_VOLATILE_finish @ no, already resolved 7024 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7025 EXPORT_PC() @ resolve() could throw 7026 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7027 bl dvmResolveInstField @ r0<- resolved InstField ptr 7028 cmp r0, #0 7029 bne .LOP_IGET_VOLATILE_finish 7030 b common_exceptionThrown 7031 7032 7033 /* ------------------------------ */ 7034 .balign 64 7035 .L_OP_IPUT_VOLATILE: /* 0xe4 */ 7036 /* File: armv5te/OP_IPUT_VOLATILE.S */ 7037 /* File: armv5te/OP_IPUT.S */ 7038 /* 7039 * General 32-bit instance field put. 7040 * 7041 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 7042 */ 7043 /* op vA, vB, field@CCCC */ 7044 mov r0, rINST, lsr #12 @ r0<- B 7045 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7046 FETCH(r1, 1) @ r1<- field ref CCCC 7047 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7048 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7049 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7050 cmp r0, #0 @ is resolved entry null? 7051 bne .LOP_IPUT_VOLATILE_finish @ no, already resolved 7052 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7053 EXPORT_PC() @ resolve() could throw 7054 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7055 bl dvmResolveInstField @ r0<- resolved InstField ptr 7056 cmp r0, #0 @ success? 7057 bne .LOP_IPUT_VOLATILE_finish @ yes, finish up 7058 b common_exceptionThrown 7059 7060 7061 /* ------------------------------ */ 7062 .balign 64 7063 .L_OP_SGET_VOLATILE: /* 0xe5 */ 7064 /* File: armv5te/OP_SGET_VOLATILE.S */ 7065 /* File: armv5te/OP_SGET.S */ 7066 /* 7067 * General 32-bit SGET handler. 7068 * 7069 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7070 */ 7071 /* op vAA, field@BBBB */ 7072 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7073 FETCH(r1, 1) @ r1<- field ref BBBB 7074 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7075 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7076 cmp r0, #0 @ is resolved entry null? 7077 beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve 7078 .LOP_SGET_VOLATILE_finish: @ field ptr in r0 7079 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7080 SMP_DMB @ acquiring load 7081 mov r2, rINST, lsr #8 @ r2<- AA 7082 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7083 SET_VREG(r1, r2) @ fp[AA]<- r1 7084 GET_INST_OPCODE(ip) @ extract opcode from rINST 7085 GOTO_OPCODE(ip) @ jump to next instruction 7086 7087 7088 /* ------------------------------ */ 7089 .balign 64 7090 .L_OP_SPUT_VOLATILE: /* 0xe6 */ 7091 /* File: armv5te/OP_SPUT_VOLATILE.S */ 7092 /* File: armv5te/OP_SPUT.S */ 7093 /* 7094 * General 32-bit SPUT handler. 7095 * 7096 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 7097 */ 7098 /* op vAA, field@BBBB */ 7099 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7100 FETCH(r1, 1) @ r1<- field ref BBBB 7101 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7102 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7103 cmp r0, #0 @ is resolved entry null? 7104 beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve 7105 .LOP_SPUT_VOLATILE_finish: @ field ptr in r0 7106 mov r2, rINST, lsr #8 @ r2<- AA 7107 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7108 GET_VREG(r1, r2) @ r1<- fp[AA] 7109 GET_INST_OPCODE(ip) @ extract opcode from rINST 7110 SMP_DMB_ST @ releasing store 7111 str r1, [r0, #offStaticField_value] @ field<- vAA 7112 SMP_DMB 7113 GOTO_OPCODE(ip) @ jump to next instruction 7114 7115 7116 /* ------------------------------ */ 7117 .balign 64 7118 .L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 7119 /* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */ 7120 /* File: armv5te/OP_IGET.S */ 7121 /* 7122 * General 32-bit instance field get. 7123 * 7124 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7125 */ 7126 /* op vA, vB, field@CCCC */ 7127 mov r0, rINST, lsr #12 @ r0<- B 7128 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7129 FETCH(r1, 1) @ r1<- field ref CCCC 7130 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7131 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7132 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7133 cmp r0, #0 @ is resolved entry null? 7134 bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved 7135 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7136 EXPORT_PC() @ resolve() could throw 7137 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7138 bl dvmResolveInstField @ r0<- resolved InstField ptr 7139 cmp r0, #0 7140 bne .LOP_IGET_OBJECT_VOLATILE_finish 7141 b common_exceptionThrown 7142 7143 7144 /* ------------------------------ */ 7145 .balign 64 7146 .L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 7147 /* File: armv5te/OP_IGET_WIDE_VOLATILE.S */ 7148 /* File: armv5te/OP_IGET_WIDE.S */ 7149 /* 7150 * Wide 32-bit instance field get. 7151 */ 7152 /* iget-wide vA, vB, field@CCCC */ 7153 mov r0, rINST, lsr #12 @ r0<- B 7154 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7155 FETCH(r1, 1) @ r1<- field ref CCCC 7156 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7157 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7158 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7159 cmp r0, #0 @ is resolved entry null? 7160 bne .LOP_IGET_WIDE_VOLATILE_finish @ no, already resolved 7161 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7162 EXPORT_PC() @ resolve() could throw 7163 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7164 bl dvmResolveInstField @ r0<- resolved InstField ptr 7165 cmp r0, #0 7166 bne .LOP_IGET_WIDE_VOLATILE_finish 7167 b common_exceptionThrown 7168 7169 7170 /* ------------------------------ */ 7171 .balign 64 7172 .L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 7173 /* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */ 7174 /* File: armv5te/OP_IPUT_WIDE.S */ 7175 /* iput-wide vA, vB, field@CCCC */ 7176 mov r0, rINST, lsr #12 @ r0<- B 7177 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7178 FETCH(r1, 1) @ r1<- field ref CCCC 7179 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7180 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7181 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7182 cmp r0, #0 @ is resolved entry null? 7183 bne .LOP_IPUT_WIDE_VOLATILE_finish @ no, already resolved 7184 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7185 EXPORT_PC() @ resolve() could throw 7186 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7187 bl dvmResolveInstField @ r0<- resolved InstField ptr 7188 cmp r0, #0 @ success? 7189 bne .LOP_IPUT_WIDE_VOLATILE_finish @ yes, finish up 7190 b common_exceptionThrown 7191 7192 7193 /* ------------------------------ */ 7194 .balign 64 7195 .L_OP_SGET_WIDE_VOLATILE: /* 0xea */ 7196 /* File: armv5te/OP_SGET_WIDE_VOLATILE.S */ 7197 /* File: armv5te/OP_SGET_WIDE.S */ 7198 /* 7199 * 64-bit SGET handler. 7200 */ 7201 /* sget-wide vAA, field@BBBB */ 7202 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7203 FETCH(r1, 1) @ r1<- field ref BBBB 7204 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7205 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7206 cmp r0, #0 @ is resolved entry null? 7207 beq .LOP_SGET_WIDE_VOLATILE_resolve @ yes, do resolve 7208 .LOP_SGET_WIDE_VOLATILE_finish: 7209 mov r9, rINST, lsr #8 @ r9<- AA 7210 .if 1 7211 add r0, r0, #offStaticField_value @ r0<- pointer to data 7212 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 7213 .else 7214 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 7215 .endif 7216 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7217 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7218 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 7219 GET_INST_OPCODE(ip) @ extract opcode from rINST 7220 GOTO_OPCODE(ip) @ jump to next instruction 7221 7222 7223 /* ------------------------------ */ 7224 .balign 64 7225 .L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 7226 /* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */ 7227 /* File: armv5te/OP_SPUT_WIDE.S */ 7228 /* 7229 * 64-bit SPUT handler. 7230 */ 7231 /* sput-wide vAA, field@BBBB */ 7232 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- DvmDex 7233 FETCH(r1, 1) @ r1<- field ref BBBB 7234 ldr r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7235 mov r9, rINST, lsr #8 @ r9<- AA 7236 ldr r2, [r10, r1, lsl #2] @ r2<- resolved StaticField ptr 7237 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7238 cmp r2, #0 @ is resolved entry null? 7239 beq .LOP_SPUT_WIDE_VOLATILE_resolve @ yes, do resolve 7240 .LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9 7241 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7242 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 7243 GET_INST_OPCODE(r10) @ extract opcode from rINST 7244 .if 1 7245 add r2, r2, #offStaticField_value @ r2<- pointer to data 7246 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 7247 .else 7248 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 7249 .endif 7250 GOTO_OPCODE(r10) @ jump to next instruction 7251 7252 7253 /* ------------------------------ */ 7254 .balign 64 7255 .L_OP_BREAKPOINT: /* 0xec */ 7256 /* File: armv5te/OP_BREAKPOINT.S */ 7257 /* 7258 * Breakpoint handler. 7259 * 7260 * Restart this instruction with the original opcode. By 7261 * the time we get here, the breakpoint will have already been 7262 * handled. 7263 */ 7264 mov r0, rPC 7265 bl dvmGetOriginalOpcode @ (rPC) 7266 FETCH(rINST, 0) @ reload OP_BREAKPOINT + rest of inst 7267 ldr r1, [rSELF, #offThread_mainHandlerTable] 7268 and rINST, #0xff00 7269 orr rINST, rINST, r0 7270 GOTO_OPCODE_BASE(r1, r0) 7271 7272 /* ------------------------------ */ 7273 .balign 64 7274 .L_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 7275 /* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */ 7276 /* 7277 * Handle a throw-verification-error instruction. This throws an 7278 * exception for an error discovered during verification. The 7279 * exception is indicated by AA, with some detail provided by BBBB. 7280 */ 7281 /* op AA, ref@BBBB */ 7282 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7283 FETCH(r2, 1) @ r2<- BBBB 7284 EXPORT_PC() @ export the PC 7285 mov r1, rINST, lsr #8 @ r1<- AA 7286 bl dvmThrowVerificationError @ always throws 7287 b common_exceptionThrown @ handle exception 7288 7289 /* ------------------------------ */ 7290 .balign 64 7291 .L_OP_EXECUTE_INLINE: /* 0xee */ 7292 /* File: armv5te/OP_EXECUTE_INLINE.S */ 7293 /* 7294 * Execute a "native inline" instruction. 7295 * 7296 * We need to call an InlineOp4Func: 7297 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7298 * 7299 * The first four args are in r0-r3, pointer to return value storage 7300 * is on the stack. The function's return value is a flag that tells 7301 * us if an exception was thrown. 7302 * 7303 * TUNING: could maintain two tables, pointer in Thread and 7304 * swap if profiler/debuggger active. 7305 */ 7306 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 7307 ldrh r2, [rSELF, #offThread_subMode] 7308 FETCH(r10, 1) @ r10<- BBBB 7309 EXPORT_PC() @ can throw 7310 ands r2, #kSubModeDebugProfile @ Any going on? 7311 bne .LOP_EXECUTE_INLINE_debugmode @ yes - take slow path 7312 .LOP_EXECUTE_INLINE_resume: 7313 add r1, rSELF, #offThread_retval @ r1<- &self->retval 7314 sub sp, sp, #8 @ make room for arg, +64 bit align 7315 mov r0, rINST, lsr #12 @ r0<- B 7316 str r1, [sp] @ push &self->retval 7317 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 7318 add sp, sp, #8 @ pop stack 7319 cmp r0, #0 @ test boolean result of inline 7320 beq common_exceptionThrown @ returned false, handle exception 7321 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7322 GET_INST_OPCODE(ip) @ extract opcode from rINST 7323 GOTO_OPCODE(ip) @ jump to next instruction 7324 7325 /* ------------------------------ */ 7326 .balign 64 7327 .L_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 7328 /* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */ 7329 /* 7330 * Execute a "native inline" instruction, using "/range" semantics. 7331 * Same idea as execute-inline, but we get the args differently. 7332 * 7333 * We need to call an InlineOp4Func: 7334 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7335 * 7336 * The first four args are in r0-r3, pointer to return value storage 7337 * is on the stack. The function's return value is a flag that tells 7338 * us if an exception was thrown. 7339 */ 7340 /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */ 7341 ldrh r2, [rSELF, #offThread_subMode] 7342 FETCH(r10, 1) @ r10<- BBBB 7343 EXPORT_PC() @ can throw 7344 ands r2, #kSubModeDebugProfile @ Any going on? 7345 bne .LOP_EXECUTE_INLINE_RANGE_debugmode @ yes - take slow path 7346 .LOP_EXECUTE_INLINE_RANGE_resume: 7347 add r1, rSELF, #offThread_retval @ r1<- &self->retval 7348 sub sp, sp, #8 @ make room for arg, +64 bit align 7349 mov r0, rINST, lsr #8 @ r0<- AA 7350 str r1, [sp] @ push &self->retval 7351 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 7352 add sp, sp, #8 @ pop stack 7353 cmp r0, #0 @ test boolean result of inline 7354 beq common_exceptionThrown @ returned false, handle exception 7355 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7356 GET_INST_OPCODE(ip) @ extract opcode from rINST 7357 GOTO_OPCODE(ip) @ jump to next instruction 7358 7359 /* ------------------------------ */ 7360 .balign 64 7361 .L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */ 7362 /* File: armv5te/OP_INVOKE_OBJECT_INIT_RANGE.S */ 7363 /* 7364 * Invoke Object.<init> on an object. In practice we know that 7365 * Object's nullary constructor doesn't do anything, so we just 7366 * skip it unless a debugger is active. 7367 */ 7368 FETCH(r1, 2) @ r1<- CCCC 7369 GET_VREG(r0, r1) @ r0<- "this" ptr 7370 cmp r0, #0 @ check for NULL 7371 beq common_errNullObject @ export PC and throw NPE 7372 ldr r1, [r0, #offObject_clazz] @ r1<- obj->clazz 7373 ldr r2, [r1, #offClassObject_accessFlags] @ r2<- clazz->accessFlags 7374 tst r2, #CLASS_ISFINALIZABLE @ is this class finalizable? 7375 bne .LOP_INVOKE_OBJECT_INIT_RANGE_setFinal @ yes, go 7376 .LOP_INVOKE_OBJECT_INIT_RANGE_finish: 7377 ldrh r1, [rSELF, #offThread_subMode] 7378 ands r1, #kSubModeDebuggerActive @ debugger active? 7379 bne .LOP_INVOKE_OBJECT_INIT_RANGE_debugger @ Yes - skip optimization 7380 FETCH_ADVANCE_INST(2+1) @ advance to next instr, load rINST 7381 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 7382 GOTO_OPCODE(ip) @ execute it 7383 7384 /* ------------------------------ */ 7385 .balign 64 7386 .L_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 7387 /* File: armv5te/OP_RETURN_VOID_BARRIER.S */ 7388 SMP_DMB_ST 7389 b common_returnFromMethod 7390 7391 /* ------------------------------ */ 7392 .balign 64 7393 .L_OP_IGET_QUICK: /* 0xf2 */ 7394 /* File: armv5te/OP_IGET_QUICK.S */ 7395 /* For: iget-quick, iget-object-quick */ 7396 /* op vA, vB, offset@CCCC */ 7397 mov r2, rINST, lsr #12 @ r2<- B 7398 GET_VREG(r3, r2) @ r3<- object we're operating on 7399 FETCH(r1, 1) @ r1<- field byte offset 7400 cmp r3, #0 @ check object for null 7401 mov r2, rINST, lsr #8 @ r2<- A(+) 7402 beq common_errNullObject @ object was null 7403 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7404 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7405 and r2, r2, #15 7406 GET_INST_OPCODE(ip) @ extract opcode from rINST 7407 SET_VREG(r0, r2) @ fp[A]<- r0 7408 GOTO_OPCODE(ip) @ jump to next instruction 7409 7410 /* ------------------------------ */ 7411 .balign 64 7412 .L_OP_IGET_WIDE_QUICK: /* 0xf3 */ 7413 /* File: armv5te/OP_IGET_WIDE_QUICK.S */ 7414 /* iget-wide-quick vA, vB, offset@CCCC */ 7415 mov r2, rINST, lsr #12 @ r2<- B 7416 GET_VREG(r3, r2) @ r3<- object we're operating on 7417 FETCH(ip, 1) @ ip<- field byte offset 7418 cmp r3, #0 @ check object for null 7419 mov r2, rINST, lsr #8 @ r2<- A(+) 7420 beq common_errNullObject @ object was null 7421 ldrd r0, [r3, ip] @ r0<- obj.field (64 bits, aligned) 7422 and r2, r2, #15 7423 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7424 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 7425 GET_INST_OPCODE(ip) @ extract opcode from rINST 7426 stmia r3, {r0-r1} @ fp[A]<- r0/r1 7427 GOTO_OPCODE(ip) @ jump to next instruction 7428 7429 /* ------------------------------ */ 7430 .balign 64 7431 .L_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 7432 /* File: armv5te/OP_IGET_OBJECT_QUICK.S */ 7433 /* File: armv5te/OP_IGET_QUICK.S */ 7434 /* For: iget-quick, iget-object-quick */ 7435 /* op vA, vB, offset@CCCC */ 7436 mov r2, rINST, lsr #12 @ r2<- B 7437 GET_VREG(r3, r2) @ r3<- object we're operating on 7438 FETCH(r1, 1) @ r1<- field byte offset 7439 cmp r3, #0 @ check object for null 7440 mov r2, rINST, lsr #8 @ r2<- A(+) 7441 beq common_errNullObject @ object was null 7442 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7443 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7444 and r2, r2, #15 7445 GET_INST_OPCODE(ip) @ extract opcode from rINST 7446 SET_VREG(r0, r2) @ fp[A]<- r0 7447 GOTO_OPCODE(ip) @ jump to next instruction 7448 7449 7450 /* ------------------------------ */ 7451 .balign 64 7452 .L_OP_IPUT_QUICK: /* 0xf5 */ 7453 /* File: armv5te/OP_IPUT_QUICK.S */ 7454 /* For: iput-quick */ 7455 /* op vA, vB, offset@CCCC */ 7456 mov r2, rINST, lsr #12 @ r2<- B 7457 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7458 FETCH(r1, 1) @ r1<- field byte offset 7459 cmp r3, #0 @ check object for null 7460 mov r2, rINST, lsr #8 @ r2<- A(+) 7461 beq common_errNullObject @ object was null 7462 and r2, r2, #15 7463 GET_VREG(r0, r2) @ r0<- fp[A] 7464 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7465 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7466 GET_INST_OPCODE(ip) @ extract opcode from rINST 7467 GOTO_OPCODE(ip) @ jump to next instruction 7468 7469 /* ------------------------------ */ 7470 .balign 64 7471 .L_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 7472 /* File: armv5te/OP_IPUT_WIDE_QUICK.S */ 7473 /* iput-wide-quick vA, vB, offset@CCCC */ 7474 mov r0, rINST, lsr #8 @ r0<- A(+) 7475 mov r1, rINST, lsr #12 @ r1<- B 7476 and r0, r0, #15 7477 GET_VREG(r2, r1) @ r2<- fp[B], the object pointer 7478 add r3, rFP, r0, lsl #2 @ r3<- &fp[A] 7479 cmp r2, #0 @ check object for null 7480 ldmia r3, {r0-r1} @ r0/r1<- fp[A] 7481 beq common_errNullObject @ object was null 7482 FETCH(r3, 1) @ r3<- field byte offset 7483 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7484 strd r0, [r2, r3] @ obj.field (64 bits, aligned)<- r0/r1 7485 GET_INST_OPCODE(ip) @ extract opcode from rINST 7486 GOTO_OPCODE(ip) @ jump to next instruction 7487 7488 /* ------------------------------ */ 7489 .balign 64 7490 .L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 7491 /* File: armv5te/OP_IPUT_OBJECT_QUICK.S */ 7492 /* For: iput-object-quick */ 7493 /* op vA, vB, offset@CCCC */ 7494 mov r2, rINST, lsr #12 @ r2<- B 7495 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7496 FETCH(r1, 1) @ r1<- field byte offset 7497 cmp r3, #0 @ check object for null 7498 mov r2, rINST, lsr #8 @ r2<- A(+) 7499 beq common_errNullObject @ object was null 7500 and r2, r2, #15 7501 GET_VREG(r0, r2) @ r0<- fp[A] 7502 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 7503 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7504 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7505 cmp r0, #0 7506 strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head 7507 GET_INST_OPCODE(ip) @ extract opcode from rINST 7508 GOTO_OPCODE(ip) @ jump to next instruction 7509 7510 /* ------------------------------ */ 7511 .balign 64 7512 .L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 7513 /* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7514 /* 7515 * Handle an optimized virtual method call. 7516 * 7517 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7518 */ 7519 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7520 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7521 FETCH(r3, 2) @ r3<- FEDC or CCCC 7522 FETCH(r1, 1) @ r1<- BBBB 7523 .if (!0) 7524 and r3, r3, #15 @ r3<- C (or stays CCCC) 7525 .endif 7526 GET_VREG(r9, r3) @ r9<- vC ("this" ptr) 7527 cmp r9, #0 @ is "this" null? 7528 beq common_errNullObject @ null "this", throw exception 7529 ldr r2, [r9, #offObject_clazz] @ r2<- thisPtr->clazz 7530 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7531 EXPORT_PC() @ invoke must export 7532 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7533 bl common_invokeMethodNoRange @ (r0=method, r9="this") 7534 7535 /* ------------------------------ */ 7536 .balign 64 7537 .L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 7538 /* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */ 7539 /* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7540 /* 7541 * Handle an optimized virtual method call. 7542 * 7543 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7544 */ 7545 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7546 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7547 FETCH(r3, 2) @ r3<- FEDC or CCCC 7548 FETCH(r1, 1) @ r1<- BBBB 7549 .if (!1) 7550 and r3, r3, #15 @ r3<- C (or stays CCCC) 7551 .endif 7552 GET_VREG(r9, r3) @ r9<- vC ("this" ptr) 7553 cmp r9, #0 @ is "this" null? 7554 beq common_errNullObject @ null "this", throw exception 7555 ldr r2, [r9, #offObject_clazz] @ r2<- thisPtr->clazz 7556 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7557 EXPORT_PC() @ invoke must export 7558 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7559 bl common_invokeMethodRange @ (r0=method, r9="this") 7560 7561 7562 /* ------------------------------ */ 7563 .balign 64 7564 .L_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 7565 /* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7566 /* 7567 * Handle an optimized "super" method call. 7568 * 7569 * for: [opt] invoke-super-quick, invoke-super-quick/range 7570 */ 7571 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7572 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7573 FETCH(r10, 2) @ r10<- GFED or CCCC 7574 ldr r2, [rSELF, #offThread_method] @ r2<- current method 7575 .if (!0) 7576 and r10, r10, #15 @ r10<- D (or stays CCCC) 7577 .endif 7578 FETCH(r1, 1) @ r1<- BBBB 7579 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7580 EXPORT_PC() @ must export for invoke 7581 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7582 GET_VREG(r9, r10) @ r9<- "this" 7583 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7584 cmp r9, #0 @ null "this" ref? 7585 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7586 beq common_errNullObject @ "this" is null, throw exception 7587 bl common_invokeMethodNoRange @ (r0=method, r9="this") 7588 7589 /* ------------------------------ */ 7590 .balign 64 7591 .L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 7592 /* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */ 7593 /* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7594 /* 7595 * Handle an optimized "super" method call. 7596 * 7597 * for: [opt] invoke-super-quick, invoke-super-quick/range 7598 */ 7599 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7600 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7601 FETCH(r10, 2) @ r10<- GFED or CCCC 7602 ldr r2, [rSELF, #offThread_method] @ r2<- current method 7603 .if (!1) 7604 and r10, r10, #15 @ r10<- D (or stays CCCC) 7605 .endif 7606 FETCH(r1, 1) @ r1<- BBBB 7607 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7608 EXPORT_PC() @ must export for invoke 7609 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7610 GET_VREG(r9, r10) @ r9<- "this" 7611 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7612 cmp r9, #0 @ null "this" ref? 7613 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7614 beq common_errNullObject @ "this" is null, throw exception 7615 bl common_invokeMethodRange @ (r0=method, r9="this") 7616 7617 7618 /* ------------------------------ */ 7619 .balign 64 7620 .L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 7621 /* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */ 7622 /* File: armv5te/OP_IPUT_OBJECT.S */ 7623 /* 7624 * 32-bit instance field put. 7625 * 7626 * for: iput-object, iput-object-volatile 7627 */ 7628 /* op vA, vB, field@CCCC */ 7629 mov r0, rINST, lsr #12 @ r0<- B 7630 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7631 FETCH(r1, 1) @ r1<- field ref CCCC 7632 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7633 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7634 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7635 cmp r0, #0 @ is resolved entry null? 7636 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved 7637 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7638 EXPORT_PC() @ resolve() could throw 7639 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7640 bl dvmResolveInstField @ r0<- resolved InstField ptr 7641 cmp r0, #0 @ success? 7642 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up 7643 b common_exceptionThrown 7644 7645 7646 /* ------------------------------ */ 7647 .balign 64 7648 .L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 7649 /* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */ 7650 /* File: armv5te/OP_SGET.S */ 7651 /* 7652 * General 32-bit SGET handler. 7653 * 7654 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7655 */ 7656 /* op vAA, field@BBBB */ 7657 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7658 FETCH(r1, 1) @ r1<- field ref BBBB 7659 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7660 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7661 cmp r0, #0 @ is resolved entry null? 7662 beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve 7663 .LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0 7664 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7665 SMP_DMB @ acquiring load 7666 mov r2, rINST, lsr #8 @ r2<- AA 7667 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7668 SET_VREG(r1, r2) @ fp[AA]<- r1 7669 GET_INST_OPCODE(ip) @ extract opcode from rINST 7670 GOTO_OPCODE(ip) @ jump to next instruction 7671 7672 7673 /* ------------------------------ */ 7674 .balign 64 7675 .L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 7676 /* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */ 7677 /* File: armv5te/OP_SPUT_OBJECT.S */ 7678 /* 7679 * 32-bit SPUT handler for objects 7680 * 7681 * for: sput-object, sput-object-volatile 7682 */ 7683 /* op vAA, field@BBBB */ 7684 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7685 FETCH(r1, 1) @ r1<- field ref BBBB 7686 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7687 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7688 cmp r0, #0 @ is resolved entry null? 7689 beq .LOP_SPUT_OBJECT_VOLATILE_resolve @ yes, do resolve 7690 .LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0 7691 mov r2, rINST, lsr #8 @ r2<- AA 7692 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7693 GET_VREG(r1, r2) @ r1<- fp[AA] 7694 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 7695 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 7696 GET_INST_OPCODE(ip) @ extract opcode from rINST 7697 SMP_DMB_ST @ releasing store 7698 b .LOP_SPUT_OBJECT_VOLATILE_end 7699 7700 7701 /* ------------------------------ */ 7702 .balign 64 7703 .L_OP_UNUSED_FF: /* 0xff */ 7704 /* File: armv5te/OP_UNUSED_FF.S */ 7705 /* File: armv5te/unused.S */ 7706 bl common_abort 7707 7708 7709 .balign 64 7710 .size dvmAsmInstructionStart, .-dvmAsmInstructionStart 7711 .global dvmAsmInstructionEnd 7712 dvmAsmInstructionEnd: 7713 7714 /* 7715 * =========================================================================== 7716 * Sister implementations 7717 * =========================================================================== 7718 */ 7719 .global dvmAsmSisterStart 7720 .type dvmAsmSisterStart, %function 7721 .text 7722 .balign 4 7723 dvmAsmSisterStart: 7724 7725 /* continuation for OP_CONST_STRING */ 7726 7727 /* 7728 * Continuation if the String has not yet been resolved. 7729 * r1: BBBB (String ref) 7730 * r9: target register 7731 */ 7732 .LOP_CONST_STRING_resolve: 7733 EXPORT_PC() 7734 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7735 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7736 bl dvmResolveString @ r0<- String reference 7737 cmp r0, #0 @ failed? 7738 beq common_exceptionThrown @ yup, handle the exception 7739 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7740 GET_INST_OPCODE(ip) @ extract opcode from rINST 7741 SET_VREG(r0, r9) @ vAA<- r0 7742 GOTO_OPCODE(ip) @ jump to next instruction 7743 7744 /* continuation for OP_CONST_STRING_JUMBO */ 7745 7746 /* 7747 * Continuation if the String has not yet been resolved. 7748 * r1: BBBBBBBB (String ref) 7749 * r9: target register 7750 */ 7751 .LOP_CONST_STRING_JUMBO_resolve: 7752 EXPORT_PC() 7753 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7754 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7755 bl dvmResolveString @ r0<- String reference 7756 cmp r0, #0 @ failed? 7757 beq common_exceptionThrown @ yup, handle the exception 7758 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7759 GET_INST_OPCODE(ip) @ extract opcode from rINST 7760 SET_VREG(r0, r9) @ vAA<- r0 7761 GOTO_OPCODE(ip) @ jump to next instruction 7762 7763 /* continuation for OP_CONST_CLASS */ 7764 7765 /* 7766 * Continuation if the Class has not yet been resolved. 7767 * r1: BBBB (Class ref) 7768 * r9: target register 7769 */ 7770 .LOP_CONST_CLASS_resolve: 7771 EXPORT_PC() 7772 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7773 mov r2, #1 @ r2<- true 7774 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7775 bl dvmResolveClass @ r0<- Class reference 7776 cmp r0, #0 @ failed? 7777 beq common_exceptionThrown @ yup, handle the exception 7778 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7779 GET_INST_OPCODE(ip) @ extract opcode from rINST 7780 SET_VREG(r0, r9) @ vAA<- r0 7781 GOTO_OPCODE(ip) @ jump to next instruction 7782 7783 /* continuation for OP_CHECK_CAST */ 7784 7785 /* 7786 * Trivial test failed, need to perform full check. This is common. 7787 * r0 holds obj->clazz 7788 * r1 holds desired class resolved from BBBB 7789 * r9 holds object 7790 */ 7791 .LOP_CHECK_CAST_fullcheck: 7792 mov r10, r1 @ avoid ClassObject getting clobbered 7793 bl dvmInstanceofNonTrivial @ r0<- boolean result 7794 cmp r0, #0 @ failed? 7795 bne .LOP_CHECK_CAST_okay @ no, success 7796 7797 @ A cast has failed. We need to throw a ClassCastException. 7798 EXPORT_PC() @ about to throw 7799 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 7800 mov r1, r10 @ r1<- desired class 7801 bl dvmThrowClassCastException 7802 b common_exceptionThrown 7803 7804 /* 7805 * Resolution required. This is the least-likely path. 7806 * 7807 * r2 holds BBBB 7808 * r9 holds object 7809 */ 7810 .LOP_CHECK_CAST_resolve: 7811 EXPORT_PC() @ resolve() could throw 7812 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 7813 mov r1, r2 @ r1<- BBBB 7814 mov r2, #0 @ r2<- false 7815 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7816 bl dvmResolveClass @ r0<- resolved ClassObject ptr 7817 cmp r0, #0 @ got null? 7818 beq common_exceptionThrown @ yes, handle exception 7819 mov r1, r0 @ r1<- class resolved from BBB 7820 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 7821 b .LOP_CHECK_CAST_resolved @ pick up where we left off 7822 7823 /* continuation for OP_INSTANCE_OF */ 7824 7825 /* 7826 * Trivial test failed, need to perform full check. This is common. 7827 * r0 holds obj->clazz 7828 * r1 holds class resolved from BBBB 7829 * r9 holds A 7830 */ 7831 .LOP_INSTANCE_OF_fullcheck: 7832 bl dvmInstanceofNonTrivial @ r0<- boolean result 7833 @ fall through to OP_INSTANCE_OF_store 7834 7835 /* 7836 * r0 holds boolean result 7837 * r9 holds A 7838 */ 7839 .LOP_INSTANCE_OF_store: 7840 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7841 SET_VREG(r0, r9) @ vA<- r0 7842 GET_INST_OPCODE(ip) @ extract opcode from rINST 7843 GOTO_OPCODE(ip) @ jump to next instruction 7844 7845 /* 7846 * Trivial test succeeded, save and bail. 7847 * r9 holds A 7848 */ 7849 .LOP_INSTANCE_OF_trivial: 7850 mov r0, #1 @ indicate success 7851 @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper 7852 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7853 SET_VREG(r0, r9) @ vA<- r0 7854 GET_INST_OPCODE(ip) @ extract opcode from rINST 7855 GOTO_OPCODE(ip) @ jump to next instruction 7856 7857 /* 7858 * Resolution required. This is the least-likely path. 7859 * 7860 * r3 holds BBBB 7861 * r9 holds A 7862 */ 7863 .LOP_INSTANCE_OF_resolve: 7864 EXPORT_PC() @ resolve() could throw 7865 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7866 mov r1, r3 @ r1<- BBBB 7867 mov r2, #1 @ r2<- true 7868 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7869 bl dvmResolveClass @ r0<- resolved ClassObject ptr 7870 cmp r0, #0 @ got null? 7871 beq common_exceptionThrown @ yes, handle exception 7872 mov r1, r0 @ r1<- class resolved from BBB 7873 mov r3, rINST, lsr #12 @ r3<- B 7874 GET_VREG(r0, r3) @ r0<- vB (object) 7875 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 7876 b .LOP_INSTANCE_OF_resolved @ pick up where we left off 7877 7878 /* continuation for OP_NEW_INSTANCE */ 7879 7880 .balign 32 @ minimize cache lines 7881 .LOP_NEW_INSTANCE_finish: @ r0=new object 7882 mov r3, rINST, lsr #8 @ r3<- AA 7883 cmp r0, #0 @ failed? 7884 #if defined(WITH_JIT) 7885 /* 7886 * The JIT needs the class to be fully resolved before it can 7887 * include this instruction in a trace. 7888 */ 7889 ldrh r1, [rSELF, #offThread_subMode] 7890 beq common_exceptionThrown @ yes, handle the exception 7891 ands r1, #kSubModeJitTraceBuild @ under construction? 7892 bne .LOP_NEW_INSTANCE_jitCheck 7893 #else 7894 beq common_exceptionThrown @ yes, handle the exception 7895 #endif 7896 .LOP_NEW_INSTANCE_end: 7897 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7898 GET_INST_OPCODE(ip) @ extract opcode from rINST 7899 SET_VREG(r0, r3) @ vAA<- r0 7900 GOTO_OPCODE(ip) @ jump to next instruction 7901 7902 #if defined(WITH_JIT) 7903 /* 7904 * Check to see if we need to stop the trace building early. 7905 * r0: new object 7906 * r3: vAA 7907 */ 7908 .LOP_NEW_INSTANCE_jitCheck: 7909 ldr r1, [r10] @ reload resolved class 7910 cmp r1, #0 @ okay? 7911 bne .LOP_NEW_INSTANCE_end @ yes, finish 7912 mov r9, r0 @ preserve new object 7913 mov r10, r3 @ preserve vAA 7914 mov r0, rSELF 7915 mov r1, rPC 7916 bl dvmJitEndTraceSelect @ (self, pc) 7917 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7918 GET_INST_OPCODE(ip) @ extract opcode from rINST 7919 SET_VREG(r9, r10) @ vAA<- new object 7920 GOTO_OPCODE(ip) @ jump to next instruction 7921 #endif 7922 7923 /* 7924 * Class initialization required. 7925 * 7926 * r0 holds class object 7927 */ 7928 .LOP_NEW_INSTANCE_needinit: 7929 mov r9, r0 @ save r0 7930 bl dvmInitClass @ initialize class 7931 cmp r0, #0 @ check boolean result 7932 mov r0, r9 @ restore r0 7933 bne .LOP_NEW_INSTANCE_initialized @ success, continue 7934 b common_exceptionThrown @ failed, deal with init exception 7935 7936 /* 7937 * Resolution required. This is the least-likely path. 7938 * 7939 * r1 holds BBBB 7940 */ 7941 .LOP_NEW_INSTANCE_resolve: 7942 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 7943 mov r2, #0 @ r2<- false 7944 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7945 bl dvmResolveClass @ r0<- resolved ClassObject ptr 7946 cmp r0, #0 @ got null? 7947 bne .LOP_NEW_INSTANCE_resolved @ no, continue 7948 b common_exceptionThrown @ yes, handle exception 7949 7950 /* continuation for OP_NEW_ARRAY */ 7951 7952 7953 /* 7954 * Resolve class. (This is an uncommon case.) 7955 * 7956 * r1 holds array length 7957 * r2 holds class ref CCCC 7958 */ 7959 .LOP_NEW_ARRAY_resolve: 7960 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 7961 mov r9, r1 @ r9<- length (save) 7962 mov r1, r2 @ r1<- CCCC 7963 mov r2, #0 @ r2<- false 7964 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7965 bl dvmResolveClass @ r0<- call(clazz, ref) 7966 cmp r0, #0 @ got null? 7967 mov r1, r9 @ r1<- length (restore) 7968 beq common_exceptionThrown @ yes, handle exception 7969 @ fall through to OP_NEW_ARRAY_finish 7970 7971 /* 7972 * Finish allocation. 7973 * 7974 * r0 holds class 7975 * r1 holds array length 7976 */ 7977 .LOP_NEW_ARRAY_finish: 7978 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 7979 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 7980 cmp r0, #0 @ failed? 7981 mov r2, rINST, lsr #8 @ r2<- A+ 7982 beq common_exceptionThrown @ yes, handle the exception 7983 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7984 and r2, r2, #15 @ r2<- A 7985 GET_INST_OPCODE(ip) @ extract opcode from rINST 7986 SET_VREG(r0, r2) @ vA<- r0 7987 GOTO_OPCODE(ip) @ jump to next instruction 7988 7989 /* continuation for OP_FILLED_NEW_ARRAY */ 7990 7991 /* 7992 * On entry: 7993 * r0 holds array class 7994 * r10 holds AA or BA 7995 */ 7996 .LOP_FILLED_NEW_ARRAY_continue: 7997 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 7998 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 7999 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 8000 .if 0 8001 mov r1, r10 @ r1<- AA (length) 8002 .else 8003 mov r1, r10, lsr #4 @ r1<- B (length) 8004 .endif 8005 cmp rINST, #'I' @ array of ints? 8006 cmpne rINST, #'L' @ array of objects? 8007 cmpne rINST, #'[' @ array of arrays? 8008 mov r9, r1 @ save length in r9 8009 bne .LOP_FILLED_NEW_ARRAY_notimpl @ no, not handled yet 8010 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 8011 cmp r0, #0 @ null return? 8012 beq common_exceptionThrown @ alloc failed, handle exception 8013 8014 FETCH(r1, 2) @ r1<- FEDC or CCCC 8015 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 8016 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 8017 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 8018 subs r9, r9, #1 @ length--, check for neg 8019 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 8020 bmi 2f @ was zero, bail 8021 8022 @ copy values from registers into the array 8023 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 8024 .if 0 8025 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 8026 1: ldr r3, [r2], #4 @ r3<- *r2++ 8027 subs r9, r9, #1 @ count-- 8028 str r3, [r0], #4 @ *contents++ = vX 8029 bpl 1b 8030 @ continue at 2 8031 .else 8032 cmp r9, #4 @ length was initially 5? 8033 and r2, r10, #15 @ r2<- A 8034 bne 1f @ <= 4 args, branch 8035 GET_VREG(r3, r2) @ r3<- vA 8036 sub r9, r9, #1 @ count-- 8037 str r3, [r0, #16] @ contents[4] = vA 8038 1: and r2, r1, #15 @ r2<- F/E/D/C 8039 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 8040 mov r1, r1, lsr #4 @ r1<- next reg in low 4 8041 subs r9, r9, #1 @ count-- 8042 str r3, [r0], #4 @ *contents++ = vX 8043 bpl 1b 8044 @ continue at 2 8045 .endif 8046 8047 2: 8048 ldr r0, [rSELF, #offThread_retval] @ r0<- object 8049 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 8050 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8051 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 8052 cmp r1, #'I' @ Is int array? 8053 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 8054 GOTO_OPCODE(ip) @ execute it 8055 8056 /* 8057 * Throw an exception indicating that we have not implemented this 8058 * mode of filled-new-array. 8059 */ 8060 .LOP_FILLED_NEW_ARRAY_notimpl: 8061 ldr r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY 8062 bl dvmThrowInternalError 8063 b common_exceptionThrown 8064 8065 /* 8066 * Ideally we'd only define this once, but depending on layout we can 8067 * exceed the range of the load above. 8068 */ 8069 8070 .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY: 8071 .word .LstrFilledNewArrayNotImpl 8072 8073 /* continuation for OP_FILLED_NEW_ARRAY_RANGE */ 8074 8075 /* 8076 * On entry: 8077 * r0 holds array class 8078 * r10 holds AA or BA 8079 */ 8080 .LOP_FILLED_NEW_ARRAY_RANGE_continue: 8081 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 8082 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 8083 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 8084 .if 1 8085 mov r1, r10 @ r1<- AA (length) 8086 .else 8087 mov r1, r10, lsr #4 @ r1<- B (length) 8088 .endif 8089 cmp rINST, #'I' @ array of ints? 8090 cmpne rINST, #'L' @ array of objects? 8091 cmpne rINST, #'[' @ array of arrays? 8092 mov r9, r1 @ save length in r9 8093 bne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl @ no, not handled yet 8094 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 8095 cmp r0, #0 @ null return? 8096 beq common_exceptionThrown @ alloc failed, handle exception 8097 8098 FETCH(r1, 2) @ r1<- FEDC or CCCC 8099 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 8100 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 8101 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 8102 subs r9, r9, #1 @ length--, check for neg 8103 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 8104 bmi 2f @ was zero, bail 8105 8106 @ copy values from registers into the array 8107 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 8108 .if 1 8109 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 8110 1: ldr r3, [r2], #4 @ r3<- *r2++ 8111 subs r9, r9, #1 @ count-- 8112 str r3, [r0], #4 @ *contents++ = vX 8113 bpl 1b 8114 @ continue at 2 8115 .else 8116 cmp r9, #4 @ length was initially 5? 8117 and r2, r10, #15 @ r2<- A 8118 bne 1f @ <= 4 args, branch 8119 GET_VREG(r3, r2) @ r3<- vA 8120 sub r9, r9, #1 @ count-- 8121 str r3, [r0, #16] @ contents[4] = vA 8122 1: and r2, r1, #15 @ r2<- F/E/D/C 8123 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 8124 mov r1, r1, lsr #4 @ r1<- next reg in low 4 8125 subs r9, r9, #1 @ count-- 8126 str r3, [r0], #4 @ *contents++ = vX 8127 bpl 1b 8128 @ continue at 2 8129 .endif 8130 8131 2: 8132 ldr r0, [rSELF, #offThread_retval] @ r0<- object 8133 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 8134 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8135 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 8136 cmp r1, #'I' @ Is int array? 8137 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 8138 GOTO_OPCODE(ip) @ execute it 8139 8140 /* 8141 * Throw an exception indicating that we have not implemented this 8142 * mode of filled-new-array. 8143 */ 8144 .LOP_FILLED_NEW_ARRAY_RANGE_notimpl: 8145 ldr r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE 8146 bl dvmThrowInternalError 8147 b common_exceptionThrown 8148 8149 /* 8150 * Ideally we'd only define this once, but depending on layout we can 8151 * exceed the range of the load above. 8152 */ 8153 8154 .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE: 8155 .word .LstrFilledNewArrayNotImpl 8156 8157 /* continuation for OP_CMPL_FLOAT */ 8158 .LOP_CMPL_FLOAT_finish: 8159 SET_VREG(r0, r9) @ vAA<- r0 8160 GOTO_OPCODE(ip) @ jump to next instruction 8161 8162 /* continuation for OP_CMPG_FLOAT */ 8163 .LOP_CMPG_FLOAT_finish: 8164 SET_VREG(r0, r9) @ vAA<- r0 8165 GOTO_OPCODE(ip) @ jump to next instruction 8166 8167 /* continuation for OP_CMPL_DOUBLE */ 8168 .LOP_CMPL_DOUBLE_finish: 8169 SET_VREG(r0, r9) @ vAA<- r0 8170 GOTO_OPCODE(ip) @ jump to next instruction 8171 8172 /* continuation for OP_CMPG_DOUBLE */ 8173 .LOP_CMPG_DOUBLE_finish: 8174 SET_VREG(r0, r9) @ vAA<- r0 8175 GOTO_OPCODE(ip) @ jump to next instruction 8176 8177 /* continuation for OP_CMP_LONG */ 8178 8179 .LOP_CMP_LONG_less: 8180 mvn r1, #0 @ r1<- -1 8181 @ Want to cond code the next mov so we can avoid branch, but don't see it; 8182 @ instead, we just replicate the tail end. 8183 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8184 SET_VREG(r1, r9) @ vAA<- r1 8185 GET_INST_OPCODE(ip) @ extract opcode from rINST 8186 GOTO_OPCODE(ip) @ jump to next instruction 8187 8188 .LOP_CMP_LONG_greater: 8189 mov r1, #1 @ r1<- 1 8190 @ fall through to _finish 8191 8192 .LOP_CMP_LONG_finish: 8193 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8194 SET_VREG(r1, r9) @ vAA<- r1 8195 GET_INST_OPCODE(ip) @ extract opcode from rINST 8196 GOTO_OPCODE(ip) @ jump to next instruction 8197 8198 /* continuation for OP_AGET_WIDE */ 8199 8200 .LOP_AGET_WIDE_finish: 8201 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8202 ldrd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 8203 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 8204 GET_INST_OPCODE(ip) @ extract opcode from rINST 8205 stmia r9, {r2-r3} @ vAA/vAA+1<- r2/r3 8206 GOTO_OPCODE(ip) @ jump to next instruction 8207 8208 /* continuation for OP_APUT_WIDE */ 8209 8210 .LOP_APUT_WIDE_finish: 8211 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8212 ldmia r9, {r2-r3} @ r2/r3<- vAA/vAA+1 8213 GET_INST_OPCODE(ip) @ extract opcode from rINST 8214 strd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 8215 GOTO_OPCODE(ip) @ jump to next instruction 8216 8217 /* continuation for OP_APUT_OBJECT */ 8218 /* 8219 * On entry: 8220 * rINST = vBB (arrayObj) 8221 * r9 = vAA (obj) 8222 * r10 = offset into array (vBB + vCC * width) 8223 */ 8224 .LOP_APUT_OBJECT_finish: 8225 cmp r9, #0 @ storing null reference? 8226 beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks 8227 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 8228 ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz 8229 bl dvmCanPutArrayElement @ test object type vs. array type 8230 cmp r0, #0 @ okay? 8231 beq .LOP_APUT_OBJECT_throw @ no 8232 mov r1, rINST @ r1<- arrayObj 8233 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8234 ldr r2, [rSELF, #offThread_cardTable] @ get biased CT base 8235 add r10, #offArrayObject_contents @ r0<- pointer to slot 8236 GET_INST_OPCODE(ip) @ extract opcode from rINST 8237 str r9, [r10] @ vBB[vCC]<- vAA 8238 strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head 8239 GOTO_OPCODE(ip) @ jump to next instruction 8240 .LOP_APUT_OBJECT_skip_check: 8241 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8242 GET_INST_OPCODE(ip) @ extract opcode from rINST 8243 str r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA 8244 GOTO_OPCODE(ip) @ jump to next instruction 8245 .LOP_APUT_OBJECT_throw: 8246 @ The types don't match. We need to throw an ArrayStoreException. 8247 ldr r0, [r9, #offObject_clazz] 8248 ldr r1, [rINST, #offObject_clazz] 8249 EXPORT_PC() 8250 bl dvmThrowArrayStoreExceptionIncompatibleElement 8251 b common_exceptionThrown 8252 8253 /* continuation for OP_IGET */ 8254 8255 /* 8256 * Currently: 8257 * r0 holds resolved field 8258 * r9 holds object 8259 */ 8260 .LOP_IGET_finish: 8261 @bl common_squeak0 8262 cmp r9, #0 @ check object for null 8263 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8264 beq common_errNullObject @ object was null 8265 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8266 @ no-op @ acquiring load 8267 mov r2, rINST, lsr #8 @ r2<- A+ 8268 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8269 and r2, r2, #15 @ r2<- A 8270 GET_INST_OPCODE(ip) @ extract opcode from rINST 8271 SET_VREG(r0, r2) @ fp[A]<- r0 8272 GOTO_OPCODE(ip) @ jump to next instruction 8273 8274 /* continuation for OP_IGET_WIDE */ 8275 8276 /* 8277 * Currently: 8278 * r0 holds resolved field 8279 * r9 holds object 8280 */ 8281 .LOP_IGET_WIDE_finish: 8282 cmp r9, #0 @ check object for null 8283 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8284 beq common_errNullObject @ object was null 8285 .if 0 8286 add r0, r9, r3 @ r0<- address of field 8287 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 8288 .else 8289 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 8290 .endif 8291 mov r2, rINST, lsr #8 @ r2<- A+ 8292 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8293 and r2, r2, #15 @ r2<- A 8294 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 8295 GET_INST_OPCODE(ip) @ extract opcode from rINST 8296 stmia r3, {r0-r1} @ fp[A]<- r0/r1 8297 GOTO_OPCODE(ip) @ jump to next instruction 8298 8299 /* continuation for OP_IGET_OBJECT */ 8300 8301 /* 8302 * Currently: 8303 * r0 holds resolved field 8304 * r9 holds object 8305 */ 8306 .LOP_IGET_OBJECT_finish: 8307 @bl common_squeak0 8308 cmp r9, #0 @ check object for null 8309 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8310 beq common_errNullObject @ object was null 8311 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8312 @ no-op @ acquiring load 8313 mov r2, rINST, lsr #8 @ r2<- A+ 8314 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8315 and r2, r2, #15 @ r2<- A 8316 GET_INST_OPCODE(ip) @ extract opcode from rINST 8317 SET_VREG(r0, r2) @ fp[A]<- r0 8318 GOTO_OPCODE(ip) @ jump to next instruction 8319 8320 /* continuation for OP_IGET_BOOLEAN */ 8321 8322 /* 8323 * Currently: 8324 * r0 holds resolved field 8325 * r9 holds object 8326 */ 8327 .LOP_IGET_BOOLEAN_finish: 8328 @bl common_squeak1 8329 cmp r9, #0 @ check object for null 8330 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8331 beq common_errNullObject @ object was null 8332 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8333 @ no-op @ acquiring load 8334 mov r2, rINST, lsr #8 @ r2<- A+ 8335 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8336 and r2, r2, #15 @ r2<- A 8337 GET_INST_OPCODE(ip) @ extract opcode from rINST 8338 SET_VREG(r0, r2) @ fp[A]<- r0 8339 GOTO_OPCODE(ip) @ jump to next instruction 8340 8341 /* continuation for OP_IGET_BYTE */ 8342 8343 /* 8344 * Currently: 8345 * r0 holds resolved field 8346 * r9 holds object 8347 */ 8348 .LOP_IGET_BYTE_finish: 8349 @bl common_squeak2 8350 cmp r9, #0 @ check object for null 8351 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8352 beq common_errNullObject @ object was null 8353 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8354 @ no-op @ acquiring load 8355 mov r2, rINST, lsr #8 @ r2<- A+ 8356 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8357 and r2, r2, #15 @ r2<- A 8358 GET_INST_OPCODE(ip) @ extract opcode from rINST 8359 SET_VREG(r0, r2) @ fp[A]<- r0 8360 GOTO_OPCODE(ip) @ jump to next instruction 8361 8362 /* continuation for OP_IGET_CHAR */ 8363 8364 /* 8365 * Currently: 8366 * r0 holds resolved field 8367 * r9 holds object 8368 */ 8369 .LOP_IGET_CHAR_finish: 8370 @bl common_squeak3 8371 cmp r9, #0 @ check object for null 8372 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8373 beq common_errNullObject @ object was null 8374 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8375 @ no-op @ acquiring load 8376 mov r2, rINST, lsr #8 @ r2<- A+ 8377 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8378 and r2, r2, #15 @ r2<- A 8379 GET_INST_OPCODE(ip) @ extract opcode from rINST 8380 SET_VREG(r0, r2) @ fp[A]<- r0 8381 GOTO_OPCODE(ip) @ jump to next instruction 8382 8383 /* continuation for OP_IGET_SHORT */ 8384 8385 /* 8386 * Currently: 8387 * r0 holds resolved field 8388 * r9 holds object 8389 */ 8390 .LOP_IGET_SHORT_finish: 8391 @bl common_squeak4 8392 cmp r9, #0 @ check object for null 8393 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8394 beq common_errNullObject @ object was null 8395 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8396 @ no-op @ acquiring load 8397 mov r2, rINST, lsr #8 @ r2<- A+ 8398 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8399 and r2, r2, #15 @ r2<- A 8400 GET_INST_OPCODE(ip) @ extract opcode from rINST 8401 SET_VREG(r0, r2) @ fp[A]<- r0 8402 GOTO_OPCODE(ip) @ jump to next instruction 8403 8404 /* continuation for OP_IPUT */ 8405 8406 /* 8407 * Currently: 8408 * r0 holds resolved field 8409 * r9 holds object 8410 */ 8411 .LOP_IPUT_finish: 8412 @bl common_squeak0 8413 mov r1, rINST, lsr #8 @ r1<- A+ 8414 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8415 and r1, r1, #15 @ r1<- A 8416 cmp r9, #0 @ check object for null 8417 GET_VREG(r0, r1) @ r0<- fp[A] 8418 beq common_errNullObject @ object was null 8419 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8420 GET_INST_OPCODE(ip) @ extract opcode from rINST 8421 @ no-op @ releasing store 8422 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8423 @ no-op 8424 GOTO_OPCODE(ip) @ jump to next instruction 8425 8426 /* continuation for OP_IPUT_WIDE */ 8427 8428 /* 8429 * Currently: 8430 * r0 holds resolved field 8431 * r9 holds object 8432 */ 8433 .LOP_IPUT_WIDE_finish: 8434 mov r2, rINST, lsr #8 @ r2<- A+ 8435 cmp r9, #0 @ check object for null 8436 and r2, r2, #15 @ r2<- A 8437 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8438 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 8439 beq common_errNullObject @ object was null 8440 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8441 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 8442 GET_INST_OPCODE(r10) @ extract opcode from rINST 8443 .if 0 8444 add r2, r9, r3 @ r2<- target address 8445 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 8446 .else 8447 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 8448 .endif 8449 GOTO_OPCODE(r10) @ jump to next instruction 8450 8451 /* continuation for OP_IPUT_OBJECT */ 8452 8453 /* 8454 * Currently: 8455 * r0 holds resolved field 8456 * r9 holds object 8457 */ 8458 .LOP_IPUT_OBJECT_finish: 8459 @bl common_squeak0 8460 mov r1, rINST, lsr #8 @ r1<- A+ 8461 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8462 and r1, r1, #15 @ r1<- A 8463 cmp r9, #0 @ check object for null 8464 GET_VREG(r0, r1) @ r0<- fp[A] 8465 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8466 beq common_errNullObject @ object was null 8467 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8468 GET_INST_OPCODE(ip) @ extract opcode from rINST 8469 @ no-op @ releasing store 8470 str r0, [r9, r3] @ obj.field (32 bits)<- r0 8471 @ no-op 8472 cmp r0, #0 @ stored a null reference? 8473 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 8474 GOTO_OPCODE(ip) @ jump to next instruction 8475 8476 /* continuation for OP_IPUT_BOOLEAN */ 8477 8478 /* 8479 * Currently: 8480 * r0 holds resolved field 8481 * r9 holds object 8482 */ 8483 .LOP_IPUT_BOOLEAN_finish: 8484 @bl common_squeak1 8485 mov r1, rINST, lsr #8 @ r1<- A+ 8486 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8487 and r1, r1, #15 @ r1<- A 8488 cmp r9, #0 @ check object for null 8489 GET_VREG(r0, r1) @ r0<- fp[A] 8490 beq common_errNullObject @ object was null 8491 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8492 GET_INST_OPCODE(ip) @ extract opcode from rINST 8493 @ no-op @ releasing store 8494 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8495 @ no-op 8496 GOTO_OPCODE(ip) @ jump to next instruction 8497 8498 /* continuation for OP_IPUT_BYTE */ 8499 8500 /* 8501 * Currently: 8502 * r0 holds resolved field 8503 * r9 holds object 8504 */ 8505 .LOP_IPUT_BYTE_finish: 8506 @bl common_squeak2 8507 mov r1, rINST, lsr #8 @ r1<- A+ 8508 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8509 and r1, r1, #15 @ r1<- A 8510 cmp r9, #0 @ check object for null 8511 GET_VREG(r0, r1) @ r0<- fp[A] 8512 beq common_errNullObject @ object was null 8513 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8514 GET_INST_OPCODE(ip) @ extract opcode from rINST 8515 @ no-op @ releasing store 8516 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8517 @ no-op 8518 GOTO_OPCODE(ip) @ jump to next instruction 8519 8520 /* continuation for OP_IPUT_CHAR */ 8521 8522 /* 8523 * Currently: 8524 * r0 holds resolved field 8525 * r9 holds object 8526 */ 8527 .LOP_IPUT_CHAR_finish: 8528 @bl common_squeak3 8529 mov r1, rINST, lsr #8 @ r1<- A+ 8530 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8531 and r1, r1, #15 @ r1<- A 8532 cmp r9, #0 @ check object for null 8533 GET_VREG(r0, r1) @ r0<- fp[A] 8534 beq common_errNullObject @ object was null 8535 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8536 GET_INST_OPCODE(ip) @ extract opcode from rINST 8537 @ no-op @ releasing store 8538 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8539 @ no-op 8540 GOTO_OPCODE(ip) @ jump to next instruction 8541 8542 /* continuation for OP_IPUT_SHORT */ 8543 8544 /* 8545 * Currently: 8546 * r0 holds resolved field 8547 * r9 holds object 8548 */ 8549 .LOP_IPUT_SHORT_finish: 8550 @bl common_squeak4 8551 mov r1, rINST, lsr #8 @ r1<- A+ 8552 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8553 and r1, r1, #15 @ r1<- A 8554 cmp r9, #0 @ check object for null 8555 GET_VREG(r0, r1) @ r0<- fp[A] 8556 beq common_errNullObject @ object was null 8557 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8558 GET_INST_OPCODE(ip) @ extract opcode from rINST 8559 @ no-op @ releasing store 8560 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8561 @ no-op 8562 GOTO_OPCODE(ip) @ jump to next instruction 8563 8564 /* continuation for OP_SGET */ 8565 8566 /* 8567 * Continuation if the field has not yet been resolved. 8568 * r1: BBBB field ref 8569 * r10: dvmDex->pResFields 8570 */ 8571 .LOP_SGET_resolve: 8572 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8573 #if defined(WITH_JIT) 8574 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8575 #endif 8576 EXPORT_PC() @ resolve() could throw, so export now 8577 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8578 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8579 cmp r0, #0 @ success? 8580 beq common_exceptionThrown @ no, handle exception 8581 #if defined(WITH_JIT) 8582 /* 8583 * If the JIT is actively building a trace we need to make sure 8584 * that the field is fully resolved before including this instruction. 8585 */ 8586 bl common_verifyField 8587 #endif 8588 b .LOP_SGET_finish 8589 8590 /* continuation for OP_SGET_WIDE */ 8591 8592 /* 8593 * Continuation if the field has not yet been resolved. 8594 * r1: BBBB field ref 8595 * r10: dvmDex->pResFields 8596 * 8597 * Returns StaticField pointer in r0. 8598 */ 8599 .LOP_SGET_WIDE_resolve: 8600 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8601 #if defined(WITH_JIT) 8602 add r10, r10, r1, lsl #2 @ r1<- &dvmDex->pResFields[field] 8603 #endif 8604 EXPORT_PC() @ resolve() could throw, so export now 8605 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8606 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8607 cmp r0, #0 @ success? 8608 beq common_exceptionThrown @ no, handle exception 8609 #if defined(WITH_JIT) 8610 /* 8611 * If the JIT is actively building a trace we need to make sure 8612 * that the field is fully resolved before including this instruction. 8613 */ 8614 bl common_verifyField 8615 #endif 8616 b .LOP_SGET_WIDE_finish @ resume 8617 8618 /* continuation for OP_SGET_OBJECT */ 8619 8620 /* 8621 * Continuation if the field has not yet been resolved. 8622 * r1: BBBB field ref 8623 * r10: dvmDex->pResFields 8624 */ 8625 .LOP_SGET_OBJECT_resolve: 8626 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8627 #if defined(WITH_JIT) 8628 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8629 #endif 8630 EXPORT_PC() @ resolve() could throw, so export now 8631 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8632 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8633 cmp r0, #0 @ success? 8634 beq common_exceptionThrown @ no, handle exception 8635 #if defined(WITH_JIT) 8636 /* 8637 * If the JIT is actively building a trace we need to make sure 8638 * that the field is fully resolved before including this instruction. 8639 */ 8640 bl common_verifyField 8641 #endif 8642 b .LOP_SGET_OBJECT_finish 8643 8644 /* continuation for OP_SGET_BOOLEAN */ 8645 8646 /* 8647 * Continuation if the field has not yet been resolved. 8648 * r1: BBBB field ref 8649 * r10: dvmDex->pResFields 8650 */ 8651 .LOP_SGET_BOOLEAN_resolve: 8652 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8653 #if defined(WITH_JIT) 8654 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8655 #endif 8656 EXPORT_PC() @ resolve() could throw, so export now 8657 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8658 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8659 cmp r0, #0 @ success? 8660 beq common_exceptionThrown @ no, handle exception 8661 #if defined(WITH_JIT) 8662 /* 8663 * If the JIT is actively building a trace we need to make sure 8664 * that the field is fully resolved before including this instruction. 8665 */ 8666 bl common_verifyField 8667 #endif 8668 b .LOP_SGET_BOOLEAN_finish 8669 8670 /* continuation for OP_SGET_BYTE */ 8671 8672 /* 8673 * Continuation if the field has not yet been resolved. 8674 * r1: BBBB field ref 8675 * r10: dvmDex->pResFields 8676 */ 8677 .LOP_SGET_BYTE_resolve: 8678 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8679 #if defined(WITH_JIT) 8680 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8681 #endif 8682 EXPORT_PC() @ resolve() could throw, so export now 8683 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8684 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8685 cmp r0, #0 @ success? 8686 beq common_exceptionThrown @ no, handle exception 8687 #if defined(WITH_JIT) 8688 /* 8689 * If the JIT is actively building a trace we need to make sure 8690 * that the field is fully resolved before including this instruction. 8691 */ 8692 bl common_verifyField 8693 #endif 8694 b .LOP_SGET_BYTE_finish 8695 8696 /* continuation for OP_SGET_CHAR */ 8697 8698 /* 8699 * Continuation if the field has not yet been resolved. 8700 * r1: BBBB field ref 8701 * r10: dvmDex->pResFields 8702 */ 8703 .LOP_SGET_CHAR_resolve: 8704 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8705 #if defined(WITH_JIT) 8706 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8707 #endif 8708 EXPORT_PC() @ resolve() could throw, so export now 8709 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8710 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8711 cmp r0, #0 @ success? 8712 beq common_exceptionThrown @ no, handle exception 8713 #if defined(WITH_JIT) 8714 /* 8715 * If the JIT is actively building a trace we need to make sure 8716 * that the field is fully resolved before including this instruction. 8717 */ 8718 bl common_verifyField 8719 #endif 8720 b .LOP_SGET_CHAR_finish 8721 8722 /* continuation for OP_SGET_SHORT */ 8723 8724 /* 8725 * Continuation if the field has not yet been resolved. 8726 * r1: BBBB field ref 8727 * r10: dvmDex->pResFields 8728 */ 8729 .LOP_SGET_SHORT_resolve: 8730 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8731 #if defined(WITH_JIT) 8732 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8733 #endif 8734 EXPORT_PC() @ resolve() could throw, so export now 8735 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8736 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8737 cmp r0, #0 @ success? 8738 beq common_exceptionThrown @ no, handle exception 8739 #if defined(WITH_JIT) 8740 /* 8741 * If the JIT is actively building a trace we need to make sure 8742 * that the field is fully resolved before including this instruction. 8743 */ 8744 bl common_verifyField 8745 #endif 8746 b .LOP_SGET_SHORT_finish 8747 8748 /* continuation for OP_SPUT */ 8749 8750 /* 8751 * Continuation if the field has not yet been resolved. 8752 * r1: BBBB field ref 8753 * r10: dvmDex->pResFields 8754 */ 8755 .LOP_SPUT_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_finish @ resume 8773 8774 /* continuation for OP_SPUT_WIDE */ 8775 8776 /* 8777 * Continuation if the field has not yet been resolved. 8778 * r1: BBBB field ref 8779 * r9: &fp[AA] 8780 * r10: dvmDex->pResFields 8781 * 8782 * Returns StaticField pointer in r2. 8783 */ 8784 .LOP_SPUT_WIDE_resolve: 8785 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8786 #if defined(WITH_JIT) 8787 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8788 #endif 8789 EXPORT_PC() @ resolve() could throw, so export now 8790 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8791 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8792 cmp r0, #0 @ success? 8793 mov r2, r0 @ copy to r2 8794 beq common_exceptionThrown @ no, handle exception 8795 #if defined(WITH_JIT) 8796 /* 8797 * If the JIT is actively building a trace we need to make sure 8798 * that the field is fully resolved before including this instruction. 8799 */ 8800 bl common_verifyField 8801 #endif 8802 b .LOP_SPUT_WIDE_finish @ resume 8803 8804 /* continuation for OP_SPUT_OBJECT */ 8805 8806 8807 .LOP_SPUT_OBJECT_end: 8808 str r1, [r0, #offStaticField_value] @ field<- vAA 8809 @ no-op 8810 cmp r1, #0 @ stored a null object? 8811 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 8812 GOTO_OPCODE(ip) @ jump to next instruction 8813 8814 /* Continuation if the field has not yet been resolved. 8815 * r1: BBBB field ref 8816 * r10: dvmDex->pResFields 8817 */ 8818 .LOP_SPUT_OBJECT_resolve: 8819 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8820 #if defined(WITH_JIT) 8821 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8822 #endif 8823 EXPORT_PC() @ resolve() could throw, so export now 8824 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8825 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8826 cmp r0, #0 @ success? 8827 beq common_exceptionThrown @ no, handle exception 8828 #if defined(WITH_JIT) 8829 /* 8830 * If the JIT is actively building a trace we need to make sure 8831 * that the field is fully resolved before including this instruction. 8832 */ 8833 bl common_verifyField 8834 #endif 8835 b .LOP_SPUT_OBJECT_finish @ resume 8836 8837 8838 /* continuation for OP_SPUT_BOOLEAN */ 8839 8840 /* 8841 * Continuation if the field has not yet been resolved. 8842 * r1: BBBB field ref 8843 * r10: dvmDex->pResFields 8844 */ 8845 .LOP_SPUT_BOOLEAN_resolve: 8846 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8847 #if defined(WITH_JIT) 8848 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8849 #endif 8850 EXPORT_PC() @ resolve() could throw, so export now 8851 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8852 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8853 cmp r0, #0 @ success? 8854 beq common_exceptionThrown @ no, handle exception 8855 #if defined(WITH_JIT) 8856 /* 8857 * If the JIT is actively building a trace we need to make sure 8858 * that the field is fully resolved before including this instruction. 8859 */ 8860 bl common_verifyField 8861 #endif 8862 b .LOP_SPUT_BOOLEAN_finish @ resume 8863 8864 /* continuation for OP_SPUT_BYTE */ 8865 8866 /* 8867 * Continuation if the field has not yet been resolved. 8868 * r1: BBBB field ref 8869 * r10: dvmDex->pResFields 8870 */ 8871 .LOP_SPUT_BYTE_resolve: 8872 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8873 #if defined(WITH_JIT) 8874 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8875 #endif 8876 EXPORT_PC() @ resolve() could throw, so export now 8877 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8878 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8879 cmp r0, #0 @ success? 8880 beq common_exceptionThrown @ no, handle exception 8881 #if defined(WITH_JIT) 8882 /* 8883 * If the JIT is actively building a trace we need to make sure 8884 * that the field is fully resolved before including this instruction. 8885 */ 8886 bl common_verifyField 8887 #endif 8888 b .LOP_SPUT_BYTE_finish @ resume 8889 8890 /* continuation for OP_SPUT_CHAR */ 8891 8892 /* 8893 * Continuation if the field has not yet been resolved. 8894 * r1: BBBB field ref 8895 * r10: dvmDex->pResFields 8896 */ 8897 .LOP_SPUT_CHAR_resolve: 8898 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8899 #if defined(WITH_JIT) 8900 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8901 #endif 8902 EXPORT_PC() @ resolve() could throw, so export now 8903 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8904 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8905 cmp r0, #0 @ success? 8906 beq common_exceptionThrown @ no, handle exception 8907 #if defined(WITH_JIT) 8908 /* 8909 * If the JIT is actively building a trace we need to make sure 8910 * that the field is fully resolved before including this instruction. 8911 */ 8912 bl common_verifyField 8913 #endif 8914 b .LOP_SPUT_CHAR_finish @ resume 8915 8916 /* continuation for OP_SPUT_SHORT */ 8917 8918 /* 8919 * Continuation if the field has not yet been resolved. 8920 * r1: BBBB field ref 8921 * r10: dvmDex->pResFields 8922 */ 8923 .LOP_SPUT_SHORT_resolve: 8924 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8925 #if defined(WITH_JIT) 8926 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8927 #endif 8928 EXPORT_PC() @ resolve() could throw, so export now 8929 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8930 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8931 cmp r0, #0 @ success? 8932 beq common_exceptionThrown @ no, handle exception 8933 #if defined(WITH_JIT) 8934 /* 8935 * If the JIT is actively building a trace we need to make sure 8936 * that the field is fully resolved before including this instruction. 8937 */ 8938 bl common_verifyField 8939 #endif 8940 b .LOP_SPUT_SHORT_finish @ resume 8941 8942 /* continuation for OP_INVOKE_VIRTUAL */ 8943 8944 /* 8945 * At this point: 8946 * r0 = resolved base method 8947 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 8948 */ 8949 .LOP_INVOKE_VIRTUAL_continue: 8950 GET_VREG(r9, r10) @ r9<- "this" ptr 8951 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 8952 cmp r9, #0 @ is "this" null? 8953 beq common_errNullObject @ null "this", throw exception 8954 ldr r3, [r9, #offObject_clazz] @ r3<- thisPtr->clazz 8955 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 8956 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 8957 bl common_invokeMethodNoRange @ (r0=method, r9="this") 8958 8959 /* continuation for OP_INVOKE_SUPER */ 8960 8961 /* 8962 * At this point: 8963 * r0 = resolved base method 8964 * r10 = method->clazz 8965 */ 8966 .LOP_INVOKE_SUPER_continue: 8967 ldr r1, [r10, #offClassObject_super] @ r1<- method->clazz->super 8968 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 8969 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 8970 EXPORT_PC() @ must export for invoke 8971 cmp r2, r3 @ compare (methodIndex, vtableCount) 8972 bcs .LOP_INVOKE_SUPER_nsm @ method not present in superclass 8973 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 8974 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 8975 bl common_invokeMethodNoRange @ continue on 8976 8977 .LOP_INVOKE_SUPER_resolve: 8978 mov r0, r10 @ r0<- method->clazz 8979 mov r2, #METHOD_VIRTUAL @ resolver method type 8980 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8981 cmp r0, #0 @ got null? 8982 bne .LOP_INVOKE_SUPER_continue @ no, continue 8983 b common_exceptionThrown @ yes, handle exception 8984 8985 /* 8986 * Throw a NoSuchMethodError with the method name as the message. 8987 * r0 = resolved base method 8988 */ 8989 .LOP_INVOKE_SUPER_nsm: 8990 ldr r1, [r0, #offMethod_name] @ r1<- method name 8991 b common_errNoSuchMethod 8992 8993 /* continuation for OP_INVOKE_DIRECT */ 8994 8995 /* 8996 * On entry: 8997 * r1 = reference (BBBB or CCCC) 8998 * r10 = "this" register 8999 */ 9000 .LOP_INVOKE_DIRECT_resolve: 9001 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9002 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9003 mov r2, #METHOD_DIRECT @ resolver method type 9004 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9005 cmp r0, #0 @ got null? 9006 bne .LOP_INVOKE_DIRECT_finish @ no, continue 9007 b common_exceptionThrown @ yes, handle exception 9008 9009 /* continuation for OP_INVOKE_STATIC */ 9010 9011 9012 .LOP_INVOKE_STATIC_resolve: 9013 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9014 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9015 mov r2, #METHOD_STATIC @ resolver method type 9016 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9017 cmp r0, #0 @ got null? 9018 #if defined(WITH_JIT) 9019 /* 9020 * Check to see if we're actively building a trace. If so, 9021 * we need to keep this instruction out of it. 9022 * r10: &resolved_methodToCall 9023 */ 9024 ldrh r2, [rSELF, #offThread_subMode] 9025 beq common_exceptionThrown @ null, handle exception 9026 ands r2, #kSubModeJitTraceBuild @ trace under construction? 9027 beq common_invokeMethodNoRange @ no (r0=method, r9="this") 9028 ldr r1, [r10] @ reload resolved method 9029 cmp r1, #0 @ finished resolving? 9030 bne common_invokeMethodNoRange @ yes (r0=method, r9="this") 9031 mov r10, r0 @ preserve method 9032 mov r0, rSELF 9033 mov r1, rPC 9034 bl dvmJitEndTraceSelect @ (self, pc) 9035 mov r0, r10 9036 b common_invokeMethodNoRange @ whew, finally! 9037 #else 9038 bne common_invokeMethodNoRange @ (r0=method, r9="this") 9039 b common_exceptionThrown @ yes, handle exception 9040 #endif 9041 9042 /* continuation for OP_INVOKE_VIRTUAL_RANGE */ 9043 9044 /* 9045 * At this point: 9046 * r0 = resolved base method 9047 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 9048 */ 9049 .LOP_INVOKE_VIRTUAL_RANGE_continue: 9050 GET_VREG(r9, r10) @ r9<- "this" ptr 9051 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 9052 cmp r9, #0 @ is "this" null? 9053 beq common_errNullObject @ null "this", throw exception 9054 ldr r3, [r9, #offObject_clazz] @ r3<- thisPtr->clazz 9055 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 9056 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 9057 bl common_invokeMethodRange @ (r0=method, r9="this") 9058 9059 /* continuation for OP_INVOKE_SUPER_RANGE */ 9060 9061 /* 9062 * At this point: 9063 * r0 = resolved base method 9064 * r10 = method->clazz 9065 */ 9066 .LOP_INVOKE_SUPER_RANGE_continue: 9067 ldr r1, [r10, #offClassObject_super] @ r1<- method->clazz->super 9068 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 9069 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 9070 EXPORT_PC() @ must export for invoke 9071 cmp r2, r3 @ compare (methodIndex, vtableCount) 9072 bcs .LOP_INVOKE_SUPER_RANGE_nsm @ method not present in superclass 9073 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 9074 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 9075 bl common_invokeMethodRange @ continue on 9076 9077 .LOP_INVOKE_SUPER_RANGE_resolve: 9078 mov r0, r10 @ r0<- method->clazz 9079 mov r2, #METHOD_VIRTUAL @ resolver method type 9080 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9081 cmp r0, #0 @ got null? 9082 bne .LOP_INVOKE_SUPER_RANGE_continue @ no, continue 9083 b common_exceptionThrown @ yes, handle exception 9084 9085 /* 9086 * Throw a NoSuchMethodError with the method name as the message. 9087 * r0 = resolved base method 9088 */ 9089 .LOP_INVOKE_SUPER_RANGE_nsm: 9090 ldr r1, [r0, #offMethod_name] @ r1<- method name 9091 b common_errNoSuchMethod 9092 9093 /* continuation for OP_INVOKE_DIRECT_RANGE */ 9094 9095 /* 9096 * On entry: 9097 * r1 = reference (BBBB or CCCC) 9098 * r10 = "this" register 9099 */ 9100 .LOP_INVOKE_DIRECT_RANGE_resolve: 9101 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9102 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9103 mov r2, #METHOD_DIRECT @ resolver method type 9104 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9105 cmp r0, #0 @ got null? 9106 bne .LOP_INVOKE_DIRECT_RANGE_finish @ no, continue 9107 b common_exceptionThrown @ yes, handle exception 9108 9109 /* continuation for OP_INVOKE_STATIC_RANGE */ 9110 9111 9112 .LOP_INVOKE_STATIC_RANGE_resolve: 9113 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9114 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9115 mov r2, #METHOD_STATIC @ resolver method type 9116 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9117 cmp r0, #0 @ got null? 9118 #if defined(WITH_JIT) 9119 /* 9120 * Check to see if we're actively building a trace. If so, 9121 * we need to keep this instruction out of it. 9122 * r10: &resolved_methodToCall 9123 */ 9124 ldrh r2, [rSELF, #offThread_subMode] 9125 beq common_exceptionThrown @ null, handle exception 9126 ands r2, #kSubModeJitTraceBuild @ trace under construction? 9127 beq common_invokeMethodRange @ no (r0=method, r9="this") 9128 ldr r1, [r10] @ reload resolved method 9129 cmp r1, #0 @ finished resolving? 9130 bne common_invokeMethodRange @ yes (r0=method, r9="this") 9131 mov r10, r0 @ preserve method 9132 mov r0, rSELF 9133 mov r1, rPC 9134 bl dvmJitEndTraceSelect @ (self, pc) 9135 mov r0, r10 9136 b common_invokeMethodRange @ whew, finally! 9137 #else 9138 bne common_invokeMethodRange @ (r0=method, r9="this") 9139 b common_exceptionThrown @ yes, handle exception 9140 #endif 9141 9142 /* continuation for OP_FLOAT_TO_LONG */ 9143 /* 9144 * Convert the float in r0 to a long in r0/r1. 9145 * 9146 * We have to clip values to long min/max per the specification. The 9147 * expected common case is a "reasonable" value that converts directly 9148 * to modest integer. The EABI convert function isn't doing this for us. 9149 */ 9150 f2l_doconv: 9151 stmfd sp!, {r4, lr} 9152 mov r1, #0x5f000000 @ (float)maxlong 9153 mov r4, r0 9154 bl __aeabi_fcmpge @ is arg >= maxlong? 9155 cmp r0, #0 @ nonzero == yes 9156 mvnne r0, #0 @ return maxlong (7fffffff) 9157 mvnne r1, #0x80000000 9158 ldmnefd sp!, {r4, pc} 9159 9160 mov r0, r4 @ recover arg 9161 mov r1, #0xdf000000 @ (float)minlong 9162 bl __aeabi_fcmple @ is arg <= minlong? 9163 cmp r0, #0 @ nonzero == yes 9164 movne r0, #0 @ return minlong (80000000) 9165 movne r1, #0x80000000 9166 ldmnefd sp!, {r4, pc} 9167 9168 mov r0, r4 @ recover arg 9169 mov r1, r4 9170 bl __aeabi_fcmpeq @ is arg == self? 9171 cmp r0, #0 @ zero == no 9172 moveq r1, #0 @ return zero for NaN 9173 ldmeqfd sp!, {r4, pc} 9174 9175 mov r0, r4 @ recover arg 9176 bl __aeabi_f2lz @ convert float to long 9177 ldmfd sp!, {r4, pc} 9178 9179 /* continuation for OP_DOUBLE_TO_LONG */ 9180 /* 9181 * Convert the double in r0/r1 to a long in r0/r1. 9182 * 9183 * We have to clip values to long min/max per the specification. The 9184 * expected common case is a "reasonable" value that converts directly 9185 * to modest integer. The EABI convert function isn't doing this for us. 9186 */ 9187 d2l_doconv: 9188 stmfd sp!, {r4, r5, lr} @ save regs 9189 mov r3, #0x43000000 @ maxlong, as a double (high word) 9190 add r3, #0x00e00000 @ 0x43e00000 9191 mov r2, #0 @ maxlong, as a double (low word) 9192 sub sp, sp, #4 @ align for EABI 9193 mov r4, r0 @ save a copy of r0 9194 mov r5, r1 @ and r1 9195 bl __aeabi_dcmpge @ is arg >= maxlong? 9196 cmp r0, #0 @ nonzero == yes 9197 mvnne r0, #0 @ return maxlong (7fffffffffffffff) 9198 mvnne r1, #0x80000000 9199 bne 1f 9200 9201 mov r0, r4 @ recover arg 9202 mov r1, r5 9203 mov r3, #0xc3000000 @ minlong, as a double (high word) 9204 add r3, #0x00e00000 @ 0xc3e00000 9205 mov r2, #0 @ minlong, as a double (low word) 9206 bl __aeabi_dcmple @ is arg <= minlong? 9207 cmp r0, #0 @ nonzero == yes 9208 movne r0, #0 @ return minlong (8000000000000000) 9209 movne r1, #0x80000000 9210 bne 1f 9211 9212 mov r0, r4 @ recover arg 9213 mov r1, r5 9214 mov r2, r4 @ compare against self 9215 mov r3, r5 9216 bl __aeabi_dcmpeq @ is arg == self? 9217 cmp r0, #0 @ zero == no 9218 moveq r1, #0 @ return zero for NaN 9219 beq 1f 9220 9221 mov r0, r4 @ recover arg 9222 mov r1, r5 9223 bl __aeabi_d2lz @ convert double to long 9224 9225 1: 9226 add sp, sp, #4 9227 ldmfd sp!, {r4, r5, pc} 9228 9229 /* continuation for OP_MUL_LONG */ 9230 9231 .LOP_MUL_LONG_finish: 9232 GET_INST_OPCODE(ip) @ extract opcode from rINST 9233 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 9234 GOTO_OPCODE(ip) @ jump to next instruction 9235 9236 /* continuation for OP_SHL_LONG */ 9237 9238 .LOP_SHL_LONG_finish: 9239 mov r0, r0, asl r2 @ r0<- r0 << r2 9240 GET_INST_OPCODE(ip) @ extract opcode from rINST 9241 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9242 GOTO_OPCODE(ip) @ jump to next instruction 9243 9244 /* continuation for OP_SHR_LONG */ 9245 9246 .LOP_SHR_LONG_finish: 9247 mov r1, r1, asr r2 @ r1<- r1 >> r2 9248 GET_INST_OPCODE(ip) @ extract opcode from rINST 9249 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9250 GOTO_OPCODE(ip) @ jump to next instruction 9251 9252 /* continuation for OP_USHR_LONG */ 9253 9254 .LOP_USHR_LONG_finish: 9255 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 9256 GET_INST_OPCODE(ip) @ extract opcode from rINST 9257 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9258 GOTO_OPCODE(ip) @ jump to next instruction 9259 9260 /* continuation for OP_SHL_LONG_2ADDR */ 9261 9262 .LOP_SHL_LONG_2ADDR_finish: 9263 GET_INST_OPCODE(ip) @ extract opcode from rINST 9264 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9265 GOTO_OPCODE(ip) @ jump to next instruction 9266 9267 /* continuation for OP_SHR_LONG_2ADDR */ 9268 9269 .LOP_SHR_LONG_2ADDR_finish: 9270 GET_INST_OPCODE(ip) @ extract opcode from rINST 9271 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9272 GOTO_OPCODE(ip) @ jump to next instruction 9273 9274 /* continuation for OP_USHR_LONG_2ADDR */ 9275 9276 .LOP_USHR_LONG_2ADDR_finish: 9277 GET_INST_OPCODE(ip) @ extract opcode from rINST 9278 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9279 GOTO_OPCODE(ip) @ jump to next instruction 9280 9281 /* continuation for OP_IGET_VOLATILE */ 9282 9283 /* 9284 * Currently: 9285 * r0 holds resolved field 9286 * r9 holds object 9287 */ 9288 .LOP_IGET_VOLATILE_finish: 9289 @bl common_squeak0 9290 cmp r9, #0 @ check object for null 9291 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9292 beq common_errNullObject @ object was null 9293 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 9294 SMP_DMB @ acquiring load 9295 mov r2, rINST, lsr #8 @ r2<- A+ 9296 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9297 and r2, r2, #15 @ r2<- A 9298 GET_INST_OPCODE(ip) @ extract opcode from rINST 9299 SET_VREG(r0, r2) @ fp[A]<- r0 9300 GOTO_OPCODE(ip) @ jump to next instruction 9301 9302 /* continuation for OP_IPUT_VOLATILE */ 9303 9304 /* 9305 * Currently: 9306 * r0 holds resolved field 9307 * r9 holds object 9308 */ 9309 .LOP_IPUT_VOLATILE_finish: 9310 @bl common_squeak0 9311 mov r1, rINST, lsr #8 @ r1<- A+ 9312 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9313 and r1, r1, #15 @ r1<- A 9314 cmp r9, #0 @ check object for null 9315 GET_VREG(r0, r1) @ r0<- fp[A] 9316 beq common_errNullObject @ object was null 9317 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9318 GET_INST_OPCODE(ip) @ extract opcode from rINST 9319 SMP_DMB_ST @ releasing store 9320 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 9321 SMP_DMB 9322 GOTO_OPCODE(ip) @ jump to next instruction 9323 9324 /* continuation for OP_SGET_VOLATILE */ 9325 9326 /* 9327 * Continuation if the field has not yet been resolved. 9328 * r1: BBBB field ref 9329 * r10: dvmDex->pResFields 9330 */ 9331 .LOP_SGET_VOLATILE_resolve: 9332 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9333 #if defined(WITH_JIT) 9334 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9335 #endif 9336 EXPORT_PC() @ resolve() could throw, so export now 9337 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9338 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9339 cmp r0, #0 @ success? 9340 beq common_exceptionThrown @ no, handle exception 9341 #if defined(WITH_JIT) 9342 /* 9343 * If the JIT is actively building a trace we need to make sure 9344 * that the field is fully resolved before including this instruction. 9345 */ 9346 bl common_verifyField 9347 #endif 9348 b .LOP_SGET_VOLATILE_finish 9349 9350 /* continuation for OP_SPUT_VOLATILE */ 9351 9352 /* 9353 * Continuation if the field has not yet been resolved. 9354 * r1: BBBB field ref 9355 * r10: dvmDex->pResFields 9356 */ 9357 .LOP_SPUT_VOLATILE_resolve: 9358 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9359 #if defined(WITH_JIT) 9360 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9361 #endif 9362 EXPORT_PC() @ resolve() could throw, so export now 9363 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9364 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9365 cmp r0, #0 @ success? 9366 beq common_exceptionThrown @ no, handle exception 9367 #if defined(WITH_JIT) 9368 /* 9369 * If the JIT is actively building a trace we need to make sure 9370 * that the field is fully resolved before including this instruction. 9371 */ 9372 bl common_verifyField 9373 #endif 9374 b .LOP_SPUT_VOLATILE_finish @ resume 9375 9376 /* continuation for OP_IGET_OBJECT_VOLATILE */ 9377 9378 /* 9379 * Currently: 9380 * r0 holds resolved field 9381 * r9 holds object 9382 */ 9383 .LOP_IGET_OBJECT_VOLATILE_finish: 9384 @bl common_squeak0 9385 cmp r9, #0 @ check object for null 9386 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9387 beq common_errNullObject @ object was null 9388 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 9389 SMP_DMB @ acquiring load 9390 mov r2, rINST, lsr #8 @ r2<- A+ 9391 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9392 and r2, r2, #15 @ r2<- A 9393 GET_INST_OPCODE(ip) @ extract opcode from rINST 9394 SET_VREG(r0, r2) @ fp[A]<- r0 9395 GOTO_OPCODE(ip) @ jump to next instruction 9396 9397 /* continuation for OP_IGET_WIDE_VOLATILE */ 9398 9399 /* 9400 * Currently: 9401 * r0 holds resolved field 9402 * r9 holds object 9403 */ 9404 .LOP_IGET_WIDE_VOLATILE_finish: 9405 cmp r9, #0 @ check object for null 9406 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9407 beq common_errNullObject @ object was null 9408 .if 1 9409 add r0, r9, r3 @ r0<- address of field 9410 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 9411 .else 9412 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 9413 .endif 9414 mov r2, rINST, lsr #8 @ r2<- A+ 9415 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9416 and r2, r2, #15 @ r2<- A 9417 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 9418 GET_INST_OPCODE(ip) @ extract opcode from rINST 9419 stmia r3, {r0-r1} @ fp[A]<- r0/r1 9420 GOTO_OPCODE(ip) @ jump to next instruction 9421 9422 /* continuation for OP_IPUT_WIDE_VOLATILE */ 9423 9424 /* 9425 * Currently: 9426 * r0 holds resolved field 9427 * r9 holds object 9428 */ 9429 .LOP_IPUT_WIDE_VOLATILE_finish: 9430 mov r2, rINST, lsr #8 @ r2<- A+ 9431 cmp r9, #0 @ check object for null 9432 and r2, r2, #15 @ r2<- A 9433 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9434 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 9435 beq common_errNullObject @ object was null 9436 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9437 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 9438 GET_INST_OPCODE(r10) @ extract opcode from rINST 9439 .if 1 9440 add r2, r9, r3 @ r2<- target address 9441 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 9442 .else 9443 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 9444 .endif 9445 GOTO_OPCODE(r10) @ jump to next instruction 9446 9447 /* continuation for OP_SGET_WIDE_VOLATILE */ 9448 9449 /* 9450 * Continuation if the field has not yet been resolved. 9451 * r1: BBBB field ref 9452 * r10: dvmDex->pResFields 9453 * 9454 * Returns StaticField pointer in r0. 9455 */ 9456 .LOP_SGET_WIDE_VOLATILE_resolve: 9457 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9458 #if defined(WITH_JIT) 9459 add r10, r10, r1, lsl #2 @ r1<- &dvmDex->pResFields[field] 9460 #endif 9461 EXPORT_PC() @ resolve() could throw, so export now 9462 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9463 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9464 cmp r0, #0 @ success? 9465 beq common_exceptionThrown @ no, handle exception 9466 #if defined(WITH_JIT) 9467 /* 9468 * If the JIT is actively building a trace we need to make sure 9469 * that the field is fully resolved before including this instruction. 9470 */ 9471 bl common_verifyField 9472 #endif 9473 b .LOP_SGET_WIDE_VOLATILE_finish @ resume 9474 9475 /* continuation for OP_SPUT_WIDE_VOLATILE */ 9476 9477 /* 9478 * Continuation if the field has not yet been resolved. 9479 * r1: BBBB field ref 9480 * r9: &fp[AA] 9481 * r10: dvmDex->pResFields 9482 * 9483 * Returns StaticField pointer in r2. 9484 */ 9485 .LOP_SPUT_WIDE_VOLATILE_resolve: 9486 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9487 #if defined(WITH_JIT) 9488 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9489 #endif 9490 EXPORT_PC() @ resolve() could throw, so export now 9491 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9492 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9493 cmp r0, #0 @ success? 9494 mov r2, r0 @ copy to r2 9495 beq common_exceptionThrown @ no, handle exception 9496 #if defined(WITH_JIT) 9497 /* 9498 * If the JIT is actively building a trace we need to make sure 9499 * that the field is fully resolved before including this instruction. 9500 */ 9501 bl common_verifyField 9502 #endif 9503 b .LOP_SPUT_WIDE_VOLATILE_finish @ resume 9504 9505 /* continuation for OP_EXECUTE_INLINE */ 9506 9507 /* 9508 * Extract args, call function. 9509 * r0 = #of args (0-4) 9510 * r10 = call index 9511 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 9512 * 9513 * Other ideas: 9514 * - Use a jump table from the main piece to jump directly into the 9515 * AND/LDR pairs. Costs a data load, saves a branch. 9516 * - Have five separate pieces that do the loading, so we can work the 9517 * interleave a little better. Increases code size. 9518 */ 9519 .LOP_EXECUTE_INLINE_continue: 9520 rsb r0, r0, #4 @ r0<- 4-r0 9521 FETCH(rINST, 2) @ rINST<- FEDC 9522 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 9523 bl common_abort @ (skipped due to ARM prefetch) 9524 4: and ip, rINST, #0xf000 @ isolate F 9525 ldr r3, [rFP, ip, lsr #10] @ r3<- vF (shift right 12, left 2) 9526 3: and ip, rINST, #0x0f00 @ isolate E 9527 ldr r2, [rFP, ip, lsr #6] @ r2<- vE 9528 2: and ip, rINST, #0x00f0 @ isolate D 9529 ldr r1, [rFP, ip, lsr #2] @ r1<- vD 9530 1: and ip, rINST, #0x000f @ isolate C 9531 ldr r0, [rFP, ip, lsl #2] @ r0<- vC 9532 0: 9533 ldr rINST, .LOP_EXECUTE_INLINE_table @ table of InlineOperation 9534 ldr pc, [rINST, r10, lsl #4] @ sizeof=16, "func" is first entry 9535 @ (not reached) 9536 9537 /* 9538 * We're debugging or profiling. 9539 * r10: opIndex 9540 */ 9541 .LOP_EXECUTE_INLINE_debugmode: 9542 mov r0, r10 9543 bl dvmResolveInlineNative 9544 cmp r0, #0 @ did it resolve? 9545 beq .LOP_EXECUTE_INLINE_resume @ no, just move on 9546 mov r9, r0 @ remember method 9547 mov r1, rSELF 9548 bl dvmFastMethodTraceEnter @ (method, self) 9549 add r1, rSELF, #offThread_retval@ r1<- &self->retval 9550 sub sp, sp, #8 @ make room for arg, +64 bit align 9551 mov r0, rINST, lsr #12 @ r0<- B 9552 str r1, [sp] @ push &self->retval 9553 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 9554 mov rINST, r0 @ save result of inline 9555 add sp, sp, #8 @ pop stack 9556 mov r0, r9 @ r0<- method 9557 mov r1, rSELF 9558 bl dvmFastNativeMethodTraceExit @ (method, self) 9559 cmp rINST, #0 @ test boolean result of inline 9560 beq common_exceptionThrown @ returned false, handle exception 9561 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 9562 GET_INST_OPCODE(ip) @ extract opcode from rINST 9563 GOTO_OPCODE(ip) @ jump to next instruction 9564 9565 9566 9567 9568 .LOP_EXECUTE_INLINE_table: 9569 .word gDvmInlineOpsTable 9570 9571 /* continuation for OP_EXECUTE_INLINE_RANGE */ 9572 9573 /* 9574 * Extract args, call function. 9575 * r0 = #of args (0-4) 9576 * r10 = call index 9577 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 9578 */ 9579 .LOP_EXECUTE_INLINE_RANGE_continue: 9580 rsb r0, r0, #4 @ r0<- 4-r0 9581 FETCH(r9, 2) @ r9<- CCCC 9582 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 9583 bl common_abort @ (skipped due to ARM prefetch) 9584 4: add ip, r9, #3 @ base+3 9585 GET_VREG(r3, ip) @ r3<- vBase[3] 9586 3: add ip, r9, #2 @ base+2 9587 GET_VREG(r2, ip) @ r2<- vBase[2] 9588 2: add ip, r9, #1 @ base+1 9589 GET_VREG(r1, ip) @ r1<- vBase[1] 9590 1: add ip, r9, #0 @ (nop) 9591 GET_VREG(r0, ip) @ r0<- vBase[0] 9592 0: 9593 ldr r9, .LOP_EXECUTE_INLINE_RANGE_table @ table of InlineOperation 9594 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 9595 @ (not reached) 9596 9597 9598 /* 9599 * We're debugging or profiling. 9600 * r10: opIndex 9601 */ 9602 .LOP_EXECUTE_INLINE_RANGE_debugmode: 9603 mov r0, r10 9604 bl dvmResolveInlineNative 9605 cmp r0, #0 @ did it resolve? 9606 beq .LOP_EXECUTE_INLINE_RANGE_resume @ no, just move on 9607 mov r9, r0 @ remember method 9608 mov r1, rSELF 9609 bl dvmFastMethodTraceEnter @ (method, self) 9610 add r1, rSELF, #offThread_retval@ r1<- &self->retval 9611 sub sp, sp, #8 @ make room for arg, +64 bit align 9612 mov r0, rINST, lsr #8 @ r0<- B 9613 mov rINST, r9 @ rINST<- method 9614 str r1, [sp] @ push &self->retval 9615 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 9616 mov r9, r0 @ save result of inline 9617 add sp, sp, #8 @ pop stack 9618 mov r0, rINST @ r0<- method 9619 mov r1, rSELF 9620 bl dvmFastNativeMethodTraceExit @ (method, self) 9621 cmp r9, #0 @ test boolean result of inline 9622 beq common_exceptionThrown @ returned false, handle exception 9623 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 9624 GET_INST_OPCODE(ip) @ extract opcode from rINST 9625 GOTO_OPCODE(ip) @ jump to next instruction 9626 9627 9628 9629 9630 .LOP_EXECUTE_INLINE_RANGE_table: 9631 .word gDvmInlineOpsTable 9632 9633 9634 /* continuation for OP_INVOKE_OBJECT_INIT_RANGE */ 9635 9636 .LOP_INVOKE_OBJECT_INIT_RANGE_setFinal: 9637 EXPORT_PC() @ can throw 9638 bl dvmSetFinalizable @ call dvmSetFinalizable(obj) 9639 ldr r0, [rSELF, #offThread_exception] @ r0<- self->exception 9640 cmp r0, #0 @ exception pending? 9641 bne common_exceptionThrown @ yes, handle it 9642 b .LOP_INVOKE_OBJECT_INIT_RANGE_finish 9643 9644 /* 9645 * A debugger is attached, so we need to go ahead and do 9646 * this. For simplicity, we'll just jump directly to the 9647 * corresponding handler. Note that we can't use 9648 * rIBASE here because it may be in single-step mode. 9649 * Load the primary table base directly. 9650 */ 9651 .LOP_INVOKE_OBJECT_INIT_RANGE_debugger: 9652 ldr r1, [rSELF, #offThread_mainHandlerTable] 9653 mov ip, #OP_INVOKE_DIRECT_RANGE 9654 GOTO_OPCODE_BASE(r1,ip) @ execute it 9655 9656 /* continuation for OP_IPUT_OBJECT_VOLATILE */ 9657 9658 /* 9659 * Currently: 9660 * r0 holds resolved field 9661 * r9 holds object 9662 */ 9663 .LOP_IPUT_OBJECT_VOLATILE_finish: 9664 @bl common_squeak0 9665 mov r1, rINST, lsr #8 @ r1<- A+ 9666 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9667 and r1, r1, #15 @ r1<- A 9668 cmp r9, #0 @ check object for null 9669 GET_VREG(r0, r1) @ r0<- fp[A] 9670 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 9671 beq common_errNullObject @ object was null 9672 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9673 GET_INST_OPCODE(ip) @ extract opcode from rINST 9674 SMP_DMB_ST @ releasing store 9675 str r0, [r9, r3] @ obj.field (32 bits)<- r0 9676 SMP_DMB 9677 cmp r0, #0 @ stored a null reference? 9678 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 9679 GOTO_OPCODE(ip) @ jump to next instruction 9680 9681 /* continuation for OP_SGET_OBJECT_VOLATILE */ 9682 9683 /* 9684 * Continuation if the field has not yet been resolved. 9685 * r1: BBBB field ref 9686 * r10: dvmDex->pResFields 9687 */ 9688 .LOP_SGET_OBJECT_VOLATILE_resolve: 9689 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9690 #if defined(WITH_JIT) 9691 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9692 #endif 9693 EXPORT_PC() @ resolve() could throw, so export now 9694 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9695 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9696 cmp r0, #0 @ success? 9697 beq common_exceptionThrown @ no, handle exception 9698 #if defined(WITH_JIT) 9699 /* 9700 * If the JIT is actively building a trace we need to make sure 9701 * that the field is fully resolved before including this instruction. 9702 */ 9703 bl common_verifyField 9704 #endif 9705 b .LOP_SGET_OBJECT_VOLATILE_finish 9706 9707 /* continuation for OP_SPUT_OBJECT_VOLATILE */ 9708 9709 9710 .LOP_SPUT_OBJECT_VOLATILE_end: 9711 str r1, [r0, #offStaticField_value] @ field<- vAA 9712 SMP_DMB 9713 cmp r1, #0 @ stored a null object? 9714 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 9715 GOTO_OPCODE(ip) @ jump to next instruction 9716 9717 /* Continuation if the field has not yet been resolved. 9718 * r1: BBBB field ref 9719 * r10: dvmDex->pResFields 9720 */ 9721 .LOP_SPUT_OBJECT_VOLATILE_resolve: 9722 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9723 #if defined(WITH_JIT) 9724 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9725 #endif 9726 EXPORT_PC() @ resolve() could throw, so export now 9727 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9728 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9729 cmp r0, #0 @ success? 9730 beq common_exceptionThrown @ no, handle exception 9731 #if defined(WITH_JIT) 9732 /* 9733 * If the JIT is actively building a trace we need to make sure 9734 * that the field is fully resolved before including this instruction. 9735 */ 9736 bl common_verifyField 9737 #endif 9738 b .LOP_SPUT_OBJECT_VOLATILE_finish @ resume 9739 9740 9741 .size dvmAsmSisterStart, .-dvmAsmSisterStart 9742 .global dvmAsmSisterEnd 9743 dvmAsmSisterEnd: 9744 9745 9746 .global dvmAsmAltInstructionStart 9747 .type dvmAsmAltInstructionStart, %function 9748 .text 9749 9750 dvmAsmAltInstructionStart = .L_ALT_OP_NOP 9751 /* ------------------------------ */ 9752 .balign 64 9753 .L_ALT_OP_NOP: /* 0x00 */ 9754 /* File: armv5te/alt_stub.S */ 9755 /* 9756 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9757 * any interesting requests and then jump to the real instruction 9758 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9759 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9760 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9761 * bail to the real handler if breakFlags==0. 9762 */ 9763 ldrb r3, [rSELF, #offThread_breakFlags] 9764 adrl lr, dvmAsmInstructionStart + (0 * 64) 9765 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9766 cmp r3, #0 9767 bxeq lr @ nothing to do - jump to real handler 9768 EXPORT_PC() 9769 mov r0, rPC @ arg0 9770 mov r1, rFP @ arg1 9771 mov r2, rSELF @ arg2 9772 b dvmCheckBefore @ (dPC,dFP,self) tail call 9773 9774 /* ------------------------------ */ 9775 .balign 64 9776 .L_ALT_OP_MOVE: /* 0x01 */ 9777 /* File: armv5te/alt_stub.S */ 9778 /* 9779 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9780 * any interesting requests and then jump to the real instruction 9781 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9782 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9783 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9784 * bail to the real handler if breakFlags==0. 9785 */ 9786 ldrb r3, [rSELF, #offThread_breakFlags] 9787 adrl lr, dvmAsmInstructionStart + (1 * 64) 9788 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9789 cmp r3, #0 9790 bxeq lr @ nothing to do - jump to real handler 9791 EXPORT_PC() 9792 mov r0, rPC @ arg0 9793 mov r1, rFP @ arg1 9794 mov r2, rSELF @ arg2 9795 b dvmCheckBefore @ (dPC,dFP,self) tail call 9796 9797 /* ------------------------------ */ 9798 .balign 64 9799 .L_ALT_OP_MOVE_FROM16: /* 0x02 */ 9800 /* File: armv5te/alt_stub.S */ 9801 /* 9802 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9803 * any interesting requests and then jump to the real instruction 9804 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9805 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9806 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9807 * bail to the real handler if breakFlags==0. 9808 */ 9809 ldrb r3, [rSELF, #offThread_breakFlags] 9810 adrl lr, dvmAsmInstructionStart + (2 * 64) 9811 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9812 cmp r3, #0 9813 bxeq lr @ nothing to do - jump to real handler 9814 EXPORT_PC() 9815 mov r0, rPC @ arg0 9816 mov r1, rFP @ arg1 9817 mov r2, rSELF @ arg2 9818 b dvmCheckBefore @ (dPC,dFP,self) tail call 9819 9820 /* ------------------------------ */ 9821 .balign 64 9822 .L_ALT_OP_MOVE_16: /* 0x03 */ 9823 /* File: armv5te/alt_stub.S */ 9824 /* 9825 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9826 * any interesting requests and then jump to the real instruction 9827 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9828 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9829 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9830 * bail to the real handler if breakFlags==0. 9831 */ 9832 ldrb r3, [rSELF, #offThread_breakFlags] 9833 adrl lr, dvmAsmInstructionStart + (3 * 64) 9834 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9835 cmp r3, #0 9836 bxeq lr @ nothing to do - jump to real handler 9837 EXPORT_PC() 9838 mov r0, rPC @ arg0 9839 mov r1, rFP @ arg1 9840 mov r2, rSELF @ arg2 9841 b dvmCheckBefore @ (dPC,dFP,self) tail call 9842 9843 /* ------------------------------ */ 9844 .balign 64 9845 .L_ALT_OP_MOVE_WIDE: /* 0x04 */ 9846 /* File: armv5te/alt_stub.S */ 9847 /* 9848 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9849 * any interesting requests and then jump to the real instruction 9850 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9851 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9852 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9853 * bail to the real handler if breakFlags==0. 9854 */ 9855 ldrb r3, [rSELF, #offThread_breakFlags] 9856 adrl lr, dvmAsmInstructionStart + (4 * 64) 9857 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9858 cmp r3, #0 9859 bxeq lr @ nothing to do - jump to real handler 9860 EXPORT_PC() 9861 mov r0, rPC @ arg0 9862 mov r1, rFP @ arg1 9863 mov r2, rSELF @ arg2 9864 b dvmCheckBefore @ (dPC,dFP,self) tail call 9865 9866 /* ------------------------------ */ 9867 .balign 64 9868 .L_ALT_OP_MOVE_WIDE_FROM16: /* 0x05 */ 9869 /* File: armv5te/alt_stub.S */ 9870 /* 9871 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9872 * any interesting requests and then jump to the real instruction 9873 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9874 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9875 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9876 * bail to the real handler if breakFlags==0. 9877 */ 9878 ldrb r3, [rSELF, #offThread_breakFlags] 9879 adrl lr, dvmAsmInstructionStart + (5 * 64) 9880 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9881 cmp r3, #0 9882 bxeq lr @ nothing to do - jump to real handler 9883 EXPORT_PC() 9884 mov r0, rPC @ arg0 9885 mov r1, rFP @ arg1 9886 mov r2, rSELF @ arg2 9887 b dvmCheckBefore @ (dPC,dFP,self) tail call 9888 9889 /* ------------------------------ */ 9890 .balign 64 9891 .L_ALT_OP_MOVE_WIDE_16: /* 0x06 */ 9892 /* File: armv5te/alt_stub.S */ 9893 /* 9894 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9895 * any interesting requests and then jump to the real instruction 9896 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9897 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9898 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9899 * bail to the real handler if breakFlags==0. 9900 */ 9901 ldrb r3, [rSELF, #offThread_breakFlags] 9902 adrl lr, dvmAsmInstructionStart + (6 * 64) 9903 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9904 cmp r3, #0 9905 bxeq lr @ nothing to do - jump to real handler 9906 EXPORT_PC() 9907 mov r0, rPC @ arg0 9908 mov r1, rFP @ arg1 9909 mov r2, rSELF @ arg2 9910 b dvmCheckBefore @ (dPC,dFP,self) tail call 9911 9912 /* ------------------------------ */ 9913 .balign 64 9914 .L_ALT_OP_MOVE_OBJECT: /* 0x07 */ 9915 /* File: armv5te/alt_stub.S */ 9916 /* 9917 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9918 * any interesting requests and then jump to the real instruction 9919 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9920 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9921 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9922 * bail to the real handler if breakFlags==0. 9923 */ 9924 ldrb r3, [rSELF, #offThread_breakFlags] 9925 adrl lr, dvmAsmInstructionStart + (7 * 64) 9926 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9927 cmp r3, #0 9928 bxeq lr @ nothing to do - jump to real handler 9929 EXPORT_PC() 9930 mov r0, rPC @ arg0 9931 mov r1, rFP @ arg1 9932 mov r2, rSELF @ arg2 9933 b dvmCheckBefore @ (dPC,dFP,self) tail call 9934 9935 /* ------------------------------ */ 9936 .balign 64 9937 .L_ALT_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 9938 /* File: armv5te/alt_stub.S */ 9939 /* 9940 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9941 * any interesting requests and then jump to the real instruction 9942 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9943 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9944 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9945 * bail to the real handler if breakFlags==0. 9946 */ 9947 ldrb r3, [rSELF, #offThread_breakFlags] 9948 adrl lr, dvmAsmInstructionStart + (8 * 64) 9949 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9950 cmp r3, #0 9951 bxeq lr @ nothing to do - jump to real handler 9952 EXPORT_PC() 9953 mov r0, rPC @ arg0 9954 mov r1, rFP @ arg1 9955 mov r2, rSELF @ arg2 9956 b dvmCheckBefore @ (dPC,dFP,self) tail call 9957 9958 /* ------------------------------ */ 9959 .balign 64 9960 .L_ALT_OP_MOVE_OBJECT_16: /* 0x09 */ 9961 /* File: armv5te/alt_stub.S */ 9962 /* 9963 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9964 * any interesting requests and then jump to the real instruction 9965 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9966 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9967 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9968 * bail to the real handler if breakFlags==0. 9969 */ 9970 ldrb r3, [rSELF, #offThread_breakFlags] 9971 adrl lr, dvmAsmInstructionStart + (9 * 64) 9972 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9973 cmp r3, #0 9974 bxeq lr @ nothing to do - jump to real handler 9975 EXPORT_PC() 9976 mov r0, rPC @ arg0 9977 mov r1, rFP @ arg1 9978 mov r2, rSELF @ arg2 9979 b dvmCheckBefore @ (dPC,dFP,self) tail call 9980 9981 /* ------------------------------ */ 9982 .balign 64 9983 .L_ALT_OP_MOVE_RESULT: /* 0x0a */ 9984 /* File: armv5te/alt_stub.S */ 9985 /* 9986 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9987 * any interesting requests and then jump to the real instruction 9988 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9989 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9990 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9991 * bail to the real handler if breakFlags==0. 9992 */ 9993 ldrb r3, [rSELF, #offThread_breakFlags] 9994 adrl lr, dvmAsmInstructionStart + (10 * 64) 9995 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9996 cmp r3, #0 9997 bxeq lr @ nothing to do - jump to real handler 9998 EXPORT_PC() 9999 mov r0, rPC @ arg0 10000 mov r1, rFP @ arg1 10001 mov r2, rSELF @ arg2 10002 b dvmCheckBefore @ (dPC,dFP,self) tail call 10003 10004 /* ------------------------------ */ 10005 .balign 64 10006 .L_ALT_OP_MOVE_RESULT_WIDE: /* 0x0b */ 10007 /* File: armv5te/alt_stub.S */ 10008 /* 10009 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10010 * any interesting requests and then jump to the real instruction 10011 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10012 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10013 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10014 * bail to the real handler if breakFlags==0. 10015 */ 10016 ldrb r3, [rSELF, #offThread_breakFlags] 10017 adrl lr, dvmAsmInstructionStart + (11 * 64) 10018 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10019 cmp r3, #0 10020 bxeq lr @ nothing to do - jump to real handler 10021 EXPORT_PC() 10022 mov r0, rPC @ arg0 10023 mov r1, rFP @ arg1 10024 mov r2, rSELF @ arg2 10025 b dvmCheckBefore @ (dPC,dFP,self) tail call 10026 10027 /* ------------------------------ */ 10028 .balign 64 10029 .L_ALT_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 10030 /* File: armv5te/alt_stub.S */ 10031 /* 10032 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10033 * any interesting requests and then jump to the real instruction 10034 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10035 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10036 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10037 * bail to the real handler if breakFlags==0. 10038 */ 10039 ldrb r3, [rSELF, #offThread_breakFlags] 10040 adrl lr, dvmAsmInstructionStart + (12 * 64) 10041 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10042 cmp r3, #0 10043 bxeq lr @ nothing to do - jump to real handler 10044 EXPORT_PC() 10045 mov r0, rPC @ arg0 10046 mov r1, rFP @ arg1 10047 mov r2, rSELF @ arg2 10048 b dvmCheckBefore @ (dPC,dFP,self) tail call 10049 10050 /* ------------------------------ */ 10051 .balign 64 10052 .L_ALT_OP_MOVE_EXCEPTION: /* 0x0d */ 10053 /* File: armv5te/alt_stub.S */ 10054 /* 10055 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10056 * any interesting requests and then jump to the real instruction 10057 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10058 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10059 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10060 * bail to the real handler if breakFlags==0. 10061 */ 10062 ldrb r3, [rSELF, #offThread_breakFlags] 10063 adrl lr, dvmAsmInstructionStart + (13 * 64) 10064 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10065 cmp r3, #0 10066 bxeq lr @ nothing to do - jump to real handler 10067 EXPORT_PC() 10068 mov r0, rPC @ arg0 10069 mov r1, rFP @ arg1 10070 mov r2, rSELF @ arg2 10071 b dvmCheckBefore @ (dPC,dFP,self) tail call 10072 10073 /* ------------------------------ */ 10074 .balign 64 10075 .L_ALT_OP_RETURN_VOID: /* 0x0e */ 10076 /* File: armv5te/alt_stub.S */ 10077 /* 10078 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10079 * any interesting requests and then jump to the real instruction 10080 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10081 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10082 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10083 * bail to the real handler if breakFlags==0. 10084 */ 10085 ldrb r3, [rSELF, #offThread_breakFlags] 10086 adrl lr, dvmAsmInstructionStart + (14 * 64) 10087 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10088 cmp r3, #0 10089 bxeq lr @ nothing to do - jump to real handler 10090 EXPORT_PC() 10091 mov r0, rPC @ arg0 10092 mov r1, rFP @ arg1 10093 mov r2, rSELF @ arg2 10094 b dvmCheckBefore @ (dPC,dFP,self) tail call 10095 10096 /* ------------------------------ */ 10097 .balign 64 10098 .L_ALT_OP_RETURN: /* 0x0f */ 10099 /* File: armv5te/alt_stub.S */ 10100 /* 10101 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10102 * any interesting requests and then jump to the real instruction 10103 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10104 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10105 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10106 * bail to the real handler if breakFlags==0. 10107 */ 10108 ldrb r3, [rSELF, #offThread_breakFlags] 10109 adrl lr, dvmAsmInstructionStart + (15 * 64) 10110 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10111 cmp r3, #0 10112 bxeq lr @ nothing to do - jump to real handler 10113 EXPORT_PC() 10114 mov r0, rPC @ arg0 10115 mov r1, rFP @ arg1 10116 mov r2, rSELF @ arg2 10117 b dvmCheckBefore @ (dPC,dFP,self) tail call 10118 10119 /* ------------------------------ */ 10120 .balign 64 10121 .L_ALT_OP_RETURN_WIDE: /* 0x10 */ 10122 /* File: armv5te/alt_stub.S */ 10123 /* 10124 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10125 * any interesting requests and then jump to the real instruction 10126 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10127 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10128 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10129 * bail to the real handler if breakFlags==0. 10130 */ 10131 ldrb r3, [rSELF, #offThread_breakFlags] 10132 adrl lr, dvmAsmInstructionStart + (16 * 64) 10133 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10134 cmp r3, #0 10135 bxeq lr @ nothing to do - jump to real handler 10136 EXPORT_PC() 10137 mov r0, rPC @ arg0 10138 mov r1, rFP @ arg1 10139 mov r2, rSELF @ arg2 10140 b dvmCheckBefore @ (dPC,dFP,self) tail call 10141 10142 /* ------------------------------ */ 10143 .balign 64 10144 .L_ALT_OP_RETURN_OBJECT: /* 0x11 */ 10145 /* File: armv5te/alt_stub.S */ 10146 /* 10147 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10148 * any interesting requests and then jump to the real instruction 10149 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10150 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10151 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10152 * bail to the real handler if breakFlags==0. 10153 */ 10154 ldrb r3, [rSELF, #offThread_breakFlags] 10155 adrl lr, dvmAsmInstructionStart + (17 * 64) 10156 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10157 cmp r3, #0 10158 bxeq lr @ nothing to do - jump to real handler 10159 EXPORT_PC() 10160 mov r0, rPC @ arg0 10161 mov r1, rFP @ arg1 10162 mov r2, rSELF @ arg2 10163 b dvmCheckBefore @ (dPC,dFP,self) tail call 10164 10165 /* ------------------------------ */ 10166 .balign 64 10167 .L_ALT_OP_CONST_4: /* 0x12 */ 10168 /* File: armv5te/alt_stub.S */ 10169 /* 10170 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10171 * any interesting requests and then jump to the real instruction 10172 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10173 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10174 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10175 * bail to the real handler if breakFlags==0. 10176 */ 10177 ldrb r3, [rSELF, #offThread_breakFlags] 10178 adrl lr, dvmAsmInstructionStart + (18 * 64) 10179 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10180 cmp r3, #0 10181 bxeq lr @ nothing to do - jump to real handler 10182 EXPORT_PC() 10183 mov r0, rPC @ arg0 10184 mov r1, rFP @ arg1 10185 mov r2, rSELF @ arg2 10186 b dvmCheckBefore @ (dPC,dFP,self) tail call 10187 10188 /* ------------------------------ */ 10189 .balign 64 10190 .L_ALT_OP_CONST_16: /* 0x13 */ 10191 /* File: armv5te/alt_stub.S */ 10192 /* 10193 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10194 * any interesting requests and then jump to the real instruction 10195 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10196 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10197 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10198 * bail to the real handler if breakFlags==0. 10199 */ 10200 ldrb r3, [rSELF, #offThread_breakFlags] 10201 adrl lr, dvmAsmInstructionStart + (19 * 64) 10202 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10203 cmp r3, #0 10204 bxeq lr @ nothing to do - jump to real handler 10205 EXPORT_PC() 10206 mov r0, rPC @ arg0 10207 mov r1, rFP @ arg1 10208 mov r2, rSELF @ arg2 10209 b dvmCheckBefore @ (dPC,dFP,self) tail call 10210 10211 /* ------------------------------ */ 10212 .balign 64 10213 .L_ALT_OP_CONST: /* 0x14 */ 10214 /* File: armv5te/alt_stub.S */ 10215 /* 10216 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10217 * any interesting requests and then jump to the real instruction 10218 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10219 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10220 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10221 * bail to the real handler if breakFlags==0. 10222 */ 10223 ldrb r3, [rSELF, #offThread_breakFlags] 10224 adrl lr, dvmAsmInstructionStart + (20 * 64) 10225 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10226 cmp r3, #0 10227 bxeq lr @ nothing to do - jump to real handler 10228 EXPORT_PC() 10229 mov r0, rPC @ arg0 10230 mov r1, rFP @ arg1 10231 mov r2, rSELF @ arg2 10232 b dvmCheckBefore @ (dPC,dFP,self) tail call 10233 10234 /* ------------------------------ */ 10235 .balign 64 10236 .L_ALT_OP_CONST_HIGH16: /* 0x15 */ 10237 /* File: armv5te/alt_stub.S */ 10238 /* 10239 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10240 * any interesting requests and then jump to the real instruction 10241 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10242 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10243 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10244 * bail to the real handler if breakFlags==0. 10245 */ 10246 ldrb r3, [rSELF, #offThread_breakFlags] 10247 adrl lr, dvmAsmInstructionStart + (21 * 64) 10248 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10249 cmp r3, #0 10250 bxeq lr @ nothing to do - jump to real handler 10251 EXPORT_PC() 10252 mov r0, rPC @ arg0 10253 mov r1, rFP @ arg1 10254 mov r2, rSELF @ arg2 10255 b dvmCheckBefore @ (dPC,dFP,self) tail call 10256 10257 /* ------------------------------ */ 10258 .balign 64 10259 .L_ALT_OP_CONST_WIDE_16: /* 0x16 */ 10260 /* File: armv5te/alt_stub.S */ 10261 /* 10262 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10263 * any interesting requests and then jump to the real instruction 10264 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10265 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10266 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10267 * bail to the real handler if breakFlags==0. 10268 */ 10269 ldrb r3, [rSELF, #offThread_breakFlags] 10270 adrl lr, dvmAsmInstructionStart + (22 * 64) 10271 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10272 cmp r3, #0 10273 bxeq lr @ nothing to do - jump to real handler 10274 EXPORT_PC() 10275 mov r0, rPC @ arg0 10276 mov r1, rFP @ arg1 10277 mov r2, rSELF @ arg2 10278 b dvmCheckBefore @ (dPC,dFP,self) tail call 10279 10280 /* ------------------------------ */ 10281 .balign 64 10282 .L_ALT_OP_CONST_WIDE_32: /* 0x17 */ 10283 /* File: armv5te/alt_stub.S */ 10284 /* 10285 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10286 * any interesting requests and then jump to the real instruction 10287 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10288 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10289 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10290 * bail to the real handler if breakFlags==0. 10291 */ 10292 ldrb r3, [rSELF, #offThread_breakFlags] 10293 adrl lr, dvmAsmInstructionStart + (23 * 64) 10294 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10295 cmp r3, #0 10296 bxeq lr @ nothing to do - jump to real handler 10297 EXPORT_PC() 10298 mov r0, rPC @ arg0 10299 mov r1, rFP @ arg1 10300 mov r2, rSELF @ arg2 10301 b dvmCheckBefore @ (dPC,dFP,self) tail call 10302 10303 /* ------------------------------ */ 10304 .balign 64 10305 .L_ALT_OP_CONST_WIDE: /* 0x18 */ 10306 /* File: armv5te/alt_stub.S */ 10307 /* 10308 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10309 * any interesting requests and then jump to the real instruction 10310 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10311 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10312 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10313 * bail to the real handler if breakFlags==0. 10314 */ 10315 ldrb r3, [rSELF, #offThread_breakFlags] 10316 adrl lr, dvmAsmInstructionStart + (24 * 64) 10317 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10318 cmp r3, #0 10319 bxeq lr @ nothing to do - jump to real handler 10320 EXPORT_PC() 10321 mov r0, rPC @ arg0 10322 mov r1, rFP @ arg1 10323 mov r2, rSELF @ arg2 10324 b dvmCheckBefore @ (dPC,dFP,self) tail call 10325 10326 /* ------------------------------ */ 10327 .balign 64 10328 .L_ALT_OP_CONST_WIDE_HIGH16: /* 0x19 */ 10329 /* File: armv5te/alt_stub.S */ 10330 /* 10331 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10332 * any interesting requests and then jump to the real instruction 10333 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10334 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10335 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10336 * bail to the real handler if breakFlags==0. 10337 */ 10338 ldrb r3, [rSELF, #offThread_breakFlags] 10339 adrl lr, dvmAsmInstructionStart + (25 * 64) 10340 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10341 cmp r3, #0 10342 bxeq lr @ nothing to do - jump to real handler 10343 EXPORT_PC() 10344 mov r0, rPC @ arg0 10345 mov r1, rFP @ arg1 10346 mov r2, rSELF @ arg2 10347 b dvmCheckBefore @ (dPC,dFP,self) tail call 10348 10349 /* ------------------------------ */ 10350 .balign 64 10351 .L_ALT_OP_CONST_STRING: /* 0x1a */ 10352 /* File: armv5te/alt_stub.S */ 10353 /* 10354 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10355 * any interesting requests and then jump to the real instruction 10356 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10357 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10358 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10359 * bail to the real handler if breakFlags==0. 10360 */ 10361 ldrb r3, [rSELF, #offThread_breakFlags] 10362 adrl lr, dvmAsmInstructionStart + (26 * 64) 10363 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10364 cmp r3, #0 10365 bxeq lr @ nothing to do - jump to real handler 10366 EXPORT_PC() 10367 mov r0, rPC @ arg0 10368 mov r1, rFP @ arg1 10369 mov r2, rSELF @ arg2 10370 b dvmCheckBefore @ (dPC,dFP,self) tail call 10371 10372 /* ------------------------------ */ 10373 .balign 64 10374 .L_ALT_OP_CONST_STRING_JUMBO: /* 0x1b */ 10375 /* File: armv5te/alt_stub.S */ 10376 /* 10377 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10378 * any interesting requests and then jump to the real instruction 10379 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10380 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10381 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10382 * bail to the real handler if breakFlags==0. 10383 */ 10384 ldrb r3, [rSELF, #offThread_breakFlags] 10385 adrl lr, dvmAsmInstructionStart + (27 * 64) 10386 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10387 cmp r3, #0 10388 bxeq lr @ nothing to do - jump to real handler 10389 EXPORT_PC() 10390 mov r0, rPC @ arg0 10391 mov r1, rFP @ arg1 10392 mov r2, rSELF @ arg2 10393 b dvmCheckBefore @ (dPC,dFP,self) tail call 10394 10395 /* ------------------------------ */ 10396 .balign 64 10397 .L_ALT_OP_CONST_CLASS: /* 0x1c */ 10398 /* File: armv5te/alt_stub.S */ 10399 /* 10400 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10401 * any interesting requests and then jump to the real instruction 10402 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10403 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10404 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10405 * bail to the real handler if breakFlags==0. 10406 */ 10407 ldrb r3, [rSELF, #offThread_breakFlags] 10408 adrl lr, dvmAsmInstructionStart + (28 * 64) 10409 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10410 cmp r3, #0 10411 bxeq lr @ nothing to do - jump to real handler 10412 EXPORT_PC() 10413 mov r0, rPC @ arg0 10414 mov r1, rFP @ arg1 10415 mov r2, rSELF @ arg2 10416 b dvmCheckBefore @ (dPC,dFP,self) tail call 10417 10418 /* ------------------------------ */ 10419 .balign 64 10420 .L_ALT_OP_MONITOR_ENTER: /* 0x1d */ 10421 /* File: armv5te/alt_stub.S */ 10422 /* 10423 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10424 * any interesting requests and then jump to the real instruction 10425 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10426 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10427 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10428 * bail to the real handler if breakFlags==0. 10429 */ 10430 ldrb r3, [rSELF, #offThread_breakFlags] 10431 adrl lr, dvmAsmInstructionStart + (29 * 64) 10432 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10433 cmp r3, #0 10434 bxeq lr @ nothing to do - jump to real handler 10435 EXPORT_PC() 10436 mov r0, rPC @ arg0 10437 mov r1, rFP @ arg1 10438 mov r2, rSELF @ arg2 10439 b dvmCheckBefore @ (dPC,dFP,self) tail call 10440 10441 /* ------------------------------ */ 10442 .balign 64 10443 .L_ALT_OP_MONITOR_EXIT: /* 0x1e */ 10444 /* File: armv5te/alt_stub.S */ 10445 /* 10446 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10447 * any interesting requests and then jump to the real instruction 10448 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10449 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10450 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10451 * bail to the real handler if breakFlags==0. 10452 */ 10453 ldrb r3, [rSELF, #offThread_breakFlags] 10454 adrl lr, dvmAsmInstructionStart + (30 * 64) 10455 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10456 cmp r3, #0 10457 bxeq lr @ nothing to do - jump to real handler 10458 EXPORT_PC() 10459 mov r0, rPC @ arg0 10460 mov r1, rFP @ arg1 10461 mov r2, rSELF @ arg2 10462 b dvmCheckBefore @ (dPC,dFP,self) tail call 10463 10464 /* ------------------------------ */ 10465 .balign 64 10466 .L_ALT_OP_CHECK_CAST: /* 0x1f */ 10467 /* File: armv5te/alt_stub.S */ 10468 /* 10469 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10470 * any interesting requests and then jump to the real instruction 10471 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10472 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10473 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10474 * bail to the real handler if breakFlags==0. 10475 */ 10476 ldrb r3, [rSELF, #offThread_breakFlags] 10477 adrl lr, dvmAsmInstructionStart + (31 * 64) 10478 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10479 cmp r3, #0 10480 bxeq lr @ nothing to do - jump to real handler 10481 EXPORT_PC() 10482 mov r0, rPC @ arg0 10483 mov r1, rFP @ arg1 10484 mov r2, rSELF @ arg2 10485 b dvmCheckBefore @ (dPC,dFP,self) tail call 10486 10487 /* ------------------------------ */ 10488 .balign 64 10489 .L_ALT_OP_INSTANCE_OF: /* 0x20 */ 10490 /* File: armv5te/alt_stub.S */ 10491 /* 10492 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10493 * any interesting requests and then jump to the real instruction 10494 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10495 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10496 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10497 * bail to the real handler if breakFlags==0. 10498 */ 10499 ldrb r3, [rSELF, #offThread_breakFlags] 10500 adrl lr, dvmAsmInstructionStart + (32 * 64) 10501 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10502 cmp r3, #0 10503 bxeq lr @ nothing to do - jump to real handler 10504 EXPORT_PC() 10505 mov r0, rPC @ arg0 10506 mov r1, rFP @ arg1 10507 mov r2, rSELF @ arg2 10508 b dvmCheckBefore @ (dPC,dFP,self) tail call 10509 10510 /* ------------------------------ */ 10511 .balign 64 10512 .L_ALT_OP_ARRAY_LENGTH: /* 0x21 */ 10513 /* File: armv5te/alt_stub.S */ 10514 /* 10515 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10516 * any interesting requests and then jump to the real instruction 10517 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10518 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10519 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10520 * bail to the real handler if breakFlags==0. 10521 */ 10522 ldrb r3, [rSELF, #offThread_breakFlags] 10523 adrl lr, dvmAsmInstructionStart + (33 * 64) 10524 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10525 cmp r3, #0 10526 bxeq lr @ nothing to do - jump to real handler 10527 EXPORT_PC() 10528 mov r0, rPC @ arg0 10529 mov r1, rFP @ arg1 10530 mov r2, rSELF @ arg2 10531 b dvmCheckBefore @ (dPC,dFP,self) tail call 10532 10533 /* ------------------------------ */ 10534 .balign 64 10535 .L_ALT_OP_NEW_INSTANCE: /* 0x22 */ 10536 /* File: armv5te/alt_stub.S */ 10537 /* 10538 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10539 * any interesting requests and then jump to the real instruction 10540 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10541 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10542 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10543 * bail to the real handler if breakFlags==0. 10544 */ 10545 ldrb r3, [rSELF, #offThread_breakFlags] 10546 adrl lr, dvmAsmInstructionStart + (34 * 64) 10547 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10548 cmp r3, #0 10549 bxeq lr @ nothing to do - jump to real handler 10550 EXPORT_PC() 10551 mov r0, rPC @ arg0 10552 mov r1, rFP @ arg1 10553 mov r2, rSELF @ arg2 10554 b dvmCheckBefore @ (dPC,dFP,self) tail call 10555 10556 /* ------------------------------ */ 10557 .balign 64 10558 .L_ALT_OP_NEW_ARRAY: /* 0x23 */ 10559 /* File: armv5te/alt_stub.S */ 10560 /* 10561 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10562 * any interesting requests and then jump to the real instruction 10563 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10564 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10565 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10566 * bail to the real handler if breakFlags==0. 10567 */ 10568 ldrb r3, [rSELF, #offThread_breakFlags] 10569 adrl lr, dvmAsmInstructionStart + (35 * 64) 10570 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10571 cmp r3, #0 10572 bxeq lr @ nothing to do - jump to real handler 10573 EXPORT_PC() 10574 mov r0, rPC @ arg0 10575 mov r1, rFP @ arg1 10576 mov r2, rSELF @ arg2 10577 b dvmCheckBefore @ (dPC,dFP,self) tail call 10578 10579 /* ------------------------------ */ 10580 .balign 64 10581 .L_ALT_OP_FILLED_NEW_ARRAY: /* 0x24 */ 10582 /* File: armv5te/alt_stub.S */ 10583 /* 10584 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10585 * any interesting requests and then jump to the real instruction 10586 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10587 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10588 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10589 * bail to the real handler if breakFlags==0. 10590 */ 10591 ldrb r3, [rSELF, #offThread_breakFlags] 10592 adrl lr, dvmAsmInstructionStart + (36 * 64) 10593 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10594 cmp r3, #0 10595 bxeq lr @ nothing to do - jump to real handler 10596 EXPORT_PC() 10597 mov r0, rPC @ arg0 10598 mov r1, rFP @ arg1 10599 mov r2, rSELF @ arg2 10600 b dvmCheckBefore @ (dPC,dFP,self) tail call 10601 10602 /* ------------------------------ */ 10603 .balign 64 10604 .L_ALT_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 10605 /* File: armv5te/alt_stub.S */ 10606 /* 10607 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10608 * any interesting requests and then jump to the real instruction 10609 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10610 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10611 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10612 * bail to the real handler if breakFlags==0. 10613 */ 10614 ldrb r3, [rSELF, #offThread_breakFlags] 10615 adrl lr, dvmAsmInstructionStart + (37 * 64) 10616 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10617 cmp r3, #0 10618 bxeq lr @ nothing to do - jump to real handler 10619 EXPORT_PC() 10620 mov r0, rPC @ arg0 10621 mov r1, rFP @ arg1 10622 mov r2, rSELF @ arg2 10623 b dvmCheckBefore @ (dPC,dFP,self) tail call 10624 10625 /* ------------------------------ */ 10626 .balign 64 10627 .L_ALT_OP_FILL_ARRAY_DATA: /* 0x26 */ 10628 /* File: armv5te/alt_stub.S */ 10629 /* 10630 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10631 * any interesting requests and then jump to the real instruction 10632 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10633 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10634 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10635 * bail to the real handler if breakFlags==0. 10636 */ 10637 ldrb r3, [rSELF, #offThread_breakFlags] 10638 adrl lr, dvmAsmInstructionStart + (38 * 64) 10639 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10640 cmp r3, #0 10641 bxeq lr @ nothing to do - jump to real handler 10642 EXPORT_PC() 10643 mov r0, rPC @ arg0 10644 mov r1, rFP @ arg1 10645 mov r2, rSELF @ arg2 10646 b dvmCheckBefore @ (dPC,dFP,self) tail call 10647 10648 /* ------------------------------ */ 10649 .balign 64 10650 .L_ALT_OP_THROW: /* 0x27 */ 10651 /* File: armv5te/alt_stub.S */ 10652 /* 10653 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10654 * any interesting requests and then jump to the real instruction 10655 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10656 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10657 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10658 * bail to the real handler if breakFlags==0. 10659 */ 10660 ldrb r3, [rSELF, #offThread_breakFlags] 10661 adrl lr, dvmAsmInstructionStart + (39 * 64) 10662 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10663 cmp r3, #0 10664 bxeq lr @ nothing to do - jump to real handler 10665 EXPORT_PC() 10666 mov r0, rPC @ arg0 10667 mov r1, rFP @ arg1 10668 mov r2, rSELF @ arg2 10669 b dvmCheckBefore @ (dPC,dFP,self) tail call 10670 10671 /* ------------------------------ */ 10672 .balign 64 10673 .L_ALT_OP_GOTO: /* 0x28 */ 10674 /* File: armv5te/alt_stub.S */ 10675 /* 10676 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10677 * any interesting requests and then jump to the real instruction 10678 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10679 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10680 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10681 * bail to the real handler if breakFlags==0. 10682 */ 10683 ldrb r3, [rSELF, #offThread_breakFlags] 10684 adrl lr, dvmAsmInstructionStart + (40 * 64) 10685 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10686 cmp r3, #0 10687 bxeq lr @ nothing to do - jump to real handler 10688 EXPORT_PC() 10689 mov r0, rPC @ arg0 10690 mov r1, rFP @ arg1 10691 mov r2, rSELF @ arg2 10692 b dvmCheckBefore @ (dPC,dFP,self) tail call 10693 10694 /* ------------------------------ */ 10695 .balign 64 10696 .L_ALT_OP_GOTO_16: /* 0x29 */ 10697 /* File: armv5te/alt_stub.S */ 10698 /* 10699 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10700 * any interesting requests and then jump to the real instruction 10701 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10702 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10703 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10704 * bail to the real handler if breakFlags==0. 10705 */ 10706 ldrb r3, [rSELF, #offThread_breakFlags] 10707 adrl lr, dvmAsmInstructionStart + (41 * 64) 10708 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10709 cmp r3, #0 10710 bxeq lr @ nothing to do - jump to real handler 10711 EXPORT_PC() 10712 mov r0, rPC @ arg0 10713 mov r1, rFP @ arg1 10714 mov r2, rSELF @ arg2 10715 b dvmCheckBefore @ (dPC,dFP,self) tail call 10716 10717 /* ------------------------------ */ 10718 .balign 64 10719 .L_ALT_OP_GOTO_32: /* 0x2a */ 10720 /* File: armv5te/alt_stub.S */ 10721 /* 10722 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10723 * any interesting requests and then jump to the real instruction 10724 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10725 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10726 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10727 * bail to the real handler if breakFlags==0. 10728 */ 10729 ldrb r3, [rSELF, #offThread_breakFlags] 10730 adrl lr, dvmAsmInstructionStart + (42 * 64) 10731 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10732 cmp r3, #0 10733 bxeq lr @ nothing to do - jump to real handler 10734 EXPORT_PC() 10735 mov r0, rPC @ arg0 10736 mov r1, rFP @ arg1 10737 mov r2, rSELF @ arg2 10738 b dvmCheckBefore @ (dPC,dFP,self) tail call 10739 10740 /* ------------------------------ */ 10741 .balign 64 10742 .L_ALT_OP_PACKED_SWITCH: /* 0x2b */ 10743 /* File: armv5te/alt_stub.S */ 10744 /* 10745 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10746 * any interesting requests and then jump to the real instruction 10747 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10748 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10749 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10750 * bail to the real handler if breakFlags==0. 10751 */ 10752 ldrb r3, [rSELF, #offThread_breakFlags] 10753 adrl lr, dvmAsmInstructionStart + (43 * 64) 10754 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10755 cmp r3, #0 10756 bxeq lr @ nothing to do - jump to real handler 10757 EXPORT_PC() 10758 mov r0, rPC @ arg0 10759 mov r1, rFP @ arg1 10760 mov r2, rSELF @ arg2 10761 b dvmCheckBefore @ (dPC,dFP,self) tail call 10762 10763 /* ------------------------------ */ 10764 .balign 64 10765 .L_ALT_OP_SPARSE_SWITCH: /* 0x2c */ 10766 /* File: armv5te/alt_stub.S */ 10767 /* 10768 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10769 * any interesting requests and then jump to the real instruction 10770 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10771 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10772 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10773 * bail to the real handler if breakFlags==0. 10774 */ 10775 ldrb r3, [rSELF, #offThread_breakFlags] 10776 adrl lr, dvmAsmInstructionStart + (44 * 64) 10777 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10778 cmp r3, #0 10779 bxeq lr @ nothing to do - jump to real handler 10780 EXPORT_PC() 10781 mov r0, rPC @ arg0 10782 mov r1, rFP @ arg1 10783 mov r2, rSELF @ arg2 10784 b dvmCheckBefore @ (dPC,dFP,self) tail call 10785 10786 /* ------------------------------ */ 10787 .balign 64 10788 .L_ALT_OP_CMPL_FLOAT: /* 0x2d */ 10789 /* File: armv5te/alt_stub.S */ 10790 /* 10791 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10792 * any interesting requests and then jump to the real instruction 10793 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10794 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10795 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10796 * bail to the real handler if breakFlags==0. 10797 */ 10798 ldrb r3, [rSELF, #offThread_breakFlags] 10799 adrl lr, dvmAsmInstructionStart + (45 * 64) 10800 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10801 cmp r3, #0 10802 bxeq lr @ nothing to do - jump to real handler 10803 EXPORT_PC() 10804 mov r0, rPC @ arg0 10805 mov r1, rFP @ arg1 10806 mov r2, rSELF @ arg2 10807 b dvmCheckBefore @ (dPC,dFP,self) tail call 10808 10809 /* ------------------------------ */ 10810 .balign 64 10811 .L_ALT_OP_CMPG_FLOAT: /* 0x2e */ 10812 /* File: armv5te/alt_stub.S */ 10813 /* 10814 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10815 * any interesting requests and then jump to the real instruction 10816 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10817 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10818 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10819 * bail to the real handler if breakFlags==0. 10820 */ 10821 ldrb r3, [rSELF, #offThread_breakFlags] 10822 adrl lr, dvmAsmInstructionStart + (46 * 64) 10823 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10824 cmp r3, #0 10825 bxeq lr @ nothing to do - jump to real handler 10826 EXPORT_PC() 10827 mov r0, rPC @ arg0 10828 mov r1, rFP @ arg1 10829 mov r2, rSELF @ arg2 10830 b dvmCheckBefore @ (dPC,dFP,self) tail call 10831 10832 /* ------------------------------ */ 10833 .balign 64 10834 .L_ALT_OP_CMPL_DOUBLE: /* 0x2f */ 10835 /* File: armv5te/alt_stub.S */ 10836 /* 10837 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10838 * any interesting requests and then jump to the real instruction 10839 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10840 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10841 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10842 * bail to the real handler if breakFlags==0. 10843 */ 10844 ldrb r3, [rSELF, #offThread_breakFlags] 10845 adrl lr, dvmAsmInstructionStart + (47 * 64) 10846 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10847 cmp r3, #0 10848 bxeq lr @ nothing to do - jump to real handler 10849 EXPORT_PC() 10850 mov r0, rPC @ arg0 10851 mov r1, rFP @ arg1 10852 mov r2, rSELF @ arg2 10853 b dvmCheckBefore @ (dPC,dFP,self) tail call 10854 10855 /* ------------------------------ */ 10856 .balign 64 10857 .L_ALT_OP_CMPG_DOUBLE: /* 0x30 */ 10858 /* File: armv5te/alt_stub.S */ 10859 /* 10860 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10861 * any interesting requests and then jump to the real instruction 10862 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10863 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10864 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10865 * bail to the real handler if breakFlags==0. 10866 */ 10867 ldrb r3, [rSELF, #offThread_breakFlags] 10868 adrl lr, dvmAsmInstructionStart + (48 * 64) 10869 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10870 cmp r3, #0 10871 bxeq lr @ nothing to do - jump to real handler 10872 EXPORT_PC() 10873 mov r0, rPC @ arg0 10874 mov r1, rFP @ arg1 10875 mov r2, rSELF @ arg2 10876 b dvmCheckBefore @ (dPC,dFP,self) tail call 10877 10878 /* ------------------------------ */ 10879 .balign 64 10880 .L_ALT_OP_CMP_LONG: /* 0x31 */ 10881 /* File: armv5te/alt_stub.S */ 10882 /* 10883 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10884 * any interesting requests and then jump to the real instruction 10885 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10886 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10887 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10888 * bail to the real handler if breakFlags==0. 10889 */ 10890 ldrb r3, [rSELF, #offThread_breakFlags] 10891 adrl lr, dvmAsmInstructionStart + (49 * 64) 10892 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10893 cmp r3, #0 10894 bxeq lr @ nothing to do - jump to real handler 10895 EXPORT_PC() 10896 mov r0, rPC @ arg0 10897 mov r1, rFP @ arg1 10898 mov r2, rSELF @ arg2 10899 b dvmCheckBefore @ (dPC,dFP,self) tail call 10900 10901 /* ------------------------------ */ 10902 .balign 64 10903 .L_ALT_OP_IF_EQ: /* 0x32 */ 10904 /* File: armv5te/alt_stub.S */ 10905 /* 10906 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10907 * any interesting requests and then jump to the real instruction 10908 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10909 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10910 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10911 * bail to the real handler if breakFlags==0. 10912 */ 10913 ldrb r3, [rSELF, #offThread_breakFlags] 10914 adrl lr, dvmAsmInstructionStart + (50 * 64) 10915 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10916 cmp r3, #0 10917 bxeq lr @ nothing to do - jump to real handler 10918 EXPORT_PC() 10919 mov r0, rPC @ arg0 10920 mov r1, rFP @ arg1 10921 mov r2, rSELF @ arg2 10922 b dvmCheckBefore @ (dPC,dFP,self) tail call 10923 10924 /* ------------------------------ */ 10925 .balign 64 10926 .L_ALT_OP_IF_NE: /* 0x33 */ 10927 /* File: armv5te/alt_stub.S */ 10928 /* 10929 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10930 * any interesting requests and then jump to the real instruction 10931 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10932 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10933 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10934 * bail to the real handler if breakFlags==0. 10935 */ 10936 ldrb r3, [rSELF, #offThread_breakFlags] 10937 adrl lr, dvmAsmInstructionStart + (51 * 64) 10938 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10939 cmp r3, #0 10940 bxeq lr @ nothing to do - jump to real handler 10941 EXPORT_PC() 10942 mov r0, rPC @ arg0 10943 mov r1, rFP @ arg1 10944 mov r2, rSELF @ arg2 10945 b dvmCheckBefore @ (dPC,dFP,self) tail call 10946 10947 /* ------------------------------ */ 10948 .balign 64 10949 .L_ALT_OP_IF_LT: /* 0x34 */ 10950 /* File: armv5te/alt_stub.S */ 10951 /* 10952 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10953 * any interesting requests and then jump to the real instruction 10954 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10955 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10956 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10957 * bail to the real handler if breakFlags==0. 10958 */ 10959 ldrb r3, [rSELF, #offThread_breakFlags] 10960 adrl lr, dvmAsmInstructionStart + (52 * 64) 10961 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10962 cmp r3, #0 10963 bxeq lr @ nothing to do - jump to real handler 10964 EXPORT_PC() 10965 mov r0, rPC @ arg0 10966 mov r1, rFP @ arg1 10967 mov r2, rSELF @ arg2 10968 b dvmCheckBefore @ (dPC,dFP,self) tail call 10969 10970 /* ------------------------------ */ 10971 .balign 64 10972 .L_ALT_OP_IF_GE: /* 0x35 */ 10973 /* File: armv5te/alt_stub.S */ 10974 /* 10975 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10976 * any interesting requests and then jump to the real instruction 10977 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10978 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10979 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10980 * bail to the real handler if breakFlags==0. 10981 */ 10982 ldrb r3, [rSELF, #offThread_breakFlags] 10983 adrl lr, dvmAsmInstructionStart + (53 * 64) 10984 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10985 cmp r3, #0 10986 bxeq lr @ nothing to do - jump to real handler 10987 EXPORT_PC() 10988 mov r0, rPC @ arg0 10989 mov r1, rFP @ arg1 10990 mov r2, rSELF @ arg2 10991 b dvmCheckBefore @ (dPC,dFP,self) tail call 10992 10993 /* ------------------------------ */ 10994 .balign 64 10995 .L_ALT_OP_IF_GT: /* 0x36 */ 10996 /* File: armv5te/alt_stub.S */ 10997 /* 10998 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10999 * any interesting requests and then jump to the real instruction 11000 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11001 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11002 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11003 * bail to the real handler if breakFlags==0. 11004 */ 11005 ldrb r3, [rSELF, #offThread_breakFlags] 11006 adrl lr, dvmAsmInstructionStart + (54 * 64) 11007 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11008 cmp r3, #0 11009 bxeq lr @ nothing to do - jump to real handler 11010 EXPORT_PC() 11011 mov r0, rPC @ arg0 11012 mov r1, rFP @ arg1 11013 mov r2, rSELF @ arg2 11014 b dvmCheckBefore @ (dPC,dFP,self) tail call 11015 11016 /* ------------------------------ */ 11017 .balign 64 11018 .L_ALT_OP_IF_LE: /* 0x37 */ 11019 /* File: armv5te/alt_stub.S */ 11020 /* 11021 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11022 * any interesting requests and then jump to the real instruction 11023 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11024 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11025 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11026 * bail to the real handler if breakFlags==0. 11027 */ 11028 ldrb r3, [rSELF, #offThread_breakFlags] 11029 adrl lr, dvmAsmInstructionStart + (55 * 64) 11030 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11031 cmp r3, #0 11032 bxeq lr @ nothing to do - jump to real handler 11033 EXPORT_PC() 11034 mov r0, rPC @ arg0 11035 mov r1, rFP @ arg1 11036 mov r2, rSELF @ arg2 11037 b dvmCheckBefore @ (dPC,dFP,self) tail call 11038 11039 /* ------------------------------ */ 11040 .balign 64 11041 .L_ALT_OP_IF_EQZ: /* 0x38 */ 11042 /* File: armv5te/alt_stub.S */ 11043 /* 11044 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11045 * any interesting requests and then jump to the real instruction 11046 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11047 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11048 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11049 * bail to the real handler if breakFlags==0. 11050 */ 11051 ldrb r3, [rSELF, #offThread_breakFlags] 11052 adrl lr, dvmAsmInstructionStart + (56 * 64) 11053 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11054 cmp r3, #0 11055 bxeq lr @ nothing to do - jump to real handler 11056 EXPORT_PC() 11057 mov r0, rPC @ arg0 11058 mov r1, rFP @ arg1 11059 mov r2, rSELF @ arg2 11060 b dvmCheckBefore @ (dPC,dFP,self) tail call 11061 11062 /* ------------------------------ */ 11063 .balign 64 11064 .L_ALT_OP_IF_NEZ: /* 0x39 */ 11065 /* File: armv5te/alt_stub.S */ 11066 /* 11067 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11068 * any interesting requests and then jump to the real instruction 11069 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11070 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11071 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11072 * bail to the real handler if breakFlags==0. 11073 */ 11074 ldrb r3, [rSELF, #offThread_breakFlags] 11075 adrl lr, dvmAsmInstructionStart + (57 * 64) 11076 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11077 cmp r3, #0 11078 bxeq lr @ nothing to do - jump to real handler 11079 EXPORT_PC() 11080 mov r0, rPC @ arg0 11081 mov r1, rFP @ arg1 11082 mov r2, rSELF @ arg2 11083 b dvmCheckBefore @ (dPC,dFP,self) tail call 11084 11085 /* ------------------------------ */ 11086 .balign 64 11087 .L_ALT_OP_IF_LTZ: /* 0x3a */ 11088 /* File: armv5te/alt_stub.S */ 11089 /* 11090 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11091 * any interesting requests and then jump to the real instruction 11092 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11093 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11094 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11095 * bail to the real handler if breakFlags==0. 11096 */ 11097 ldrb r3, [rSELF, #offThread_breakFlags] 11098 adrl lr, dvmAsmInstructionStart + (58 * 64) 11099 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11100 cmp r3, #0 11101 bxeq lr @ nothing to do - jump to real handler 11102 EXPORT_PC() 11103 mov r0, rPC @ arg0 11104 mov r1, rFP @ arg1 11105 mov r2, rSELF @ arg2 11106 b dvmCheckBefore @ (dPC,dFP,self) tail call 11107 11108 /* ------------------------------ */ 11109 .balign 64 11110 .L_ALT_OP_IF_GEZ: /* 0x3b */ 11111 /* File: armv5te/alt_stub.S */ 11112 /* 11113 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11114 * any interesting requests and then jump to the real instruction 11115 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11116 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11117 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11118 * bail to the real handler if breakFlags==0. 11119 */ 11120 ldrb r3, [rSELF, #offThread_breakFlags] 11121 adrl lr, dvmAsmInstructionStart + (59 * 64) 11122 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11123 cmp r3, #0 11124 bxeq lr @ nothing to do - jump to real handler 11125 EXPORT_PC() 11126 mov r0, rPC @ arg0 11127 mov r1, rFP @ arg1 11128 mov r2, rSELF @ arg2 11129 b dvmCheckBefore @ (dPC,dFP,self) tail call 11130 11131 /* ------------------------------ */ 11132 .balign 64 11133 .L_ALT_OP_IF_GTZ: /* 0x3c */ 11134 /* File: armv5te/alt_stub.S */ 11135 /* 11136 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11137 * any interesting requests and then jump to the real instruction 11138 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11139 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11140 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11141 * bail to the real handler if breakFlags==0. 11142 */ 11143 ldrb r3, [rSELF, #offThread_breakFlags] 11144 adrl lr, dvmAsmInstructionStart + (60 * 64) 11145 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11146 cmp r3, #0 11147 bxeq lr @ nothing to do - jump to real handler 11148 EXPORT_PC() 11149 mov r0, rPC @ arg0 11150 mov r1, rFP @ arg1 11151 mov r2, rSELF @ arg2 11152 b dvmCheckBefore @ (dPC,dFP,self) tail call 11153 11154 /* ------------------------------ */ 11155 .balign 64 11156 .L_ALT_OP_IF_LEZ: /* 0x3d */ 11157 /* File: armv5te/alt_stub.S */ 11158 /* 11159 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11160 * any interesting requests and then jump to the real instruction 11161 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11162 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11163 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11164 * bail to the real handler if breakFlags==0. 11165 */ 11166 ldrb r3, [rSELF, #offThread_breakFlags] 11167 adrl lr, dvmAsmInstructionStart + (61 * 64) 11168 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11169 cmp r3, #0 11170 bxeq lr @ nothing to do - jump to real handler 11171 EXPORT_PC() 11172 mov r0, rPC @ arg0 11173 mov r1, rFP @ arg1 11174 mov r2, rSELF @ arg2 11175 b dvmCheckBefore @ (dPC,dFP,self) tail call 11176 11177 /* ------------------------------ */ 11178 .balign 64 11179 .L_ALT_OP_UNUSED_3E: /* 0x3e */ 11180 /* File: armv5te/alt_stub.S */ 11181 /* 11182 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11183 * any interesting requests and then jump to the real instruction 11184 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11185 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11186 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11187 * bail to the real handler if breakFlags==0. 11188 */ 11189 ldrb r3, [rSELF, #offThread_breakFlags] 11190 adrl lr, dvmAsmInstructionStart + (62 * 64) 11191 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11192 cmp r3, #0 11193 bxeq lr @ nothing to do - jump to real handler 11194 EXPORT_PC() 11195 mov r0, rPC @ arg0 11196 mov r1, rFP @ arg1 11197 mov r2, rSELF @ arg2 11198 b dvmCheckBefore @ (dPC,dFP,self) tail call 11199 11200 /* ------------------------------ */ 11201 .balign 64 11202 .L_ALT_OP_UNUSED_3F: /* 0x3f */ 11203 /* File: armv5te/alt_stub.S */ 11204 /* 11205 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11206 * any interesting requests and then jump to the real instruction 11207 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11208 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11209 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11210 * bail to the real handler if breakFlags==0. 11211 */ 11212 ldrb r3, [rSELF, #offThread_breakFlags] 11213 adrl lr, dvmAsmInstructionStart + (63 * 64) 11214 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11215 cmp r3, #0 11216 bxeq lr @ nothing to do - jump to real handler 11217 EXPORT_PC() 11218 mov r0, rPC @ arg0 11219 mov r1, rFP @ arg1 11220 mov r2, rSELF @ arg2 11221 b dvmCheckBefore @ (dPC,dFP,self) tail call 11222 11223 /* ------------------------------ */ 11224 .balign 64 11225 .L_ALT_OP_UNUSED_40: /* 0x40 */ 11226 /* File: armv5te/alt_stub.S */ 11227 /* 11228 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11229 * any interesting requests and then jump to the real instruction 11230 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11231 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11232 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11233 * bail to the real handler if breakFlags==0. 11234 */ 11235 ldrb r3, [rSELF, #offThread_breakFlags] 11236 adrl lr, dvmAsmInstructionStart + (64 * 64) 11237 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11238 cmp r3, #0 11239 bxeq lr @ nothing to do - jump to real handler 11240 EXPORT_PC() 11241 mov r0, rPC @ arg0 11242 mov r1, rFP @ arg1 11243 mov r2, rSELF @ arg2 11244 b dvmCheckBefore @ (dPC,dFP,self) tail call 11245 11246 /* ------------------------------ */ 11247 .balign 64 11248 .L_ALT_OP_UNUSED_41: /* 0x41 */ 11249 /* File: armv5te/alt_stub.S */ 11250 /* 11251 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11252 * any interesting requests and then jump to the real instruction 11253 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11254 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11255 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11256 * bail to the real handler if breakFlags==0. 11257 */ 11258 ldrb r3, [rSELF, #offThread_breakFlags] 11259 adrl lr, dvmAsmInstructionStart + (65 * 64) 11260 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11261 cmp r3, #0 11262 bxeq lr @ nothing to do - jump to real handler 11263 EXPORT_PC() 11264 mov r0, rPC @ arg0 11265 mov r1, rFP @ arg1 11266 mov r2, rSELF @ arg2 11267 b dvmCheckBefore @ (dPC,dFP,self) tail call 11268 11269 /* ------------------------------ */ 11270 .balign 64 11271 .L_ALT_OP_UNUSED_42: /* 0x42 */ 11272 /* File: armv5te/alt_stub.S */ 11273 /* 11274 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11275 * any interesting requests and then jump to the real instruction 11276 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11277 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11278 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11279 * bail to the real handler if breakFlags==0. 11280 */ 11281 ldrb r3, [rSELF, #offThread_breakFlags] 11282 adrl lr, dvmAsmInstructionStart + (66 * 64) 11283 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11284 cmp r3, #0 11285 bxeq lr @ nothing to do - jump to real handler 11286 EXPORT_PC() 11287 mov r0, rPC @ arg0 11288 mov r1, rFP @ arg1 11289 mov r2, rSELF @ arg2 11290 b dvmCheckBefore @ (dPC,dFP,self) tail call 11291 11292 /* ------------------------------ */ 11293 .balign 64 11294 .L_ALT_OP_UNUSED_43: /* 0x43 */ 11295 /* File: armv5te/alt_stub.S */ 11296 /* 11297 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11298 * any interesting requests and then jump to the real instruction 11299 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11300 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11301 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11302 * bail to the real handler if breakFlags==0. 11303 */ 11304 ldrb r3, [rSELF, #offThread_breakFlags] 11305 adrl lr, dvmAsmInstructionStart + (67 * 64) 11306 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11307 cmp r3, #0 11308 bxeq lr @ nothing to do - jump to real handler 11309 EXPORT_PC() 11310 mov r0, rPC @ arg0 11311 mov r1, rFP @ arg1 11312 mov r2, rSELF @ arg2 11313 b dvmCheckBefore @ (dPC,dFP,self) tail call 11314 11315 /* ------------------------------ */ 11316 .balign 64 11317 .L_ALT_OP_AGET: /* 0x44 */ 11318 /* File: armv5te/alt_stub.S */ 11319 /* 11320 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11321 * any interesting requests and then jump to the real instruction 11322 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11323 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11324 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11325 * bail to the real handler if breakFlags==0. 11326 */ 11327 ldrb r3, [rSELF, #offThread_breakFlags] 11328 adrl lr, dvmAsmInstructionStart + (68 * 64) 11329 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11330 cmp r3, #0 11331 bxeq lr @ nothing to do - jump to real handler 11332 EXPORT_PC() 11333 mov r0, rPC @ arg0 11334 mov r1, rFP @ arg1 11335 mov r2, rSELF @ arg2 11336 b dvmCheckBefore @ (dPC,dFP,self) tail call 11337 11338 /* ------------------------------ */ 11339 .balign 64 11340 .L_ALT_OP_AGET_WIDE: /* 0x45 */ 11341 /* File: armv5te/alt_stub.S */ 11342 /* 11343 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11344 * any interesting requests and then jump to the real instruction 11345 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11346 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11347 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11348 * bail to the real handler if breakFlags==0. 11349 */ 11350 ldrb r3, [rSELF, #offThread_breakFlags] 11351 adrl lr, dvmAsmInstructionStart + (69 * 64) 11352 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11353 cmp r3, #0 11354 bxeq lr @ nothing to do - jump to real handler 11355 EXPORT_PC() 11356 mov r0, rPC @ arg0 11357 mov r1, rFP @ arg1 11358 mov r2, rSELF @ arg2 11359 b dvmCheckBefore @ (dPC,dFP,self) tail call 11360 11361 /* ------------------------------ */ 11362 .balign 64 11363 .L_ALT_OP_AGET_OBJECT: /* 0x46 */ 11364 /* File: armv5te/alt_stub.S */ 11365 /* 11366 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11367 * any interesting requests and then jump to the real instruction 11368 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11369 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11370 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11371 * bail to the real handler if breakFlags==0. 11372 */ 11373 ldrb r3, [rSELF, #offThread_breakFlags] 11374 adrl lr, dvmAsmInstructionStart + (70 * 64) 11375 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11376 cmp r3, #0 11377 bxeq lr @ nothing to do - jump to real handler 11378 EXPORT_PC() 11379 mov r0, rPC @ arg0 11380 mov r1, rFP @ arg1 11381 mov r2, rSELF @ arg2 11382 b dvmCheckBefore @ (dPC,dFP,self) tail call 11383 11384 /* ------------------------------ */ 11385 .balign 64 11386 .L_ALT_OP_AGET_BOOLEAN: /* 0x47 */ 11387 /* File: armv5te/alt_stub.S */ 11388 /* 11389 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11390 * any interesting requests and then jump to the real instruction 11391 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11392 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11393 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11394 * bail to the real handler if breakFlags==0. 11395 */ 11396 ldrb r3, [rSELF, #offThread_breakFlags] 11397 adrl lr, dvmAsmInstructionStart + (71 * 64) 11398 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11399 cmp r3, #0 11400 bxeq lr @ nothing to do - jump to real handler 11401 EXPORT_PC() 11402 mov r0, rPC @ arg0 11403 mov r1, rFP @ arg1 11404 mov r2, rSELF @ arg2 11405 b dvmCheckBefore @ (dPC,dFP,self) tail call 11406 11407 /* ------------------------------ */ 11408 .balign 64 11409 .L_ALT_OP_AGET_BYTE: /* 0x48 */ 11410 /* File: armv5te/alt_stub.S */ 11411 /* 11412 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11413 * any interesting requests and then jump to the real instruction 11414 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11415 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11416 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11417 * bail to the real handler if breakFlags==0. 11418 */ 11419 ldrb r3, [rSELF, #offThread_breakFlags] 11420 adrl lr, dvmAsmInstructionStart + (72 * 64) 11421 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11422 cmp r3, #0 11423 bxeq lr @ nothing to do - jump to real handler 11424 EXPORT_PC() 11425 mov r0, rPC @ arg0 11426 mov r1, rFP @ arg1 11427 mov r2, rSELF @ arg2 11428 b dvmCheckBefore @ (dPC,dFP,self) tail call 11429 11430 /* ------------------------------ */ 11431 .balign 64 11432 .L_ALT_OP_AGET_CHAR: /* 0x49 */ 11433 /* File: armv5te/alt_stub.S */ 11434 /* 11435 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11436 * any interesting requests and then jump to the real instruction 11437 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11438 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11439 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11440 * bail to the real handler if breakFlags==0. 11441 */ 11442 ldrb r3, [rSELF, #offThread_breakFlags] 11443 adrl lr, dvmAsmInstructionStart + (73 * 64) 11444 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11445 cmp r3, #0 11446 bxeq lr @ nothing to do - jump to real handler 11447 EXPORT_PC() 11448 mov r0, rPC @ arg0 11449 mov r1, rFP @ arg1 11450 mov r2, rSELF @ arg2 11451 b dvmCheckBefore @ (dPC,dFP,self) tail call 11452 11453 /* ------------------------------ */ 11454 .balign 64 11455 .L_ALT_OP_AGET_SHORT: /* 0x4a */ 11456 /* File: armv5te/alt_stub.S */ 11457 /* 11458 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11459 * any interesting requests and then jump to the real instruction 11460 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11461 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11462 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11463 * bail to the real handler if breakFlags==0. 11464 */ 11465 ldrb r3, [rSELF, #offThread_breakFlags] 11466 adrl lr, dvmAsmInstructionStart + (74 * 64) 11467 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11468 cmp r3, #0 11469 bxeq lr @ nothing to do - jump to real handler 11470 EXPORT_PC() 11471 mov r0, rPC @ arg0 11472 mov r1, rFP @ arg1 11473 mov r2, rSELF @ arg2 11474 b dvmCheckBefore @ (dPC,dFP,self) tail call 11475 11476 /* ------------------------------ */ 11477 .balign 64 11478 .L_ALT_OP_APUT: /* 0x4b */ 11479 /* File: armv5te/alt_stub.S */ 11480 /* 11481 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11482 * any interesting requests and then jump to the real instruction 11483 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11484 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11485 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11486 * bail to the real handler if breakFlags==0. 11487 */ 11488 ldrb r3, [rSELF, #offThread_breakFlags] 11489 adrl lr, dvmAsmInstructionStart + (75 * 64) 11490 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11491 cmp r3, #0 11492 bxeq lr @ nothing to do - jump to real handler 11493 EXPORT_PC() 11494 mov r0, rPC @ arg0 11495 mov r1, rFP @ arg1 11496 mov r2, rSELF @ arg2 11497 b dvmCheckBefore @ (dPC,dFP,self) tail call 11498 11499 /* ------------------------------ */ 11500 .balign 64 11501 .L_ALT_OP_APUT_WIDE: /* 0x4c */ 11502 /* File: armv5te/alt_stub.S */ 11503 /* 11504 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11505 * any interesting requests and then jump to the real instruction 11506 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11507 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11508 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11509 * bail to the real handler if breakFlags==0. 11510 */ 11511 ldrb r3, [rSELF, #offThread_breakFlags] 11512 adrl lr, dvmAsmInstructionStart + (76 * 64) 11513 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11514 cmp r3, #0 11515 bxeq lr @ nothing to do - jump to real handler 11516 EXPORT_PC() 11517 mov r0, rPC @ arg0 11518 mov r1, rFP @ arg1 11519 mov r2, rSELF @ arg2 11520 b dvmCheckBefore @ (dPC,dFP,self) tail call 11521 11522 /* ------------------------------ */ 11523 .balign 64 11524 .L_ALT_OP_APUT_OBJECT: /* 0x4d */ 11525 /* File: armv5te/alt_stub.S */ 11526 /* 11527 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11528 * any interesting requests and then jump to the real instruction 11529 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11530 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11531 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11532 * bail to the real handler if breakFlags==0. 11533 */ 11534 ldrb r3, [rSELF, #offThread_breakFlags] 11535 adrl lr, dvmAsmInstructionStart + (77 * 64) 11536 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11537 cmp r3, #0 11538 bxeq lr @ nothing to do - jump to real handler 11539 EXPORT_PC() 11540 mov r0, rPC @ arg0 11541 mov r1, rFP @ arg1 11542 mov r2, rSELF @ arg2 11543 b dvmCheckBefore @ (dPC,dFP,self) tail call 11544 11545 /* ------------------------------ */ 11546 .balign 64 11547 .L_ALT_OP_APUT_BOOLEAN: /* 0x4e */ 11548 /* File: armv5te/alt_stub.S */ 11549 /* 11550 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11551 * any interesting requests and then jump to the real instruction 11552 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11553 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11554 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11555 * bail to the real handler if breakFlags==0. 11556 */ 11557 ldrb r3, [rSELF, #offThread_breakFlags] 11558 adrl lr, dvmAsmInstructionStart + (78 * 64) 11559 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11560 cmp r3, #0 11561 bxeq lr @ nothing to do - jump to real handler 11562 EXPORT_PC() 11563 mov r0, rPC @ arg0 11564 mov r1, rFP @ arg1 11565 mov r2, rSELF @ arg2 11566 b dvmCheckBefore @ (dPC,dFP,self) tail call 11567 11568 /* ------------------------------ */ 11569 .balign 64 11570 .L_ALT_OP_APUT_BYTE: /* 0x4f */ 11571 /* File: armv5te/alt_stub.S */ 11572 /* 11573 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11574 * any interesting requests and then jump to the real instruction 11575 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11576 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11577 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11578 * bail to the real handler if breakFlags==0. 11579 */ 11580 ldrb r3, [rSELF, #offThread_breakFlags] 11581 adrl lr, dvmAsmInstructionStart + (79 * 64) 11582 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11583 cmp r3, #0 11584 bxeq lr @ nothing to do - jump to real handler 11585 EXPORT_PC() 11586 mov r0, rPC @ arg0 11587 mov r1, rFP @ arg1 11588 mov r2, rSELF @ arg2 11589 b dvmCheckBefore @ (dPC,dFP,self) tail call 11590 11591 /* ------------------------------ */ 11592 .balign 64 11593 .L_ALT_OP_APUT_CHAR: /* 0x50 */ 11594 /* File: armv5te/alt_stub.S */ 11595 /* 11596 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11597 * any interesting requests and then jump to the real instruction 11598 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11599 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11600 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11601 * bail to the real handler if breakFlags==0. 11602 */ 11603 ldrb r3, [rSELF, #offThread_breakFlags] 11604 adrl lr, dvmAsmInstructionStart + (80 * 64) 11605 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11606 cmp r3, #0 11607 bxeq lr @ nothing to do - jump to real handler 11608 EXPORT_PC() 11609 mov r0, rPC @ arg0 11610 mov r1, rFP @ arg1 11611 mov r2, rSELF @ arg2 11612 b dvmCheckBefore @ (dPC,dFP,self) tail call 11613 11614 /* ------------------------------ */ 11615 .balign 64 11616 .L_ALT_OP_APUT_SHORT: /* 0x51 */ 11617 /* File: armv5te/alt_stub.S */ 11618 /* 11619 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11620 * any interesting requests and then jump to the real instruction 11621 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11622 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11623 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11624 * bail to the real handler if breakFlags==0. 11625 */ 11626 ldrb r3, [rSELF, #offThread_breakFlags] 11627 adrl lr, dvmAsmInstructionStart + (81 * 64) 11628 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11629 cmp r3, #0 11630 bxeq lr @ nothing to do - jump to real handler 11631 EXPORT_PC() 11632 mov r0, rPC @ arg0 11633 mov r1, rFP @ arg1 11634 mov r2, rSELF @ arg2 11635 b dvmCheckBefore @ (dPC,dFP,self) tail call 11636 11637 /* ------------------------------ */ 11638 .balign 64 11639 .L_ALT_OP_IGET: /* 0x52 */ 11640 /* File: armv5te/alt_stub.S */ 11641 /* 11642 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11643 * any interesting requests and then jump to the real instruction 11644 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11645 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11646 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11647 * bail to the real handler if breakFlags==0. 11648 */ 11649 ldrb r3, [rSELF, #offThread_breakFlags] 11650 adrl lr, dvmAsmInstructionStart + (82 * 64) 11651 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11652 cmp r3, #0 11653 bxeq lr @ nothing to do - jump to real handler 11654 EXPORT_PC() 11655 mov r0, rPC @ arg0 11656 mov r1, rFP @ arg1 11657 mov r2, rSELF @ arg2 11658 b dvmCheckBefore @ (dPC,dFP,self) tail call 11659 11660 /* ------------------------------ */ 11661 .balign 64 11662 .L_ALT_OP_IGET_WIDE: /* 0x53 */ 11663 /* File: armv5te/alt_stub.S */ 11664 /* 11665 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11666 * any interesting requests and then jump to the real instruction 11667 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11668 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11669 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11670 * bail to the real handler if breakFlags==0. 11671 */ 11672 ldrb r3, [rSELF, #offThread_breakFlags] 11673 adrl lr, dvmAsmInstructionStart + (83 * 64) 11674 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11675 cmp r3, #0 11676 bxeq lr @ nothing to do - jump to real handler 11677 EXPORT_PC() 11678 mov r0, rPC @ arg0 11679 mov r1, rFP @ arg1 11680 mov r2, rSELF @ arg2 11681 b dvmCheckBefore @ (dPC,dFP,self) tail call 11682 11683 /* ------------------------------ */ 11684 .balign 64 11685 .L_ALT_OP_IGET_OBJECT: /* 0x54 */ 11686 /* File: armv5te/alt_stub.S */ 11687 /* 11688 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11689 * any interesting requests and then jump to the real instruction 11690 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11691 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11692 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11693 * bail to the real handler if breakFlags==0. 11694 */ 11695 ldrb r3, [rSELF, #offThread_breakFlags] 11696 adrl lr, dvmAsmInstructionStart + (84 * 64) 11697 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11698 cmp r3, #0 11699 bxeq lr @ nothing to do - jump to real handler 11700 EXPORT_PC() 11701 mov r0, rPC @ arg0 11702 mov r1, rFP @ arg1 11703 mov r2, rSELF @ arg2 11704 b dvmCheckBefore @ (dPC,dFP,self) tail call 11705 11706 /* ------------------------------ */ 11707 .balign 64 11708 .L_ALT_OP_IGET_BOOLEAN: /* 0x55 */ 11709 /* File: armv5te/alt_stub.S */ 11710 /* 11711 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11712 * any interesting requests and then jump to the real instruction 11713 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11714 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11715 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11716 * bail to the real handler if breakFlags==0. 11717 */ 11718 ldrb r3, [rSELF, #offThread_breakFlags] 11719 adrl lr, dvmAsmInstructionStart + (85 * 64) 11720 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11721 cmp r3, #0 11722 bxeq lr @ nothing to do - jump to real handler 11723 EXPORT_PC() 11724 mov r0, rPC @ arg0 11725 mov r1, rFP @ arg1 11726 mov r2, rSELF @ arg2 11727 b dvmCheckBefore @ (dPC,dFP,self) tail call 11728 11729 /* ------------------------------ */ 11730 .balign 64 11731 .L_ALT_OP_IGET_BYTE: /* 0x56 */ 11732 /* File: armv5te/alt_stub.S */ 11733 /* 11734 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11735 * any interesting requests and then jump to the real instruction 11736 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11737 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11738 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11739 * bail to the real handler if breakFlags==0. 11740 */ 11741 ldrb r3, [rSELF, #offThread_breakFlags] 11742 adrl lr, dvmAsmInstructionStart + (86 * 64) 11743 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11744 cmp r3, #0 11745 bxeq lr @ nothing to do - jump to real handler 11746 EXPORT_PC() 11747 mov r0, rPC @ arg0 11748 mov r1, rFP @ arg1 11749 mov r2, rSELF @ arg2 11750 b dvmCheckBefore @ (dPC,dFP,self) tail call 11751 11752 /* ------------------------------ */ 11753 .balign 64 11754 .L_ALT_OP_IGET_CHAR: /* 0x57 */ 11755 /* File: armv5te/alt_stub.S */ 11756 /* 11757 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11758 * any interesting requests and then jump to the real instruction 11759 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11760 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11761 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11762 * bail to the real handler if breakFlags==0. 11763 */ 11764 ldrb r3, [rSELF, #offThread_breakFlags] 11765 adrl lr, dvmAsmInstructionStart + (87 * 64) 11766 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11767 cmp r3, #0 11768 bxeq lr @ nothing to do - jump to real handler 11769 EXPORT_PC() 11770 mov r0, rPC @ arg0 11771 mov r1, rFP @ arg1 11772 mov r2, rSELF @ arg2 11773 b dvmCheckBefore @ (dPC,dFP,self) tail call 11774 11775 /* ------------------------------ */ 11776 .balign 64 11777 .L_ALT_OP_IGET_SHORT: /* 0x58 */ 11778 /* File: armv5te/alt_stub.S */ 11779 /* 11780 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11781 * any interesting requests and then jump to the real instruction 11782 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11783 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11784 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11785 * bail to the real handler if breakFlags==0. 11786 */ 11787 ldrb r3, [rSELF, #offThread_breakFlags] 11788 adrl lr, dvmAsmInstructionStart + (88 * 64) 11789 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11790 cmp r3, #0 11791 bxeq lr @ nothing to do - jump to real handler 11792 EXPORT_PC() 11793 mov r0, rPC @ arg0 11794 mov r1, rFP @ arg1 11795 mov r2, rSELF @ arg2 11796 b dvmCheckBefore @ (dPC,dFP,self) tail call 11797 11798 /* ------------------------------ */ 11799 .balign 64 11800 .L_ALT_OP_IPUT: /* 0x59 */ 11801 /* File: armv5te/alt_stub.S */ 11802 /* 11803 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11804 * any interesting requests and then jump to the real instruction 11805 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11806 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11807 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11808 * bail to the real handler if breakFlags==0. 11809 */ 11810 ldrb r3, [rSELF, #offThread_breakFlags] 11811 adrl lr, dvmAsmInstructionStart + (89 * 64) 11812 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11813 cmp r3, #0 11814 bxeq lr @ nothing to do - jump to real handler 11815 EXPORT_PC() 11816 mov r0, rPC @ arg0 11817 mov r1, rFP @ arg1 11818 mov r2, rSELF @ arg2 11819 b dvmCheckBefore @ (dPC,dFP,self) tail call 11820 11821 /* ------------------------------ */ 11822 .balign 64 11823 .L_ALT_OP_IPUT_WIDE: /* 0x5a */ 11824 /* File: armv5te/alt_stub.S */ 11825 /* 11826 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11827 * any interesting requests and then jump to the real instruction 11828 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11829 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11830 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11831 * bail to the real handler if breakFlags==0. 11832 */ 11833 ldrb r3, [rSELF, #offThread_breakFlags] 11834 adrl lr, dvmAsmInstructionStart + (90 * 64) 11835 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11836 cmp r3, #0 11837 bxeq lr @ nothing to do - jump to real handler 11838 EXPORT_PC() 11839 mov r0, rPC @ arg0 11840 mov r1, rFP @ arg1 11841 mov r2, rSELF @ arg2 11842 b dvmCheckBefore @ (dPC,dFP,self) tail call 11843 11844 /* ------------------------------ */ 11845 .balign 64 11846 .L_ALT_OP_IPUT_OBJECT: /* 0x5b */ 11847 /* File: armv5te/alt_stub.S */ 11848 /* 11849 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11850 * any interesting requests and then jump to the real instruction 11851 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11852 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11853 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11854 * bail to the real handler if breakFlags==0. 11855 */ 11856 ldrb r3, [rSELF, #offThread_breakFlags] 11857 adrl lr, dvmAsmInstructionStart + (91 * 64) 11858 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11859 cmp r3, #0 11860 bxeq lr @ nothing to do - jump to real handler 11861 EXPORT_PC() 11862 mov r0, rPC @ arg0 11863 mov r1, rFP @ arg1 11864 mov r2, rSELF @ arg2 11865 b dvmCheckBefore @ (dPC,dFP,self) tail call 11866 11867 /* ------------------------------ */ 11868 .balign 64 11869 .L_ALT_OP_IPUT_BOOLEAN: /* 0x5c */ 11870 /* File: armv5te/alt_stub.S */ 11871 /* 11872 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11873 * any interesting requests and then jump to the real instruction 11874 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11875 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11876 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11877 * bail to the real handler if breakFlags==0. 11878 */ 11879 ldrb r3, [rSELF, #offThread_breakFlags] 11880 adrl lr, dvmAsmInstructionStart + (92 * 64) 11881 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11882 cmp r3, #0 11883 bxeq lr @ nothing to do - jump to real handler 11884 EXPORT_PC() 11885 mov r0, rPC @ arg0 11886 mov r1, rFP @ arg1 11887 mov r2, rSELF @ arg2 11888 b dvmCheckBefore @ (dPC,dFP,self) tail call 11889 11890 /* ------------------------------ */ 11891 .balign 64 11892 .L_ALT_OP_IPUT_BYTE: /* 0x5d */ 11893 /* File: armv5te/alt_stub.S */ 11894 /* 11895 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11896 * any interesting requests and then jump to the real instruction 11897 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11898 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11899 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11900 * bail to the real handler if breakFlags==0. 11901 */ 11902 ldrb r3, [rSELF, #offThread_breakFlags] 11903 adrl lr, dvmAsmInstructionStart + (93 * 64) 11904 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11905 cmp r3, #0 11906 bxeq lr @ nothing to do - jump to real handler 11907 EXPORT_PC() 11908 mov r0, rPC @ arg0 11909 mov r1, rFP @ arg1 11910 mov r2, rSELF @ arg2 11911 b dvmCheckBefore @ (dPC,dFP,self) tail call 11912 11913 /* ------------------------------ */ 11914 .balign 64 11915 .L_ALT_OP_IPUT_CHAR: /* 0x5e */ 11916 /* File: armv5te/alt_stub.S */ 11917 /* 11918 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11919 * any interesting requests and then jump to the real instruction 11920 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11921 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11922 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11923 * bail to the real handler if breakFlags==0. 11924 */ 11925 ldrb r3, [rSELF, #offThread_breakFlags] 11926 adrl lr, dvmAsmInstructionStart + (94 * 64) 11927 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11928 cmp r3, #0 11929 bxeq lr @ nothing to do - jump to real handler 11930 EXPORT_PC() 11931 mov r0, rPC @ arg0 11932 mov r1, rFP @ arg1 11933 mov r2, rSELF @ arg2 11934 b dvmCheckBefore @ (dPC,dFP,self) tail call 11935 11936 /* ------------------------------ */ 11937 .balign 64 11938 .L_ALT_OP_IPUT_SHORT: /* 0x5f */ 11939 /* File: armv5te/alt_stub.S */ 11940 /* 11941 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11942 * any interesting requests and then jump to the real instruction 11943 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11944 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11945 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11946 * bail to the real handler if breakFlags==0. 11947 */ 11948 ldrb r3, [rSELF, #offThread_breakFlags] 11949 adrl lr, dvmAsmInstructionStart + (95 * 64) 11950 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11951 cmp r3, #0 11952 bxeq lr @ nothing to do - jump to real handler 11953 EXPORT_PC() 11954 mov r0, rPC @ arg0 11955 mov r1, rFP @ arg1 11956 mov r2, rSELF @ arg2 11957 b dvmCheckBefore @ (dPC,dFP,self) tail call 11958 11959 /* ------------------------------ */ 11960 .balign 64 11961 .L_ALT_OP_SGET: /* 0x60 */ 11962 /* File: armv5te/alt_stub.S */ 11963 /* 11964 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11965 * any interesting requests and then jump to the real instruction 11966 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11967 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11968 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11969 * bail to the real handler if breakFlags==0. 11970 */ 11971 ldrb r3, [rSELF, #offThread_breakFlags] 11972 adrl lr, dvmAsmInstructionStart + (96 * 64) 11973 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11974 cmp r3, #0 11975 bxeq lr @ nothing to do - jump to real handler 11976 EXPORT_PC() 11977 mov r0, rPC @ arg0 11978 mov r1, rFP @ arg1 11979 mov r2, rSELF @ arg2 11980 b dvmCheckBefore @ (dPC,dFP,self) tail call 11981 11982 /* ------------------------------ */ 11983 .balign 64 11984 .L_ALT_OP_SGET_WIDE: /* 0x61 */ 11985 /* File: armv5te/alt_stub.S */ 11986 /* 11987 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11988 * any interesting requests and then jump to the real instruction 11989 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11990 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11991 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11992 * bail to the real handler if breakFlags==0. 11993 */ 11994 ldrb r3, [rSELF, #offThread_breakFlags] 11995 adrl lr, dvmAsmInstructionStart + (97 * 64) 11996 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11997 cmp r3, #0 11998 bxeq lr @ nothing to do - jump to real handler 11999 EXPORT_PC() 12000 mov r0, rPC @ arg0 12001 mov r1, rFP @ arg1 12002 mov r2, rSELF @ arg2 12003 b dvmCheckBefore @ (dPC,dFP,self) tail call 12004 12005 /* ------------------------------ */ 12006 .balign 64 12007 .L_ALT_OP_SGET_OBJECT: /* 0x62 */ 12008 /* File: armv5te/alt_stub.S */ 12009 /* 12010 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12011 * any interesting requests and then jump to the real instruction 12012 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12013 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12014 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12015 * bail to the real handler if breakFlags==0. 12016 */ 12017 ldrb r3, [rSELF, #offThread_breakFlags] 12018 adrl lr, dvmAsmInstructionStart + (98 * 64) 12019 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12020 cmp r3, #0 12021 bxeq lr @ nothing to do - jump to real handler 12022 EXPORT_PC() 12023 mov r0, rPC @ arg0 12024 mov r1, rFP @ arg1 12025 mov r2, rSELF @ arg2 12026 b dvmCheckBefore @ (dPC,dFP,self) tail call 12027 12028 /* ------------------------------ */ 12029 .balign 64 12030 .L_ALT_OP_SGET_BOOLEAN: /* 0x63 */ 12031 /* File: armv5te/alt_stub.S */ 12032 /* 12033 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12034 * any interesting requests and then jump to the real instruction 12035 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12036 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12037 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12038 * bail to the real handler if breakFlags==0. 12039 */ 12040 ldrb r3, [rSELF, #offThread_breakFlags] 12041 adrl lr, dvmAsmInstructionStart + (99 * 64) 12042 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12043 cmp r3, #0 12044 bxeq lr @ nothing to do - jump to real handler 12045 EXPORT_PC() 12046 mov r0, rPC @ arg0 12047 mov r1, rFP @ arg1 12048 mov r2, rSELF @ arg2 12049 b dvmCheckBefore @ (dPC,dFP,self) tail call 12050 12051 /* ------------------------------ */ 12052 .balign 64 12053 .L_ALT_OP_SGET_BYTE: /* 0x64 */ 12054 /* File: armv5te/alt_stub.S */ 12055 /* 12056 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12057 * any interesting requests and then jump to the real instruction 12058 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12059 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12060 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12061 * bail to the real handler if breakFlags==0. 12062 */ 12063 ldrb r3, [rSELF, #offThread_breakFlags] 12064 adrl lr, dvmAsmInstructionStart + (100 * 64) 12065 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12066 cmp r3, #0 12067 bxeq lr @ nothing to do - jump to real handler 12068 EXPORT_PC() 12069 mov r0, rPC @ arg0 12070 mov r1, rFP @ arg1 12071 mov r2, rSELF @ arg2 12072 b dvmCheckBefore @ (dPC,dFP,self) tail call 12073 12074 /* ------------------------------ */ 12075 .balign 64 12076 .L_ALT_OP_SGET_CHAR: /* 0x65 */ 12077 /* File: armv5te/alt_stub.S */ 12078 /* 12079 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12080 * any interesting requests and then jump to the real instruction 12081 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12082 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12083 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12084 * bail to the real handler if breakFlags==0. 12085 */ 12086 ldrb r3, [rSELF, #offThread_breakFlags] 12087 adrl lr, dvmAsmInstructionStart + (101 * 64) 12088 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12089 cmp r3, #0 12090 bxeq lr @ nothing to do - jump to real handler 12091 EXPORT_PC() 12092 mov r0, rPC @ arg0 12093 mov r1, rFP @ arg1 12094 mov r2, rSELF @ arg2 12095 b dvmCheckBefore @ (dPC,dFP,self) tail call 12096 12097 /* ------------------------------ */ 12098 .balign 64 12099 .L_ALT_OP_SGET_SHORT: /* 0x66 */ 12100 /* File: armv5te/alt_stub.S */ 12101 /* 12102 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12103 * any interesting requests and then jump to the real instruction 12104 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12105 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12106 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12107 * bail to the real handler if breakFlags==0. 12108 */ 12109 ldrb r3, [rSELF, #offThread_breakFlags] 12110 adrl lr, dvmAsmInstructionStart + (102 * 64) 12111 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12112 cmp r3, #0 12113 bxeq lr @ nothing to do - jump to real handler 12114 EXPORT_PC() 12115 mov r0, rPC @ arg0 12116 mov r1, rFP @ arg1 12117 mov r2, rSELF @ arg2 12118 b dvmCheckBefore @ (dPC,dFP,self) tail call 12119 12120 /* ------------------------------ */ 12121 .balign 64 12122 .L_ALT_OP_SPUT: /* 0x67 */ 12123 /* File: armv5te/alt_stub.S */ 12124 /* 12125 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12126 * any interesting requests and then jump to the real instruction 12127 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12128 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12129 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12130 * bail to the real handler if breakFlags==0. 12131 */ 12132 ldrb r3, [rSELF, #offThread_breakFlags] 12133 adrl lr, dvmAsmInstructionStart + (103 * 64) 12134 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12135 cmp r3, #0 12136 bxeq lr @ nothing to do - jump to real handler 12137 EXPORT_PC() 12138 mov r0, rPC @ arg0 12139 mov r1, rFP @ arg1 12140 mov r2, rSELF @ arg2 12141 b dvmCheckBefore @ (dPC,dFP,self) tail call 12142 12143 /* ------------------------------ */ 12144 .balign 64 12145 .L_ALT_OP_SPUT_WIDE: /* 0x68 */ 12146 /* File: armv5te/alt_stub.S */ 12147 /* 12148 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12149 * any interesting requests and then jump to the real instruction 12150 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12151 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12152 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12153 * bail to the real handler if breakFlags==0. 12154 */ 12155 ldrb r3, [rSELF, #offThread_breakFlags] 12156 adrl lr, dvmAsmInstructionStart + (104 * 64) 12157 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12158 cmp r3, #0 12159 bxeq lr @ nothing to do - jump to real handler 12160 EXPORT_PC() 12161 mov r0, rPC @ arg0 12162 mov r1, rFP @ arg1 12163 mov r2, rSELF @ arg2 12164 b dvmCheckBefore @ (dPC,dFP,self) tail call 12165 12166 /* ------------------------------ */ 12167 .balign 64 12168 .L_ALT_OP_SPUT_OBJECT: /* 0x69 */ 12169 /* File: armv5te/alt_stub.S */ 12170 /* 12171 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12172 * any interesting requests and then jump to the real instruction 12173 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12174 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12175 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12176 * bail to the real handler if breakFlags==0. 12177 */ 12178 ldrb r3, [rSELF, #offThread_breakFlags] 12179 adrl lr, dvmAsmInstructionStart + (105 * 64) 12180 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12181 cmp r3, #0 12182 bxeq lr @ nothing to do - jump to real handler 12183 EXPORT_PC() 12184 mov r0, rPC @ arg0 12185 mov r1, rFP @ arg1 12186 mov r2, rSELF @ arg2 12187 b dvmCheckBefore @ (dPC,dFP,self) tail call 12188 12189 /* ------------------------------ */ 12190 .balign 64 12191 .L_ALT_OP_SPUT_BOOLEAN: /* 0x6a */ 12192 /* File: armv5te/alt_stub.S */ 12193 /* 12194 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12195 * any interesting requests and then jump to the real instruction 12196 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12197 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12198 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12199 * bail to the real handler if breakFlags==0. 12200 */ 12201 ldrb r3, [rSELF, #offThread_breakFlags] 12202 adrl lr, dvmAsmInstructionStart + (106 * 64) 12203 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12204 cmp r3, #0 12205 bxeq lr @ nothing to do - jump to real handler 12206 EXPORT_PC() 12207 mov r0, rPC @ arg0 12208 mov r1, rFP @ arg1 12209 mov r2, rSELF @ arg2 12210 b dvmCheckBefore @ (dPC,dFP,self) tail call 12211 12212 /* ------------------------------ */ 12213 .balign 64 12214 .L_ALT_OP_SPUT_BYTE: /* 0x6b */ 12215 /* File: armv5te/alt_stub.S */ 12216 /* 12217 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12218 * any interesting requests and then jump to the real instruction 12219 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12220 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12221 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12222 * bail to the real handler if breakFlags==0. 12223 */ 12224 ldrb r3, [rSELF, #offThread_breakFlags] 12225 adrl lr, dvmAsmInstructionStart + (107 * 64) 12226 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12227 cmp r3, #0 12228 bxeq lr @ nothing to do - jump to real handler 12229 EXPORT_PC() 12230 mov r0, rPC @ arg0 12231 mov r1, rFP @ arg1 12232 mov r2, rSELF @ arg2 12233 b dvmCheckBefore @ (dPC,dFP,self) tail call 12234 12235 /* ------------------------------ */ 12236 .balign 64 12237 .L_ALT_OP_SPUT_CHAR: /* 0x6c */ 12238 /* File: armv5te/alt_stub.S */ 12239 /* 12240 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12241 * any interesting requests and then jump to the real instruction 12242 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12243 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12244 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12245 * bail to the real handler if breakFlags==0. 12246 */ 12247 ldrb r3, [rSELF, #offThread_breakFlags] 12248 adrl lr, dvmAsmInstructionStart + (108 * 64) 12249 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12250 cmp r3, #0 12251 bxeq lr @ nothing to do - jump to real handler 12252 EXPORT_PC() 12253 mov r0, rPC @ arg0 12254 mov r1, rFP @ arg1 12255 mov r2, rSELF @ arg2 12256 b dvmCheckBefore @ (dPC,dFP,self) tail call 12257 12258 /* ------------------------------ */ 12259 .balign 64 12260 .L_ALT_OP_SPUT_SHORT: /* 0x6d */ 12261 /* File: armv5te/alt_stub.S */ 12262 /* 12263 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12264 * any interesting requests and then jump to the real instruction 12265 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12266 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12267 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12268 * bail to the real handler if breakFlags==0. 12269 */ 12270 ldrb r3, [rSELF, #offThread_breakFlags] 12271 adrl lr, dvmAsmInstructionStart + (109 * 64) 12272 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12273 cmp r3, #0 12274 bxeq lr @ nothing to do - jump to real handler 12275 EXPORT_PC() 12276 mov r0, rPC @ arg0 12277 mov r1, rFP @ arg1 12278 mov r2, rSELF @ arg2 12279 b dvmCheckBefore @ (dPC,dFP,self) tail call 12280 12281 /* ------------------------------ */ 12282 .balign 64 12283 .L_ALT_OP_INVOKE_VIRTUAL: /* 0x6e */ 12284 /* File: armv5te/alt_stub.S */ 12285 /* 12286 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12287 * any interesting requests and then jump to the real instruction 12288 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12289 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12290 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12291 * bail to the real handler if breakFlags==0. 12292 */ 12293 ldrb r3, [rSELF, #offThread_breakFlags] 12294 adrl lr, dvmAsmInstructionStart + (110 * 64) 12295 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12296 cmp r3, #0 12297 bxeq lr @ nothing to do - jump to real handler 12298 EXPORT_PC() 12299 mov r0, rPC @ arg0 12300 mov r1, rFP @ arg1 12301 mov r2, rSELF @ arg2 12302 b dvmCheckBefore @ (dPC,dFP,self) tail call 12303 12304 /* ------------------------------ */ 12305 .balign 64 12306 .L_ALT_OP_INVOKE_SUPER: /* 0x6f */ 12307 /* File: armv5te/alt_stub.S */ 12308 /* 12309 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12310 * any interesting requests and then jump to the real instruction 12311 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12312 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12313 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12314 * bail to the real handler if breakFlags==0. 12315 */ 12316 ldrb r3, [rSELF, #offThread_breakFlags] 12317 adrl lr, dvmAsmInstructionStart + (111 * 64) 12318 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12319 cmp r3, #0 12320 bxeq lr @ nothing to do - jump to real handler 12321 EXPORT_PC() 12322 mov r0, rPC @ arg0 12323 mov r1, rFP @ arg1 12324 mov r2, rSELF @ arg2 12325 b dvmCheckBefore @ (dPC,dFP,self) tail call 12326 12327 /* ------------------------------ */ 12328 .balign 64 12329 .L_ALT_OP_INVOKE_DIRECT: /* 0x70 */ 12330 /* File: armv5te/alt_stub.S */ 12331 /* 12332 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12333 * any interesting requests and then jump to the real instruction 12334 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12335 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12336 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12337 * bail to the real handler if breakFlags==0. 12338 */ 12339 ldrb r3, [rSELF, #offThread_breakFlags] 12340 adrl lr, dvmAsmInstructionStart + (112 * 64) 12341 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12342 cmp r3, #0 12343 bxeq lr @ nothing to do - jump to real handler 12344 EXPORT_PC() 12345 mov r0, rPC @ arg0 12346 mov r1, rFP @ arg1 12347 mov r2, rSELF @ arg2 12348 b dvmCheckBefore @ (dPC,dFP,self) tail call 12349 12350 /* ------------------------------ */ 12351 .balign 64 12352 .L_ALT_OP_INVOKE_STATIC: /* 0x71 */ 12353 /* File: armv5te/alt_stub.S */ 12354 /* 12355 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12356 * any interesting requests and then jump to the real instruction 12357 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12358 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12359 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12360 * bail to the real handler if breakFlags==0. 12361 */ 12362 ldrb r3, [rSELF, #offThread_breakFlags] 12363 adrl lr, dvmAsmInstructionStart + (113 * 64) 12364 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12365 cmp r3, #0 12366 bxeq lr @ nothing to do - jump to real handler 12367 EXPORT_PC() 12368 mov r0, rPC @ arg0 12369 mov r1, rFP @ arg1 12370 mov r2, rSELF @ arg2 12371 b dvmCheckBefore @ (dPC,dFP,self) tail call 12372 12373 /* ------------------------------ */ 12374 .balign 64 12375 .L_ALT_OP_INVOKE_INTERFACE: /* 0x72 */ 12376 /* File: armv5te/alt_stub.S */ 12377 /* 12378 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12379 * any interesting requests and then jump to the real instruction 12380 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12381 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12382 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12383 * bail to the real handler if breakFlags==0. 12384 */ 12385 ldrb r3, [rSELF, #offThread_breakFlags] 12386 adrl lr, dvmAsmInstructionStart + (114 * 64) 12387 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12388 cmp r3, #0 12389 bxeq lr @ nothing to do - jump to real handler 12390 EXPORT_PC() 12391 mov r0, rPC @ arg0 12392 mov r1, rFP @ arg1 12393 mov r2, rSELF @ arg2 12394 b dvmCheckBefore @ (dPC,dFP,self) tail call 12395 12396 /* ------------------------------ */ 12397 .balign 64 12398 .L_ALT_OP_UNUSED_73: /* 0x73 */ 12399 /* File: armv5te/alt_stub.S */ 12400 /* 12401 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12402 * any interesting requests and then jump to the real instruction 12403 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12404 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12405 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12406 * bail to the real handler if breakFlags==0. 12407 */ 12408 ldrb r3, [rSELF, #offThread_breakFlags] 12409 adrl lr, dvmAsmInstructionStart + (115 * 64) 12410 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12411 cmp r3, #0 12412 bxeq lr @ nothing to do - jump to real handler 12413 EXPORT_PC() 12414 mov r0, rPC @ arg0 12415 mov r1, rFP @ arg1 12416 mov r2, rSELF @ arg2 12417 b dvmCheckBefore @ (dPC,dFP,self) tail call 12418 12419 /* ------------------------------ */ 12420 .balign 64 12421 .L_ALT_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 12422 /* File: armv5te/alt_stub.S */ 12423 /* 12424 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12425 * any interesting requests and then jump to the real instruction 12426 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12427 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12428 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12429 * bail to the real handler if breakFlags==0. 12430 */ 12431 ldrb r3, [rSELF, #offThread_breakFlags] 12432 adrl lr, dvmAsmInstructionStart + (116 * 64) 12433 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12434 cmp r3, #0 12435 bxeq lr @ nothing to do - jump to real handler 12436 EXPORT_PC() 12437 mov r0, rPC @ arg0 12438 mov r1, rFP @ arg1 12439 mov r2, rSELF @ arg2 12440 b dvmCheckBefore @ (dPC,dFP,self) tail call 12441 12442 /* ------------------------------ */ 12443 .balign 64 12444 .L_ALT_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 12445 /* File: armv5te/alt_stub.S */ 12446 /* 12447 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12448 * any interesting requests and then jump to the real instruction 12449 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12450 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12451 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12452 * bail to the real handler if breakFlags==0. 12453 */ 12454 ldrb r3, [rSELF, #offThread_breakFlags] 12455 adrl lr, dvmAsmInstructionStart + (117 * 64) 12456 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12457 cmp r3, #0 12458 bxeq lr @ nothing to do - jump to real handler 12459 EXPORT_PC() 12460 mov r0, rPC @ arg0 12461 mov r1, rFP @ arg1 12462 mov r2, rSELF @ arg2 12463 b dvmCheckBefore @ (dPC,dFP,self) tail call 12464 12465 /* ------------------------------ */ 12466 .balign 64 12467 .L_ALT_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 12468 /* File: armv5te/alt_stub.S */ 12469 /* 12470 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12471 * any interesting requests and then jump to the real instruction 12472 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12473 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12474 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12475 * bail to the real handler if breakFlags==0. 12476 */ 12477 ldrb r3, [rSELF, #offThread_breakFlags] 12478 adrl lr, dvmAsmInstructionStart + (118 * 64) 12479 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12480 cmp r3, #0 12481 bxeq lr @ nothing to do - jump to real handler 12482 EXPORT_PC() 12483 mov r0, rPC @ arg0 12484 mov r1, rFP @ arg1 12485 mov r2, rSELF @ arg2 12486 b dvmCheckBefore @ (dPC,dFP,self) tail call 12487 12488 /* ------------------------------ */ 12489 .balign 64 12490 .L_ALT_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 12491 /* File: armv5te/alt_stub.S */ 12492 /* 12493 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12494 * any interesting requests and then jump to the real instruction 12495 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12496 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12497 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12498 * bail to the real handler if breakFlags==0. 12499 */ 12500 ldrb r3, [rSELF, #offThread_breakFlags] 12501 adrl lr, dvmAsmInstructionStart + (119 * 64) 12502 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12503 cmp r3, #0 12504 bxeq lr @ nothing to do - jump to real handler 12505 EXPORT_PC() 12506 mov r0, rPC @ arg0 12507 mov r1, rFP @ arg1 12508 mov r2, rSELF @ arg2 12509 b dvmCheckBefore @ (dPC,dFP,self) tail call 12510 12511 /* ------------------------------ */ 12512 .balign 64 12513 .L_ALT_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 12514 /* File: armv5te/alt_stub.S */ 12515 /* 12516 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12517 * any interesting requests and then jump to the real instruction 12518 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12519 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12520 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12521 * bail to the real handler if breakFlags==0. 12522 */ 12523 ldrb r3, [rSELF, #offThread_breakFlags] 12524 adrl lr, dvmAsmInstructionStart + (120 * 64) 12525 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12526 cmp r3, #0 12527 bxeq lr @ nothing to do - jump to real handler 12528 EXPORT_PC() 12529 mov r0, rPC @ arg0 12530 mov r1, rFP @ arg1 12531 mov r2, rSELF @ arg2 12532 b dvmCheckBefore @ (dPC,dFP,self) tail call 12533 12534 /* ------------------------------ */ 12535 .balign 64 12536 .L_ALT_OP_UNUSED_79: /* 0x79 */ 12537 /* File: armv5te/alt_stub.S */ 12538 /* 12539 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12540 * any interesting requests and then jump to the real instruction 12541 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12542 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12543 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12544 * bail to the real handler if breakFlags==0. 12545 */ 12546 ldrb r3, [rSELF, #offThread_breakFlags] 12547 adrl lr, dvmAsmInstructionStart + (121 * 64) 12548 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12549 cmp r3, #0 12550 bxeq lr @ nothing to do - jump to real handler 12551 EXPORT_PC() 12552 mov r0, rPC @ arg0 12553 mov r1, rFP @ arg1 12554 mov r2, rSELF @ arg2 12555 b dvmCheckBefore @ (dPC,dFP,self) tail call 12556 12557 /* ------------------------------ */ 12558 .balign 64 12559 .L_ALT_OP_UNUSED_7A: /* 0x7a */ 12560 /* File: armv5te/alt_stub.S */ 12561 /* 12562 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12563 * any interesting requests and then jump to the real instruction 12564 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12565 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12566 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12567 * bail to the real handler if breakFlags==0. 12568 */ 12569 ldrb r3, [rSELF, #offThread_breakFlags] 12570 adrl lr, dvmAsmInstructionStart + (122 * 64) 12571 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12572 cmp r3, #0 12573 bxeq lr @ nothing to do - jump to real handler 12574 EXPORT_PC() 12575 mov r0, rPC @ arg0 12576 mov r1, rFP @ arg1 12577 mov r2, rSELF @ arg2 12578 b dvmCheckBefore @ (dPC,dFP,self) tail call 12579 12580 /* ------------------------------ */ 12581 .balign 64 12582 .L_ALT_OP_NEG_INT: /* 0x7b */ 12583 /* File: armv5te/alt_stub.S */ 12584 /* 12585 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12586 * any interesting requests and then jump to the real instruction 12587 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12588 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12589 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12590 * bail to the real handler if breakFlags==0. 12591 */ 12592 ldrb r3, [rSELF, #offThread_breakFlags] 12593 adrl lr, dvmAsmInstructionStart + (123 * 64) 12594 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12595 cmp r3, #0 12596 bxeq lr @ nothing to do - jump to real handler 12597 EXPORT_PC() 12598 mov r0, rPC @ arg0 12599 mov r1, rFP @ arg1 12600 mov r2, rSELF @ arg2 12601 b dvmCheckBefore @ (dPC,dFP,self) tail call 12602 12603 /* ------------------------------ */ 12604 .balign 64 12605 .L_ALT_OP_NOT_INT: /* 0x7c */ 12606 /* File: armv5te/alt_stub.S */ 12607 /* 12608 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12609 * any interesting requests and then jump to the real instruction 12610 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12611 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12612 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12613 * bail to the real handler if breakFlags==0. 12614 */ 12615 ldrb r3, [rSELF, #offThread_breakFlags] 12616 adrl lr, dvmAsmInstructionStart + (124 * 64) 12617 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12618 cmp r3, #0 12619 bxeq lr @ nothing to do - jump to real handler 12620 EXPORT_PC() 12621 mov r0, rPC @ arg0 12622 mov r1, rFP @ arg1 12623 mov r2, rSELF @ arg2 12624 b dvmCheckBefore @ (dPC,dFP,self) tail call 12625 12626 /* ------------------------------ */ 12627 .balign 64 12628 .L_ALT_OP_NEG_LONG: /* 0x7d */ 12629 /* File: armv5te/alt_stub.S */ 12630 /* 12631 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12632 * any interesting requests and then jump to the real instruction 12633 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12634 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12635 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12636 * bail to the real handler if breakFlags==0. 12637 */ 12638 ldrb r3, [rSELF, #offThread_breakFlags] 12639 adrl lr, dvmAsmInstructionStart + (125 * 64) 12640 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12641 cmp r3, #0 12642 bxeq lr @ nothing to do - jump to real handler 12643 EXPORT_PC() 12644 mov r0, rPC @ arg0 12645 mov r1, rFP @ arg1 12646 mov r2, rSELF @ arg2 12647 b dvmCheckBefore @ (dPC,dFP,self) tail call 12648 12649 /* ------------------------------ */ 12650 .balign 64 12651 .L_ALT_OP_NOT_LONG: /* 0x7e */ 12652 /* File: armv5te/alt_stub.S */ 12653 /* 12654 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12655 * any interesting requests and then jump to the real instruction 12656 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12657 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12658 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12659 * bail to the real handler if breakFlags==0. 12660 */ 12661 ldrb r3, [rSELF, #offThread_breakFlags] 12662 adrl lr, dvmAsmInstructionStart + (126 * 64) 12663 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12664 cmp r3, #0 12665 bxeq lr @ nothing to do - jump to real handler 12666 EXPORT_PC() 12667 mov r0, rPC @ arg0 12668 mov r1, rFP @ arg1 12669 mov r2, rSELF @ arg2 12670 b dvmCheckBefore @ (dPC,dFP,self) tail call 12671 12672 /* ------------------------------ */ 12673 .balign 64 12674 .L_ALT_OP_NEG_FLOAT: /* 0x7f */ 12675 /* File: armv5te/alt_stub.S */ 12676 /* 12677 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12678 * any interesting requests and then jump to the real instruction 12679 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12680 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12681 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12682 * bail to the real handler if breakFlags==0. 12683 */ 12684 ldrb r3, [rSELF, #offThread_breakFlags] 12685 adrl lr, dvmAsmInstructionStart + (127 * 64) 12686 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12687 cmp r3, #0 12688 bxeq lr @ nothing to do - jump to real handler 12689 EXPORT_PC() 12690 mov r0, rPC @ arg0 12691 mov r1, rFP @ arg1 12692 mov r2, rSELF @ arg2 12693 b dvmCheckBefore @ (dPC,dFP,self) tail call 12694 12695 /* ------------------------------ */ 12696 .balign 64 12697 .L_ALT_OP_NEG_DOUBLE: /* 0x80 */ 12698 /* File: armv5te/alt_stub.S */ 12699 /* 12700 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12701 * any interesting requests and then jump to the real instruction 12702 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12703 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12704 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12705 * bail to the real handler if breakFlags==0. 12706 */ 12707 ldrb r3, [rSELF, #offThread_breakFlags] 12708 adrl lr, dvmAsmInstructionStart + (128 * 64) 12709 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12710 cmp r3, #0 12711 bxeq lr @ nothing to do - jump to real handler 12712 EXPORT_PC() 12713 mov r0, rPC @ arg0 12714 mov r1, rFP @ arg1 12715 mov r2, rSELF @ arg2 12716 b dvmCheckBefore @ (dPC,dFP,self) tail call 12717 12718 /* ------------------------------ */ 12719 .balign 64 12720 .L_ALT_OP_INT_TO_LONG: /* 0x81 */ 12721 /* File: armv5te/alt_stub.S */ 12722 /* 12723 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12724 * any interesting requests and then jump to the real instruction 12725 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12726 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12727 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12728 * bail to the real handler if breakFlags==0. 12729 */ 12730 ldrb r3, [rSELF, #offThread_breakFlags] 12731 adrl lr, dvmAsmInstructionStart + (129 * 64) 12732 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12733 cmp r3, #0 12734 bxeq lr @ nothing to do - jump to real handler 12735 EXPORT_PC() 12736 mov r0, rPC @ arg0 12737 mov r1, rFP @ arg1 12738 mov r2, rSELF @ arg2 12739 b dvmCheckBefore @ (dPC,dFP,self) tail call 12740 12741 /* ------------------------------ */ 12742 .balign 64 12743 .L_ALT_OP_INT_TO_FLOAT: /* 0x82 */ 12744 /* File: armv5te/alt_stub.S */ 12745 /* 12746 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12747 * any interesting requests and then jump to the real instruction 12748 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12749 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12750 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12751 * bail to the real handler if breakFlags==0. 12752 */ 12753 ldrb r3, [rSELF, #offThread_breakFlags] 12754 adrl lr, dvmAsmInstructionStart + (130 * 64) 12755 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12756 cmp r3, #0 12757 bxeq lr @ nothing to do - jump to real handler 12758 EXPORT_PC() 12759 mov r0, rPC @ arg0 12760 mov r1, rFP @ arg1 12761 mov r2, rSELF @ arg2 12762 b dvmCheckBefore @ (dPC,dFP,self) tail call 12763 12764 /* ------------------------------ */ 12765 .balign 64 12766 .L_ALT_OP_INT_TO_DOUBLE: /* 0x83 */ 12767 /* File: armv5te/alt_stub.S */ 12768 /* 12769 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12770 * any interesting requests and then jump to the real instruction 12771 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12772 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12773 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12774 * bail to the real handler if breakFlags==0. 12775 */ 12776 ldrb r3, [rSELF, #offThread_breakFlags] 12777 adrl lr, dvmAsmInstructionStart + (131 * 64) 12778 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12779 cmp r3, #0 12780 bxeq lr @ nothing to do - jump to real handler 12781 EXPORT_PC() 12782 mov r0, rPC @ arg0 12783 mov r1, rFP @ arg1 12784 mov r2, rSELF @ arg2 12785 b dvmCheckBefore @ (dPC,dFP,self) tail call 12786 12787 /* ------------------------------ */ 12788 .balign 64 12789 .L_ALT_OP_LONG_TO_INT: /* 0x84 */ 12790 /* File: armv5te/alt_stub.S */ 12791 /* 12792 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12793 * any interesting requests and then jump to the real instruction 12794 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12795 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12796 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12797 * bail to the real handler if breakFlags==0. 12798 */ 12799 ldrb r3, [rSELF, #offThread_breakFlags] 12800 adrl lr, dvmAsmInstructionStart + (132 * 64) 12801 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12802 cmp r3, #0 12803 bxeq lr @ nothing to do - jump to real handler 12804 EXPORT_PC() 12805 mov r0, rPC @ arg0 12806 mov r1, rFP @ arg1 12807 mov r2, rSELF @ arg2 12808 b dvmCheckBefore @ (dPC,dFP,self) tail call 12809 12810 /* ------------------------------ */ 12811 .balign 64 12812 .L_ALT_OP_LONG_TO_FLOAT: /* 0x85 */ 12813 /* File: armv5te/alt_stub.S */ 12814 /* 12815 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12816 * any interesting requests and then jump to the real instruction 12817 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12818 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12819 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12820 * bail to the real handler if breakFlags==0. 12821 */ 12822 ldrb r3, [rSELF, #offThread_breakFlags] 12823 adrl lr, dvmAsmInstructionStart + (133 * 64) 12824 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12825 cmp r3, #0 12826 bxeq lr @ nothing to do - jump to real handler 12827 EXPORT_PC() 12828 mov r0, rPC @ arg0 12829 mov r1, rFP @ arg1 12830 mov r2, rSELF @ arg2 12831 b dvmCheckBefore @ (dPC,dFP,self) tail call 12832 12833 /* ------------------------------ */ 12834 .balign 64 12835 .L_ALT_OP_LONG_TO_DOUBLE: /* 0x86 */ 12836 /* File: armv5te/alt_stub.S */ 12837 /* 12838 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12839 * any interesting requests and then jump to the real instruction 12840 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12841 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12842 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12843 * bail to the real handler if breakFlags==0. 12844 */ 12845 ldrb r3, [rSELF, #offThread_breakFlags] 12846 adrl lr, dvmAsmInstructionStart + (134 * 64) 12847 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12848 cmp r3, #0 12849 bxeq lr @ nothing to do - jump to real handler 12850 EXPORT_PC() 12851 mov r0, rPC @ arg0 12852 mov r1, rFP @ arg1 12853 mov r2, rSELF @ arg2 12854 b dvmCheckBefore @ (dPC,dFP,self) tail call 12855 12856 /* ------------------------------ */ 12857 .balign 64 12858 .L_ALT_OP_FLOAT_TO_INT: /* 0x87 */ 12859 /* File: armv5te/alt_stub.S */ 12860 /* 12861 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12862 * any interesting requests and then jump to the real instruction 12863 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12864 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12865 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12866 * bail to the real handler if breakFlags==0. 12867 */ 12868 ldrb r3, [rSELF, #offThread_breakFlags] 12869 adrl lr, dvmAsmInstructionStart + (135 * 64) 12870 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12871 cmp r3, #0 12872 bxeq lr @ nothing to do - jump to real handler 12873 EXPORT_PC() 12874 mov r0, rPC @ arg0 12875 mov r1, rFP @ arg1 12876 mov r2, rSELF @ arg2 12877 b dvmCheckBefore @ (dPC,dFP,self) tail call 12878 12879 /* ------------------------------ */ 12880 .balign 64 12881 .L_ALT_OP_FLOAT_TO_LONG: /* 0x88 */ 12882 /* File: armv5te/alt_stub.S */ 12883 /* 12884 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12885 * any interesting requests and then jump to the real instruction 12886 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12887 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12888 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12889 * bail to the real handler if breakFlags==0. 12890 */ 12891 ldrb r3, [rSELF, #offThread_breakFlags] 12892 adrl lr, dvmAsmInstructionStart + (136 * 64) 12893 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12894 cmp r3, #0 12895 bxeq lr @ nothing to do - jump to real handler 12896 EXPORT_PC() 12897 mov r0, rPC @ arg0 12898 mov r1, rFP @ arg1 12899 mov r2, rSELF @ arg2 12900 b dvmCheckBefore @ (dPC,dFP,self) tail call 12901 12902 /* ------------------------------ */ 12903 .balign 64 12904 .L_ALT_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 12905 /* File: armv5te/alt_stub.S */ 12906 /* 12907 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12908 * any interesting requests and then jump to the real instruction 12909 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12910 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12911 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12912 * bail to the real handler if breakFlags==0. 12913 */ 12914 ldrb r3, [rSELF, #offThread_breakFlags] 12915 adrl lr, dvmAsmInstructionStart + (137 * 64) 12916 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12917 cmp r3, #0 12918 bxeq lr @ nothing to do - jump to real handler 12919 EXPORT_PC() 12920 mov r0, rPC @ arg0 12921 mov r1, rFP @ arg1 12922 mov r2, rSELF @ arg2 12923 b dvmCheckBefore @ (dPC,dFP,self) tail call 12924 12925 /* ------------------------------ */ 12926 .balign 64 12927 .L_ALT_OP_DOUBLE_TO_INT: /* 0x8a */ 12928 /* File: armv5te/alt_stub.S */ 12929 /* 12930 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12931 * any interesting requests and then jump to the real instruction 12932 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12933 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12934 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12935 * bail to the real handler if breakFlags==0. 12936 */ 12937 ldrb r3, [rSELF, #offThread_breakFlags] 12938 adrl lr, dvmAsmInstructionStart + (138 * 64) 12939 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12940 cmp r3, #0 12941 bxeq lr @ nothing to do - jump to real handler 12942 EXPORT_PC() 12943 mov r0, rPC @ arg0 12944 mov r1, rFP @ arg1 12945 mov r2, rSELF @ arg2 12946 b dvmCheckBefore @ (dPC,dFP,self) tail call 12947 12948 /* ------------------------------ */ 12949 .balign 64 12950 .L_ALT_OP_DOUBLE_TO_LONG: /* 0x8b */ 12951 /* File: armv5te/alt_stub.S */ 12952 /* 12953 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12954 * any interesting requests and then jump to the real instruction 12955 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12956 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12957 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12958 * bail to the real handler if breakFlags==0. 12959 */ 12960 ldrb r3, [rSELF, #offThread_breakFlags] 12961 adrl lr, dvmAsmInstructionStart + (139 * 64) 12962 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12963 cmp r3, #0 12964 bxeq lr @ nothing to do - jump to real handler 12965 EXPORT_PC() 12966 mov r0, rPC @ arg0 12967 mov r1, rFP @ arg1 12968 mov r2, rSELF @ arg2 12969 b dvmCheckBefore @ (dPC,dFP,self) tail call 12970 12971 /* ------------------------------ */ 12972 .balign 64 12973 .L_ALT_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 12974 /* File: armv5te/alt_stub.S */ 12975 /* 12976 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12977 * any interesting requests and then jump to the real instruction 12978 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12979 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12980 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12981 * bail to the real handler if breakFlags==0. 12982 */ 12983 ldrb r3, [rSELF, #offThread_breakFlags] 12984 adrl lr, dvmAsmInstructionStart + (140 * 64) 12985 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12986 cmp r3, #0 12987 bxeq lr @ nothing to do - jump to real handler 12988 EXPORT_PC() 12989 mov r0, rPC @ arg0 12990 mov r1, rFP @ arg1 12991 mov r2, rSELF @ arg2 12992 b dvmCheckBefore @ (dPC,dFP,self) tail call 12993 12994 /* ------------------------------ */ 12995 .balign 64 12996 .L_ALT_OP_INT_TO_BYTE: /* 0x8d */ 12997 /* File: armv5te/alt_stub.S */ 12998 /* 12999 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13000 * any interesting requests and then jump to the real instruction 13001 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13002 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13003 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13004 * bail to the real handler if breakFlags==0. 13005 */ 13006 ldrb r3, [rSELF, #offThread_breakFlags] 13007 adrl lr, dvmAsmInstructionStart + (141 * 64) 13008 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13009 cmp r3, #0 13010 bxeq lr @ nothing to do - jump to real handler 13011 EXPORT_PC() 13012 mov r0, rPC @ arg0 13013 mov r1, rFP @ arg1 13014 mov r2, rSELF @ arg2 13015 b dvmCheckBefore @ (dPC,dFP,self) tail call 13016 13017 /* ------------------------------ */ 13018 .balign 64 13019 .L_ALT_OP_INT_TO_CHAR: /* 0x8e */ 13020 /* File: armv5te/alt_stub.S */ 13021 /* 13022 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13023 * any interesting requests and then jump to the real instruction 13024 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13025 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13026 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13027 * bail to the real handler if breakFlags==0. 13028 */ 13029 ldrb r3, [rSELF, #offThread_breakFlags] 13030 adrl lr, dvmAsmInstructionStart + (142 * 64) 13031 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13032 cmp r3, #0 13033 bxeq lr @ nothing to do - jump to real handler 13034 EXPORT_PC() 13035 mov r0, rPC @ arg0 13036 mov r1, rFP @ arg1 13037 mov r2, rSELF @ arg2 13038 b dvmCheckBefore @ (dPC,dFP,self) tail call 13039 13040 /* ------------------------------ */ 13041 .balign 64 13042 .L_ALT_OP_INT_TO_SHORT: /* 0x8f */ 13043 /* File: armv5te/alt_stub.S */ 13044 /* 13045 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13046 * any interesting requests and then jump to the real instruction 13047 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13048 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13049 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13050 * bail to the real handler if breakFlags==0. 13051 */ 13052 ldrb r3, [rSELF, #offThread_breakFlags] 13053 adrl lr, dvmAsmInstructionStart + (143 * 64) 13054 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13055 cmp r3, #0 13056 bxeq lr @ nothing to do - jump to real handler 13057 EXPORT_PC() 13058 mov r0, rPC @ arg0 13059 mov r1, rFP @ arg1 13060 mov r2, rSELF @ arg2 13061 b dvmCheckBefore @ (dPC,dFP,self) tail call 13062 13063 /* ------------------------------ */ 13064 .balign 64 13065 .L_ALT_OP_ADD_INT: /* 0x90 */ 13066 /* File: armv5te/alt_stub.S */ 13067 /* 13068 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13069 * any interesting requests and then jump to the real instruction 13070 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13071 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13072 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13073 * bail to the real handler if breakFlags==0. 13074 */ 13075 ldrb r3, [rSELF, #offThread_breakFlags] 13076 adrl lr, dvmAsmInstructionStart + (144 * 64) 13077 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13078 cmp r3, #0 13079 bxeq lr @ nothing to do - jump to real handler 13080 EXPORT_PC() 13081 mov r0, rPC @ arg0 13082 mov r1, rFP @ arg1 13083 mov r2, rSELF @ arg2 13084 b dvmCheckBefore @ (dPC,dFP,self) tail call 13085 13086 /* ------------------------------ */ 13087 .balign 64 13088 .L_ALT_OP_SUB_INT: /* 0x91 */ 13089 /* File: armv5te/alt_stub.S */ 13090 /* 13091 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13092 * any interesting requests and then jump to the real instruction 13093 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13094 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13095 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13096 * bail to the real handler if breakFlags==0. 13097 */ 13098 ldrb r3, [rSELF, #offThread_breakFlags] 13099 adrl lr, dvmAsmInstructionStart + (145 * 64) 13100 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13101 cmp r3, #0 13102 bxeq lr @ nothing to do - jump to real handler 13103 EXPORT_PC() 13104 mov r0, rPC @ arg0 13105 mov r1, rFP @ arg1 13106 mov r2, rSELF @ arg2 13107 b dvmCheckBefore @ (dPC,dFP,self) tail call 13108 13109 /* ------------------------------ */ 13110 .balign 64 13111 .L_ALT_OP_MUL_INT: /* 0x92 */ 13112 /* File: armv5te/alt_stub.S */ 13113 /* 13114 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13115 * any interesting requests and then jump to the real instruction 13116 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13117 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13118 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13119 * bail to the real handler if breakFlags==0. 13120 */ 13121 ldrb r3, [rSELF, #offThread_breakFlags] 13122 adrl lr, dvmAsmInstructionStart + (146 * 64) 13123 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13124 cmp r3, #0 13125 bxeq lr @ nothing to do - jump to real handler 13126 EXPORT_PC() 13127 mov r0, rPC @ arg0 13128 mov r1, rFP @ arg1 13129 mov r2, rSELF @ arg2 13130 b dvmCheckBefore @ (dPC,dFP,self) tail call 13131 13132 /* ------------------------------ */ 13133 .balign 64 13134 .L_ALT_OP_DIV_INT: /* 0x93 */ 13135 /* File: armv5te/alt_stub.S */ 13136 /* 13137 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13138 * any interesting requests and then jump to the real instruction 13139 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13140 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13141 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13142 * bail to the real handler if breakFlags==0. 13143 */ 13144 ldrb r3, [rSELF, #offThread_breakFlags] 13145 adrl lr, dvmAsmInstructionStart + (147 * 64) 13146 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13147 cmp r3, #0 13148 bxeq lr @ nothing to do - jump to real handler 13149 EXPORT_PC() 13150 mov r0, rPC @ arg0 13151 mov r1, rFP @ arg1 13152 mov r2, rSELF @ arg2 13153 b dvmCheckBefore @ (dPC,dFP,self) tail call 13154 13155 /* ------------------------------ */ 13156 .balign 64 13157 .L_ALT_OP_REM_INT: /* 0x94 */ 13158 /* File: armv5te/alt_stub.S */ 13159 /* 13160 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13161 * any interesting requests and then jump to the real instruction 13162 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13163 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13164 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13165 * bail to the real handler if breakFlags==0. 13166 */ 13167 ldrb r3, [rSELF, #offThread_breakFlags] 13168 adrl lr, dvmAsmInstructionStart + (148 * 64) 13169 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13170 cmp r3, #0 13171 bxeq lr @ nothing to do - jump to real handler 13172 EXPORT_PC() 13173 mov r0, rPC @ arg0 13174 mov r1, rFP @ arg1 13175 mov r2, rSELF @ arg2 13176 b dvmCheckBefore @ (dPC,dFP,self) tail call 13177 13178 /* ------------------------------ */ 13179 .balign 64 13180 .L_ALT_OP_AND_INT: /* 0x95 */ 13181 /* File: armv5te/alt_stub.S */ 13182 /* 13183 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13184 * any interesting requests and then jump to the real instruction 13185 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13186 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13187 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13188 * bail to the real handler if breakFlags==0. 13189 */ 13190 ldrb r3, [rSELF, #offThread_breakFlags] 13191 adrl lr, dvmAsmInstructionStart + (149 * 64) 13192 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13193 cmp r3, #0 13194 bxeq lr @ nothing to do - jump to real handler 13195 EXPORT_PC() 13196 mov r0, rPC @ arg0 13197 mov r1, rFP @ arg1 13198 mov r2, rSELF @ arg2 13199 b dvmCheckBefore @ (dPC,dFP,self) tail call 13200 13201 /* ------------------------------ */ 13202 .balign 64 13203 .L_ALT_OP_OR_INT: /* 0x96 */ 13204 /* File: armv5te/alt_stub.S */ 13205 /* 13206 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13207 * any interesting requests and then jump to the real instruction 13208 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13209 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13210 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13211 * bail to the real handler if breakFlags==0. 13212 */ 13213 ldrb r3, [rSELF, #offThread_breakFlags] 13214 adrl lr, dvmAsmInstructionStart + (150 * 64) 13215 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13216 cmp r3, #0 13217 bxeq lr @ nothing to do - jump to real handler 13218 EXPORT_PC() 13219 mov r0, rPC @ arg0 13220 mov r1, rFP @ arg1 13221 mov r2, rSELF @ arg2 13222 b dvmCheckBefore @ (dPC,dFP,self) tail call 13223 13224 /* ------------------------------ */ 13225 .balign 64 13226 .L_ALT_OP_XOR_INT: /* 0x97 */ 13227 /* File: armv5te/alt_stub.S */ 13228 /* 13229 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13230 * any interesting requests and then jump to the real instruction 13231 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13232 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13233 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13234 * bail to the real handler if breakFlags==0. 13235 */ 13236 ldrb r3, [rSELF, #offThread_breakFlags] 13237 adrl lr, dvmAsmInstructionStart + (151 * 64) 13238 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13239 cmp r3, #0 13240 bxeq lr @ nothing to do - jump to real handler 13241 EXPORT_PC() 13242 mov r0, rPC @ arg0 13243 mov r1, rFP @ arg1 13244 mov r2, rSELF @ arg2 13245 b dvmCheckBefore @ (dPC,dFP,self) tail call 13246 13247 /* ------------------------------ */ 13248 .balign 64 13249 .L_ALT_OP_SHL_INT: /* 0x98 */ 13250 /* File: armv5te/alt_stub.S */ 13251 /* 13252 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13253 * any interesting requests and then jump to the real instruction 13254 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13255 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13256 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13257 * bail to the real handler if breakFlags==0. 13258 */ 13259 ldrb r3, [rSELF, #offThread_breakFlags] 13260 adrl lr, dvmAsmInstructionStart + (152 * 64) 13261 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13262 cmp r3, #0 13263 bxeq lr @ nothing to do - jump to real handler 13264 EXPORT_PC() 13265 mov r0, rPC @ arg0 13266 mov r1, rFP @ arg1 13267 mov r2, rSELF @ arg2 13268 b dvmCheckBefore @ (dPC,dFP,self) tail call 13269 13270 /* ------------------------------ */ 13271 .balign 64 13272 .L_ALT_OP_SHR_INT: /* 0x99 */ 13273 /* File: armv5te/alt_stub.S */ 13274 /* 13275 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13276 * any interesting requests and then jump to the real instruction 13277 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13278 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13279 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13280 * bail to the real handler if breakFlags==0. 13281 */ 13282 ldrb r3, [rSELF, #offThread_breakFlags] 13283 adrl lr, dvmAsmInstructionStart + (153 * 64) 13284 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13285 cmp r3, #0 13286 bxeq lr @ nothing to do - jump to real handler 13287 EXPORT_PC() 13288 mov r0, rPC @ arg0 13289 mov r1, rFP @ arg1 13290 mov r2, rSELF @ arg2 13291 b dvmCheckBefore @ (dPC,dFP,self) tail call 13292 13293 /* ------------------------------ */ 13294 .balign 64 13295 .L_ALT_OP_USHR_INT: /* 0x9a */ 13296 /* File: armv5te/alt_stub.S */ 13297 /* 13298 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13299 * any interesting requests and then jump to the real instruction 13300 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13301 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13302 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13303 * bail to the real handler if breakFlags==0. 13304 */ 13305 ldrb r3, [rSELF, #offThread_breakFlags] 13306 adrl lr, dvmAsmInstructionStart + (154 * 64) 13307 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13308 cmp r3, #0 13309 bxeq lr @ nothing to do - jump to real handler 13310 EXPORT_PC() 13311 mov r0, rPC @ arg0 13312 mov r1, rFP @ arg1 13313 mov r2, rSELF @ arg2 13314 b dvmCheckBefore @ (dPC,dFP,self) tail call 13315 13316 /* ------------------------------ */ 13317 .balign 64 13318 .L_ALT_OP_ADD_LONG: /* 0x9b */ 13319 /* File: armv5te/alt_stub.S */ 13320 /* 13321 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13322 * any interesting requests and then jump to the real instruction 13323 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13324 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13325 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13326 * bail to the real handler if breakFlags==0. 13327 */ 13328 ldrb r3, [rSELF, #offThread_breakFlags] 13329 adrl lr, dvmAsmInstructionStart + (155 * 64) 13330 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13331 cmp r3, #0 13332 bxeq lr @ nothing to do - jump to real handler 13333 EXPORT_PC() 13334 mov r0, rPC @ arg0 13335 mov r1, rFP @ arg1 13336 mov r2, rSELF @ arg2 13337 b dvmCheckBefore @ (dPC,dFP,self) tail call 13338 13339 /* ------------------------------ */ 13340 .balign 64 13341 .L_ALT_OP_SUB_LONG: /* 0x9c */ 13342 /* File: armv5te/alt_stub.S */ 13343 /* 13344 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13345 * any interesting requests and then jump to the real instruction 13346 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13347 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13348 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13349 * bail to the real handler if breakFlags==0. 13350 */ 13351 ldrb r3, [rSELF, #offThread_breakFlags] 13352 adrl lr, dvmAsmInstructionStart + (156 * 64) 13353 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13354 cmp r3, #0 13355 bxeq lr @ nothing to do - jump to real handler 13356 EXPORT_PC() 13357 mov r0, rPC @ arg0 13358 mov r1, rFP @ arg1 13359 mov r2, rSELF @ arg2 13360 b dvmCheckBefore @ (dPC,dFP,self) tail call 13361 13362 /* ------------------------------ */ 13363 .balign 64 13364 .L_ALT_OP_MUL_LONG: /* 0x9d */ 13365 /* File: armv5te/alt_stub.S */ 13366 /* 13367 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13368 * any interesting requests and then jump to the real instruction 13369 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13370 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13371 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13372 * bail to the real handler if breakFlags==0. 13373 */ 13374 ldrb r3, [rSELF, #offThread_breakFlags] 13375 adrl lr, dvmAsmInstructionStart + (157 * 64) 13376 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13377 cmp r3, #0 13378 bxeq lr @ nothing to do - jump to real handler 13379 EXPORT_PC() 13380 mov r0, rPC @ arg0 13381 mov r1, rFP @ arg1 13382 mov r2, rSELF @ arg2 13383 b dvmCheckBefore @ (dPC,dFP,self) tail call 13384 13385 /* ------------------------------ */ 13386 .balign 64 13387 .L_ALT_OP_DIV_LONG: /* 0x9e */ 13388 /* File: armv5te/alt_stub.S */ 13389 /* 13390 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13391 * any interesting requests and then jump to the real instruction 13392 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13393 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13394 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13395 * bail to the real handler if breakFlags==0. 13396 */ 13397 ldrb r3, [rSELF, #offThread_breakFlags] 13398 adrl lr, dvmAsmInstructionStart + (158 * 64) 13399 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13400 cmp r3, #0 13401 bxeq lr @ nothing to do - jump to real handler 13402 EXPORT_PC() 13403 mov r0, rPC @ arg0 13404 mov r1, rFP @ arg1 13405 mov r2, rSELF @ arg2 13406 b dvmCheckBefore @ (dPC,dFP,self) tail call 13407 13408 /* ------------------------------ */ 13409 .balign 64 13410 .L_ALT_OP_REM_LONG: /* 0x9f */ 13411 /* File: armv5te/alt_stub.S */ 13412 /* 13413 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13414 * any interesting requests and then jump to the real instruction 13415 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13416 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13417 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13418 * bail to the real handler if breakFlags==0. 13419 */ 13420 ldrb r3, [rSELF, #offThread_breakFlags] 13421 adrl lr, dvmAsmInstructionStart + (159 * 64) 13422 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13423 cmp r3, #0 13424 bxeq lr @ nothing to do - jump to real handler 13425 EXPORT_PC() 13426 mov r0, rPC @ arg0 13427 mov r1, rFP @ arg1 13428 mov r2, rSELF @ arg2 13429 b dvmCheckBefore @ (dPC,dFP,self) tail call 13430 13431 /* ------------------------------ */ 13432 .balign 64 13433 .L_ALT_OP_AND_LONG: /* 0xa0 */ 13434 /* File: armv5te/alt_stub.S */ 13435 /* 13436 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13437 * any interesting requests and then jump to the real instruction 13438 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13439 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13440 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13441 * bail to the real handler if breakFlags==0. 13442 */ 13443 ldrb r3, [rSELF, #offThread_breakFlags] 13444 adrl lr, dvmAsmInstructionStart + (160 * 64) 13445 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13446 cmp r3, #0 13447 bxeq lr @ nothing to do - jump to real handler 13448 EXPORT_PC() 13449 mov r0, rPC @ arg0 13450 mov r1, rFP @ arg1 13451 mov r2, rSELF @ arg2 13452 b dvmCheckBefore @ (dPC,dFP,self) tail call 13453 13454 /* ------------------------------ */ 13455 .balign 64 13456 .L_ALT_OP_OR_LONG: /* 0xa1 */ 13457 /* File: armv5te/alt_stub.S */ 13458 /* 13459 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13460 * any interesting requests and then jump to the real instruction 13461 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13462 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13463 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13464 * bail to the real handler if breakFlags==0. 13465 */ 13466 ldrb r3, [rSELF, #offThread_breakFlags] 13467 adrl lr, dvmAsmInstructionStart + (161 * 64) 13468 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13469 cmp r3, #0 13470 bxeq lr @ nothing to do - jump to real handler 13471 EXPORT_PC() 13472 mov r0, rPC @ arg0 13473 mov r1, rFP @ arg1 13474 mov r2, rSELF @ arg2 13475 b dvmCheckBefore @ (dPC,dFP,self) tail call 13476 13477 /* ------------------------------ */ 13478 .balign 64 13479 .L_ALT_OP_XOR_LONG: /* 0xa2 */ 13480 /* File: armv5te/alt_stub.S */ 13481 /* 13482 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13483 * any interesting requests and then jump to the real instruction 13484 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13485 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13486 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13487 * bail to the real handler if breakFlags==0. 13488 */ 13489 ldrb r3, [rSELF, #offThread_breakFlags] 13490 adrl lr, dvmAsmInstructionStart + (162 * 64) 13491 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13492 cmp r3, #0 13493 bxeq lr @ nothing to do - jump to real handler 13494 EXPORT_PC() 13495 mov r0, rPC @ arg0 13496 mov r1, rFP @ arg1 13497 mov r2, rSELF @ arg2 13498 b dvmCheckBefore @ (dPC,dFP,self) tail call 13499 13500 /* ------------------------------ */ 13501 .balign 64 13502 .L_ALT_OP_SHL_LONG: /* 0xa3 */ 13503 /* File: armv5te/alt_stub.S */ 13504 /* 13505 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13506 * any interesting requests and then jump to the real instruction 13507 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13508 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13509 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13510 * bail to the real handler if breakFlags==0. 13511 */ 13512 ldrb r3, [rSELF, #offThread_breakFlags] 13513 adrl lr, dvmAsmInstructionStart + (163 * 64) 13514 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13515 cmp r3, #0 13516 bxeq lr @ nothing to do - jump to real handler 13517 EXPORT_PC() 13518 mov r0, rPC @ arg0 13519 mov r1, rFP @ arg1 13520 mov r2, rSELF @ arg2 13521 b dvmCheckBefore @ (dPC,dFP,self) tail call 13522 13523 /* ------------------------------ */ 13524 .balign 64 13525 .L_ALT_OP_SHR_LONG: /* 0xa4 */ 13526 /* File: armv5te/alt_stub.S */ 13527 /* 13528 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13529 * any interesting requests and then jump to the real instruction 13530 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13531 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13532 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13533 * bail to the real handler if breakFlags==0. 13534 */ 13535 ldrb r3, [rSELF, #offThread_breakFlags] 13536 adrl lr, dvmAsmInstructionStart + (164 * 64) 13537 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13538 cmp r3, #0 13539 bxeq lr @ nothing to do - jump to real handler 13540 EXPORT_PC() 13541 mov r0, rPC @ arg0 13542 mov r1, rFP @ arg1 13543 mov r2, rSELF @ arg2 13544 b dvmCheckBefore @ (dPC,dFP,self) tail call 13545 13546 /* ------------------------------ */ 13547 .balign 64 13548 .L_ALT_OP_USHR_LONG: /* 0xa5 */ 13549 /* File: armv5te/alt_stub.S */ 13550 /* 13551 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13552 * any interesting requests and then jump to the real instruction 13553 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13554 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13555 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13556 * bail to the real handler if breakFlags==0. 13557 */ 13558 ldrb r3, [rSELF, #offThread_breakFlags] 13559 adrl lr, dvmAsmInstructionStart + (165 * 64) 13560 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13561 cmp r3, #0 13562 bxeq lr @ nothing to do - jump to real handler 13563 EXPORT_PC() 13564 mov r0, rPC @ arg0 13565 mov r1, rFP @ arg1 13566 mov r2, rSELF @ arg2 13567 b dvmCheckBefore @ (dPC,dFP,self) tail call 13568 13569 /* ------------------------------ */ 13570 .balign 64 13571 .L_ALT_OP_ADD_FLOAT: /* 0xa6 */ 13572 /* File: armv5te/alt_stub.S */ 13573 /* 13574 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13575 * any interesting requests and then jump to the real instruction 13576 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13577 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13578 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13579 * bail to the real handler if breakFlags==0. 13580 */ 13581 ldrb r3, [rSELF, #offThread_breakFlags] 13582 adrl lr, dvmAsmInstructionStart + (166 * 64) 13583 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13584 cmp r3, #0 13585 bxeq lr @ nothing to do - jump to real handler 13586 EXPORT_PC() 13587 mov r0, rPC @ arg0 13588 mov r1, rFP @ arg1 13589 mov r2, rSELF @ arg2 13590 b dvmCheckBefore @ (dPC,dFP,self) tail call 13591 13592 /* ------------------------------ */ 13593 .balign 64 13594 .L_ALT_OP_SUB_FLOAT: /* 0xa7 */ 13595 /* File: armv5te/alt_stub.S */ 13596 /* 13597 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13598 * any interesting requests and then jump to the real instruction 13599 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13600 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13601 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13602 * bail to the real handler if breakFlags==0. 13603 */ 13604 ldrb r3, [rSELF, #offThread_breakFlags] 13605 adrl lr, dvmAsmInstructionStart + (167 * 64) 13606 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13607 cmp r3, #0 13608 bxeq lr @ nothing to do - jump to real handler 13609 EXPORT_PC() 13610 mov r0, rPC @ arg0 13611 mov r1, rFP @ arg1 13612 mov r2, rSELF @ arg2 13613 b dvmCheckBefore @ (dPC,dFP,self) tail call 13614 13615 /* ------------------------------ */ 13616 .balign 64 13617 .L_ALT_OP_MUL_FLOAT: /* 0xa8 */ 13618 /* File: armv5te/alt_stub.S */ 13619 /* 13620 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13621 * any interesting requests and then jump to the real instruction 13622 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13623 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13624 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13625 * bail to the real handler if breakFlags==0. 13626 */ 13627 ldrb r3, [rSELF, #offThread_breakFlags] 13628 adrl lr, dvmAsmInstructionStart + (168 * 64) 13629 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13630 cmp r3, #0 13631 bxeq lr @ nothing to do - jump to real handler 13632 EXPORT_PC() 13633 mov r0, rPC @ arg0 13634 mov r1, rFP @ arg1 13635 mov r2, rSELF @ arg2 13636 b dvmCheckBefore @ (dPC,dFP,self) tail call 13637 13638 /* ------------------------------ */ 13639 .balign 64 13640 .L_ALT_OP_DIV_FLOAT: /* 0xa9 */ 13641 /* File: armv5te/alt_stub.S */ 13642 /* 13643 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13644 * any interesting requests and then jump to the real instruction 13645 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13646 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13647 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13648 * bail to the real handler if breakFlags==0. 13649 */ 13650 ldrb r3, [rSELF, #offThread_breakFlags] 13651 adrl lr, dvmAsmInstructionStart + (169 * 64) 13652 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13653 cmp r3, #0 13654 bxeq lr @ nothing to do - jump to real handler 13655 EXPORT_PC() 13656 mov r0, rPC @ arg0 13657 mov r1, rFP @ arg1 13658 mov r2, rSELF @ arg2 13659 b dvmCheckBefore @ (dPC,dFP,self) tail call 13660 13661 /* ------------------------------ */ 13662 .balign 64 13663 .L_ALT_OP_REM_FLOAT: /* 0xaa */ 13664 /* File: armv5te/alt_stub.S */ 13665 /* 13666 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13667 * any interesting requests and then jump to the real instruction 13668 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13669 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13670 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13671 * bail to the real handler if breakFlags==0. 13672 */ 13673 ldrb r3, [rSELF, #offThread_breakFlags] 13674 adrl lr, dvmAsmInstructionStart + (170 * 64) 13675 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13676 cmp r3, #0 13677 bxeq lr @ nothing to do - jump to real handler 13678 EXPORT_PC() 13679 mov r0, rPC @ arg0 13680 mov r1, rFP @ arg1 13681 mov r2, rSELF @ arg2 13682 b dvmCheckBefore @ (dPC,dFP,self) tail call 13683 13684 /* ------------------------------ */ 13685 .balign 64 13686 .L_ALT_OP_ADD_DOUBLE: /* 0xab */ 13687 /* File: armv5te/alt_stub.S */ 13688 /* 13689 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13690 * any interesting requests and then jump to the real instruction 13691 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13692 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13693 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13694 * bail to the real handler if breakFlags==0. 13695 */ 13696 ldrb r3, [rSELF, #offThread_breakFlags] 13697 adrl lr, dvmAsmInstructionStart + (171 * 64) 13698 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13699 cmp r3, #0 13700 bxeq lr @ nothing to do - jump to real handler 13701 EXPORT_PC() 13702 mov r0, rPC @ arg0 13703 mov r1, rFP @ arg1 13704 mov r2, rSELF @ arg2 13705 b dvmCheckBefore @ (dPC,dFP,self) tail call 13706 13707 /* ------------------------------ */ 13708 .balign 64 13709 .L_ALT_OP_SUB_DOUBLE: /* 0xac */ 13710 /* File: armv5te/alt_stub.S */ 13711 /* 13712 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13713 * any interesting requests and then jump to the real instruction 13714 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13715 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13716 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13717 * bail to the real handler if breakFlags==0. 13718 */ 13719 ldrb r3, [rSELF, #offThread_breakFlags] 13720 adrl lr, dvmAsmInstructionStart + (172 * 64) 13721 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13722 cmp r3, #0 13723 bxeq lr @ nothing to do - jump to real handler 13724 EXPORT_PC() 13725 mov r0, rPC @ arg0 13726 mov r1, rFP @ arg1 13727 mov r2, rSELF @ arg2 13728 b dvmCheckBefore @ (dPC,dFP,self) tail call 13729 13730 /* ------------------------------ */ 13731 .balign 64 13732 .L_ALT_OP_MUL_DOUBLE: /* 0xad */ 13733 /* File: armv5te/alt_stub.S */ 13734 /* 13735 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13736 * any interesting requests and then jump to the real instruction 13737 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13738 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13739 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13740 * bail to the real handler if breakFlags==0. 13741 */ 13742 ldrb r3, [rSELF, #offThread_breakFlags] 13743 adrl lr, dvmAsmInstructionStart + (173 * 64) 13744 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13745 cmp r3, #0 13746 bxeq lr @ nothing to do - jump to real handler 13747 EXPORT_PC() 13748 mov r0, rPC @ arg0 13749 mov r1, rFP @ arg1 13750 mov r2, rSELF @ arg2 13751 b dvmCheckBefore @ (dPC,dFP,self) tail call 13752 13753 /* ------------------------------ */ 13754 .balign 64 13755 .L_ALT_OP_DIV_DOUBLE: /* 0xae */ 13756 /* File: armv5te/alt_stub.S */ 13757 /* 13758 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13759 * any interesting requests and then jump to the real instruction 13760 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13761 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13762 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13763 * bail to the real handler if breakFlags==0. 13764 */ 13765 ldrb r3, [rSELF, #offThread_breakFlags] 13766 adrl lr, dvmAsmInstructionStart + (174 * 64) 13767 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13768 cmp r3, #0 13769 bxeq lr @ nothing to do - jump to real handler 13770 EXPORT_PC() 13771 mov r0, rPC @ arg0 13772 mov r1, rFP @ arg1 13773 mov r2, rSELF @ arg2 13774 b dvmCheckBefore @ (dPC,dFP,self) tail call 13775 13776 /* ------------------------------ */ 13777 .balign 64 13778 .L_ALT_OP_REM_DOUBLE: /* 0xaf */ 13779 /* File: armv5te/alt_stub.S */ 13780 /* 13781 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13782 * any interesting requests and then jump to the real instruction 13783 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13784 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13785 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13786 * bail to the real handler if breakFlags==0. 13787 */ 13788 ldrb r3, [rSELF, #offThread_breakFlags] 13789 adrl lr, dvmAsmInstructionStart + (175 * 64) 13790 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13791 cmp r3, #0 13792 bxeq lr @ nothing to do - jump to real handler 13793 EXPORT_PC() 13794 mov r0, rPC @ arg0 13795 mov r1, rFP @ arg1 13796 mov r2, rSELF @ arg2 13797 b dvmCheckBefore @ (dPC,dFP,self) tail call 13798 13799 /* ------------------------------ */ 13800 .balign 64 13801 .L_ALT_OP_ADD_INT_2ADDR: /* 0xb0 */ 13802 /* File: armv5te/alt_stub.S */ 13803 /* 13804 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13805 * any interesting requests and then jump to the real instruction 13806 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13807 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13808 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13809 * bail to the real handler if breakFlags==0. 13810 */ 13811 ldrb r3, [rSELF, #offThread_breakFlags] 13812 adrl lr, dvmAsmInstructionStart + (176 * 64) 13813 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13814 cmp r3, #0 13815 bxeq lr @ nothing to do - jump to real handler 13816 EXPORT_PC() 13817 mov r0, rPC @ arg0 13818 mov r1, rFP @ arg1 13819 mov r2, rSELF @ arg2 13820 b dvmCheckBefore @ (dPC,dFP,self) tail call 13821 13822 /* ------------------------------ */ 13823 .balign 64 13824 .L_ALT_OP_SUB_INT_2ADDR: /* 0xb1 */ 13825 /* File: armv5te/alt_stub.S */ 13826 /* 13827 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13828 * any interesting requests and then jump to the real instruction 13829 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13830 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13831 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13832 * bail to the real handler if breakFlags==0. 13833 */ 13834 ldrb r3, [rSELF, #offThread_breakFlags] 13835 adrl lr, dvmAsmInstructionStart + (177 * 64) 13836 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13837 cmp r3, #0 13838 bxeq lr @ nothing to do - jump to real handler 13839 EXPORT_PC() 13840 mov r0, rPC @ arg0 13841 mov r1, rFP @ arg1 13842 mov r2, rSELF @ arg2 13843 b dvmCheckBefore @ (dPC,dFP,self) tail call 13844 13845 /* ------------------------------ */ 13846 .balign 64 13847 .L_ALT_OP_MUL_INT_2ADDR: /* 0xb2 */ 13848 /* File: armv5te/alt_stub.S */ 13849 /* 13850 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13851 * any interesting requests and then jump to the real instruction 13852 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13853 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13854 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13855 * bail to the real handler if breakFlags==0. 13856 */ 13857 ldrb r3, [rSELF, #offThread_breakFlags] 13858 adrl lr, dvmAsmInstructionStart + (178 * 64) 13859 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13860 cmp r3, #0 13861 bxeq lr @ nothing to do - jump to real handler 13862 EXPORT_PC() 13863 mov r0, rPC @ arg0 13864 mov r1, rFP @ arg1 13865 mov r2, rSELF @ arg2 13866 b dvmCheckBefore @ (dPC,dFP,self) tail call 13867 13868 /* ------------------------------ */ 13869 .balign 64 13870 .L_ALT_OP_DIV_INT_2ADDR: /* 0xb3 */ 13871 /* File: armv5te/alt_stub.S */ 13872 /* 13873 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13874 * any interesting requests and then jump to the real instruction 13875 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13876 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13877 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13878 * bail to the real handler if breakFlags==0. 13879 */ 13880 ldrb r3, [rSELF, #offThread_breakFlags] 13881 adrl lr, dvmAsmInstructionStart + (179 * 64) 13882 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13883 cmp r3, #0 13884 bxeq lr @ nothing to do - jump to real handler 13885 EXPORT_PC() 13886 mov r0, rPC @ arg0 13887 mov r1, rFP @ arg1 13888 mov r2, rSELF @ arg2 13889 b dvmCheckBefore @ (dPC,dFP,self) tail call 13890 13891 /* ------------------------------ */ 13892 .balign 64 13893 .L_ALT_OP_REM_INT_2ADDR: /* 0xb4 */ 13894 /* File: armv5te/alt_stub.S */ 13895 /* 13896 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13897 * any interesting requests and then jump to the real instruction 13898 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13899 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13900 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13901 * bail to the real handler if breakFlags==0. 13902 */ 13903 ldrb r3, [rSELF, #offThread_breakFlags] 13904 adrl lr, dvmAsmInstructionStart + (180 * 64) 13905 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13906 cmp r3, #0 13907 bxeq lr @ nothing to do - jump to real handler 13908 EXPORT_PC() 13909 mov r0, rPC @ arg0 13910 mov r1, rFP @ arg1 13911 mov r2, rSELF @ arg2 13912 b dvmCheckBefore @ (dPC,dFP,self) tail call 13913 13914 /* ------------------------------ */ 13915 .balign 64 13916 .L_ALT_OP_AND_INT_2ADDR: /* 0xb5 */ 13917 /* File: armv5te/alt_stub.S */ 13918 /* 13919 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13920 * any interesting requests and then jump to the real instruction 13921 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13922 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13923 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13924 * bail to the real handler if breakFlags==0. 13925 */ 13926 ldrb r3, [rSELF, #offThread_breakFlags] 13927 adrl lr, dvmAsmInstructionStart + (181 * 64) 13928 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13929 cmp r3, #0 13930 bxeq lr @ nothing to do - jump to real handler 13931 EXPORT_PC() 13932 mov r0, rPC @ arg0 13933 mov r1, rFP @ arg1 13934 mov r2, rSELF @ arg2 13935 b dvmCheckBefore @ (dPC,dFP,self) tail call 13936 13937 /* ------------------------------ */ 13938 .balign 64 13939 .L_ALT_OP_OR_INT_2ADDR: /* 0xb6 */ 13940 /* File: armv5te/alt_stub.S */ 13941 /* 13942 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13943 * any interesting requests and then jump to the real instruction 13944 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13945 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13946 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13947 * bail to the real handler if breakFlags==0. 13948 */ 13949 ldrb r3, [rSELF, #offThread_breakFlags] 13950 adrl lr, dvmAsmInstructionStart + (182 * 64) 13951 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13952 cmp r3, #0 13953 bxeq lr @ nothing to do - jump to real handler 13954 EXPORT_PC() 13955 mov r0, rPC @ arg0 13956 mov r1, rFP @ arg1 13957 mov r2, rSELF @ arg2 13958 b dvmCheckBefore @ (dPC,dFP,self) tail call 13959 13960 /* ------------------------------ */ 13961 .balign 64 13962 .L_ALT_OP_XOR_INT_2ADDR: /* 0xb7 */ 13963 /* File: armv5te/alt_stub.S */ 13964 /* 13965 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13966 * any interesting requests and then jump to the real instruction 13967 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13968 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13969 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13970 * bail to the real handler if breakFlags==0. 13971 */ 13972 ldrb r3, [rSELF, #offThread_breakFlags] 13973 adrl lr, dvmAsmInstructionStart + (183 * 64) 13974 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13975 cmp r3, #0 13976 bxeq lr @ nothing to do - jump to real handler 13977 EXPORT_PC() 13978 mov r0, rPC @ arg0 13979 mov r1, rFP @ arg1 13980 mov r2, rSELF @ arg2 13981 b dvmCheckBefore @ (dPC,dFP,self) tail call 13982 13983 /* ------------------------------ */ 13984 .balign 64 13985 .L_ALT_OP_SHL_INT_2ADDR: /* 0xb8 */ 13986 /* File: armv5te/alt_stub.S */ 13987 /* 13988 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13989 * any interesting requests and then jump to the real instruction 13990 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13991 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13992 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13993 * bail to the real handler if breakFlags==0. 13994 */ 13995 ldrb r3, [rSELF, #offThread_breakFlags] 13996 adrl lr, dvmAsmInstructionStart + (184 * 64) 13997 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13998 cmp r3, #0 13999 bxeq lr @ nothing to do - jump to real handler 14000 EXPORT_PC() 14001 mov r0, rPC @ arg0 14002 mov r1, rFP @ arg1 14003 mov r2, rSELF @ arg2 14004 b dvmCheckBefore @ (dPC,dFP,self) tail call 14005 14006 /* ------------------------------ */ 14007 .balign 64 14008 .L_ALT_OP_SHR_INT_2ADDR: /* 0xb9 */ 14009 /* File: armv5te/alt_stub.S */ 14010 /* 14011 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14012 * any interesting requests and then jump to the real instruction 14013 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14014 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14015 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14016 * bail to the real handler if breakFlags==0. 14017 */ 14018 ldrb r3, [rSELF, #offThread_breakFlags] 14019 adrl lr, dvmAsmInstructionStart + (185 * 64) 14020 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14021 cmp r3, #0 14022 bxeq lr @ nothing to do - jump to real handler 14023 EXPORT_PC() 14024 mov r0, rPC @ arg0 14025 mov r1, rFP @ arg1 14026 mov r2, rSELF @ arg2 14027 b dvmCheckBefore @ (dPC,dFP,self) tail call 14028 14029 /* ------------------------------ */ 14030 .balign 64 14031 .L_ALT_OP_USHR_INT_2ADDR: /* 0xba */ 14032 /* File: armv5te/alt_stub.S */ 14033 /* 14034 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14035 * any interesting requests and then jump to the real instruction 14036 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14037 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14038 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14039 * bail to the real handler if breakFlags==0. 14040 */ 14041 ldrb r3, [rSELF, #offThread_breakFlags] 14042 adrl lr, dvmAsmInstructionStart + (186 * 64) 14043 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14044 cmp r3, #0 14045 bxeq lr @ nothing to do - jump to real handler 14046 EXPORT_PC() 14047 mov r0, rPC @ arg0 14048 mov r1, rFP @ arg1 14049 mov r2, rSELF @ arg2 14050 b dvmCheckBefore @ (dPC,dFP,self) tail call 14051 14052 /* ------------------------------ */ 14053 .balign 64 14054 .L_ALT_OP_ADD_LONG_2ADDR: /* 0xbb */ 14055 /* File: armv5te/alt_stub.S */ 14056 /* 14057 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14058 * any interesting requests and then jump to the real instruction 14059 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14060 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14061 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14062 * bail to the real handler if breakFlags==0. 14063 */ 14064 ldrb r3, [rSELF, #offThread_breakFlags] 14065 adrl lr, dvmAsmInstructionStart + (187 * 64) 14066 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14067 cmp r3, #0 14068 bxeq lr @ nothing to do - jump to real handler 14069 EXPORT_PC() 14070 mov r0, rPC @ arg0 14071 mov r1, rFP @ arg1 14072 mov r2, rSELF @ arg2 14073 b dvmCheckBefore @ (dPC,dFP,self) tail call 14074 14075 /* ------------------------------ */ 14076 .balign 64 14077 .L_ALT_OP_SUB_LONG_2ADDR: /* 0xbc */ 14078 /* File: armv5te/alt_stub.S */ 14079 /* 14080 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14081 * any interesting requests and then jump to the real instruction 14082 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14083 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14084 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14085 * bail to the real handler if breakFlags==0. 14086 */ 14087 ldrb r3, [rSELF, #offThread_breakFlags] 14088 adrl lr, dvmAsmInstructionStart + (188 * 64) 14089 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14090 cmp r3, #0 14091 bxeq lr @ nothing to do - jump to real handler 14092 EXPORT_PC() 14093 mov r0, rPC @ arg0 14094 mov r1, rFP @ arg1 14095 mov r2, rSELF @ arg2 14096 b dvmCheckBefore @ (dPC,dFP,self) tail call 14097 14098 /* ------------------------------ */ 14099 .balign 64 14100 .L_ALT_OP_MUL_LONG_2ADDR: /* 0xbd */ 14101 /* File: armv5te/alt_stub.S */ 14102 /* 14103 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14104 * any interesting requests and then jump to the real instruction 14105 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14106 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14107 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14108 * bail to the real handler if breakFlags==0. 14109 */ 14110 ldrb r3, [rSELF, #offThread_breakFlags] 14111 adrl lr, dvmAsmInstructionStart + (189 * 64) 14112 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14113 cmp r3, #0 14114 bxeq lr @ nothing to do - jump to real handler 14115 EXPORT_PC() 14116 mov r0, rPC @ arg0 14117 mov r1, rFP @ arg1 14118 mov r2, rSELF @ arg2 14119 b dvmCheckBefore @ (dPC,dFP,self) tail call 14120 14121 /* ------------------------------ */ 14122 .balign 64 14123 .L_ALT_OP_DIV_LONG_2ADDR: /* 0xbe */ 14124 /* File: armv5te/alt_stub.S */ 14125 /* 14126 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14127 * any interesting requests and then jump to the real instruction 14128 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14129 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14130 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14131 * bail to the real handler if breakFlags==0. 14132 */ 14133 ldrb r3, [rSELF, #offThread_breakFlags] 14134 adrl lr, dvmAsmInstructionStart + (190 * 64) 14135 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14136 cmp r3, #0 14137 bxeq lr @ nothing to do - jump to real handler 14138 EXPORT_PC() 14139 mov r0, rPC @ arg0 14140 mov r1, rFP @ arg1 14141 mov r2, rSELF @ arg2 14142 b dvmCheckBefore @ (dPC,dFP,self) tail call 14143 14144 /* ------------------------------ */ 14145 .balign 64 14146 .L_ALT_OP_REM_LONG_2ADDR: /* 0xbf */ 14147 /* File: armv5te/alt_stub.S */ 14148 /* 14149 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14150 * any interesting requests and then jump to the real instruction 14151 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14152 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14153 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14154 * bail to the real handler if breakFlags==0. 14155 */ 14156 ldrb r3, [rSELF, #offThread_breakFlags] 14157 adrl lr, dvmAsmInstructionStart + (191 * 64) 14158 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14159 cmp r3, #0 14160 bxeq lr @ nothing to do - jump to real handler 14161 EXPORT_PC() 14162 mov r0, rPC @ arg0 14163 mov r1, rFP @ arg1 14164 mov r2, rSELF @ arg2 14165 b dvmCheckBefore @ (dPC,dFP,self) tail call 14166 14167 /* ------------------------------ */ 14168 .balign 64 14169 .L_ALT_OP_AND_LONG_2ADDR: /* 0xc0 */ 14170 /* File: armv5te/alt_stub.S */ 14171 /* 14172 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14173 * any interesting requests and then jump to the real instruction 14174 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14175 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14176 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14177 * bail to the real handler if breakFlags==0. 14178 */ 14179 ldrb r3, [rSELF, #offThread_breakFlags] 14180 adrl lr, dvmAsmInstructionStart + (192 * 64) 14181 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14182 cmp r3, #0 14183 bxeq lr @ nothing to do - jump to real handler 14184 EXPORT_PC() 14185 mov r0, rPC @ arg0 14186 mov r1, rFP @ arg1 14187 mov r2, rSELF @ arg2 14188 b dvmCheckBefore @ (dPC,dFP,self) tail call 14189 14190 /* ------------------------------ */ 14191 .balign 64 14192 .L_ALT_OP_OR_LONG_2ADDR: /* 0xc1 */ 14193 /* File: armv5te/alt_stub.S */ 14194 /* 14195 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14196 * any interesting requests and then jump to the real instruction 14197 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14198 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14199 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14200 * bail to the real handler if breakFlags==0. 14201 */ 14202 ldrb r3, [rSELF, #offThread_breakFlags] 14203 adrl lr, dvmAsmInstructionStart + (193 * 64) 14204 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14205 cmp r3, #0 14206 bxeq lr @ nothing to do - jump to real handler 14207 EXPORT_PC() 14208 mov r0, rPC @ arg0 14209 mov r1, rFP @ arg1 14210 mov r2, rSELF @ arg2 14211 b dvmCheckBefore @ (dPC,dFP,self) tail call 14212 14213 /* ------------------------------ */ 14214 .balign 64 14215 .L_ALT_OP_XOR_LONG_2ADDR: /* 0xc2 */ 14216 /* File: armv5te/alt_stub.S */ 14217 /* 14218 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14219 * any interesting requests and then jump to the real instruction 14220 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14221 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14222 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14223 * bail to the real handler if breakFlags==0. 14224 */ 14225 ldrb r3, [rSELF, #offThread_breakFlags] 14226 adrl lr, dvmAsmInstructionStart + (194 * 64) 14227 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14228 cmp r3, #0 14229 bxeq lr @ nothing to do - jump to real handler 14230 EXPORT_PC() 14231 mov r0, rPC @ arg0 14232 mov r1, rFP @ arg1 14233 mov r2, rSELF @ arg2 14234 b dvmCheckBefore @ (dPC,dFP,self) tail call 14235 14236 /* ------------------------------ */ 14237 .balign 64 14238 .L_ALT_OP_SHL_LONG_2ADDR: /* 0xc3 */ 14239 /* File: armv5te/alt_stub.S */ 14240 /* 14241 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14242 * any interesting requests and then jump to the real instruction 14243 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14244 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14245 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14246 * bail to the real handler if breakFlags==0. 14247 */ 14248 ldrb r3, [rSELF, #offThread_breakFlags] 14249 adrl lr, dvmAsmInstructionStart + (195 * 64) 14250 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14251 cmp r3, #0 14252 bxeq lr @ nothing to do - jump to real handler 14253 EXPORT_PC() 14254 mov r0, rPC @ arg0 14255 mov r1, rFP @ arg1 14256 mov r2, rSELF @ arg2 14257 b dvmCheckBefore @ (dPC,dFP,self) tail call 14258 14259 /* ------------------------------ */ 14260 .balign 64 14261 .L_ALT_OP_SHR_LONG_2ADDR: /* 0xc4 */ 14262 /* File: armv5te/alt_stub.S */ 14263 /* 14264 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14265 * any interesting requests and then jump to the real instruction 14266 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14267 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14268 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14269 * bail to the real handler if breakFlags==0. 14270 */ 14271 ldrb r3, [rSELF, #offThread_breakFlags] 14272 adrl lr, dvmAsmInstructionStart + (196 * 64) 14273 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14274 cmp r3, #0 14275 bxeq lr @ nothing to do - jump to real handler 14276 EXPORT_PC() 14277 mov r0, rPC @ arg0 14278 mov r1, rFP @ arg1 14279 mov r2, rSELF @ arg2 14280 b dvmCheckBefore @ (dPC,dFP,self) tail call 14281 14282 /* ------------------------------ */ 14283 .balign 64 14284 .L_ALT_OP_USHR_LONG_2ADDR: /* 0xc5 */ 14285 /* File: armv5te/alt_stub.S */ 14286 /* 14287 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14288 * any interesting requests and then jump to the real instruction 14289 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14290 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14291 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14292 * bail to the real handler if breakFlags==0. 14293 */ 14294 ldrb r3, [rSELF, #offThread_breakFlags] 14295 adrl lr, dvmAsmInstructionStart + (197 * 64) 14296 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14297 cmp r3, #0 14298 bxeq lr @ nothing to do - jump to real handler 14299 EXPORT_PC() 14300 mov r0, rPC @ arg0 14301 mov r1, rFP @ arg1 14302 mov r2, rSELF @ arg2 14303 b dvmCheckBefore @ (dPC,dFP,self) tail call 14304 14305 /* ------------------------------ */ 14306 .balign 64 14307 .L_ALT_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 14308 /* File: armv5te/alt_stub.S */ 14309 /* 14310 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14311 * any interesting requests and then jump to the real instruction 14312 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14313 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14314 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14315 * bail to the real handler if breakFlags==0. 14316 */ 14317 ldrb r3, [rSELF, #offThread_breakFlags] 14318 adrl lr, dvmAsmInstructionStart + (198 * 64) 14319 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14320 cmp r3, #0 14321 bxeq lr @ nothing to do - jump to real handler 14322 EXPORT_PC() 14323 mov r0, rPC @ arg0 14324 mov r1, rFP @ arg1 14325 mov r2, rSELF @ arg2 14326 b dvmCheckBefore @ (dPC,dFP,self) tail call 14327 14328 /* ------------------------------ */ 14329 .balign 64 14330 .L_ALT_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 14331 /* File: armv5te/alt_stub.S */ 14332 /* 14333 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14334 * any interesting requests and then jump to the real instruction 14335 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14336 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14337 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14338 * bail to the real handler if breakFlags==0. 14339 */ 14340 ldrb r3, [rSELF, #offThread_breakFlags] 14341 adrl lr, dvmAsmInstructionStart + (199 * 64) 14342 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14343 cmp r3, #0 14344 bxeq lr @ nothing to do - jump to real handler 14345 EXPORT_PC() 14346 mov r0, rPC @ arg0 14347 mov r1, rFP @ arg1 14348 mov r2, rSELF @ arg2 14349 b dvmCheckBefore @ (dPC,dFP,self) tail call 14350 14351 /* ------------------------------ */ 14352 .balign 64 14353 .L_ALT_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 14354 /* File: armv5te/alt_stub.S */ 14355 /* 14356 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14357 * any interesting requests and then jump to the real instruction 14358 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14359 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14360 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14361 * bail to the real handler if breakFlags==0. 14362 */ 14363 ldrb r3, [rSELF, #offThread_breakFlags] 14364 adrl lr, dvmAsmInstructionStart + (200 * 64) 14365 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14366 cmp r3, #0 14367 bxeq lr @ nothing to do - jump to real handler 14368 EXPORT_PC() 14369 mov r0, rPC @ arg0 14370 mov r1, rFP @ arg1 14371 mov r2, rSELF @ arg2 14372 b dvmCheckBefore @ (dPC,dFP,self) tail call 14373 14374 /* ------------------------------ */ 14375 .balign 64 14376 .L_ALT_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 14377 /* File: armv5te/alt_stub.S */ 14378 /* 14379 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14380 * any interesting requests and then jump to the real instruction 14381 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14382 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14383 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14384 * bail to the real handler if breakFlags==0. 14385 */ 14386 ldrb r3, [rSELF, #offThread_breakFlags] 14387 adrl lr, dvmAsmInstructionStart + (201 * 64) 14388 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14389 cmp r3, #0 14390 bxeq lr @ nothing to do - jump to real handler 14391 EXPORT_PC() 14392 mov r0, rPC @ arg0 14393 mov r1, rFP @ arg1 14394 mov r2, rSELF @ arg2 14395 b dvmCheckBefore @ (dPC,dFP,self) tail call 14396 14397 /* ------------------------------ */ 14398 .balign 64 14399 .L_ALT_OP_REM_FLOAT_2ADDR: /* 0xca */ 14400 /* File: armv5te/alt_stub.S */ 14401 /* 14402 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14403 * any interesting requests and then jump to the real instruction 14404 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14405 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14406 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14407 * bail to the real handler if breakFlags==0. 14408 */ 14409 ldrb r3, [rSELF, #offThread_breakFlags] 14410 adrl lr, dvmAsmInstructionStart + (202 * 64) 14411 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14412 cmp r3, #0 14413 bxeq lr @ nothing to do - jump to real handler 14414 EXPORT_PC() 14415 mov r0, rPC @ arg0 14416 mov r1, rFP @ arg1 14417 mov r2, rSELF @ arg2 14418 b dvmCheckBefore @ (dPC,dFP,self) tail call 14419 14420 /* ------------------------------ */ 14421 .balign 64 14422 .L_ALT_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 14423 /* File: armv5te/alt_stub.S */ 14424 /* 14425 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14426 * any interesting requests and then jump to the real instruction 14427 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14428 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14429 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14430 * bail to the real handler if breakFlags==0. 14431 */ 14432 ldrb r3, [rSELF, #offThread_breakFlags] 14433 adrl lr, dvmAsmInstructionStart + (203 * 64) 14434 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14435 cmp r3, #0 14436 bxeq lr @ nothing to do - jump to real handler 14437 EXPORT_PC() 14438 mov r0, rPC @ arg0 14439 mov r1, rFP @ arg1 14440 mov r2, rSELF @ arg2 14441 b dvmCheckBefore @ (dPC,dFP,self) tail call 14442 14443 /* ------------------------------ */ 14444 .balign 64 14445 .L_ALT_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 14446 /* File: armv5te/alt_stub.S */ 14447 /* 14448 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14449 * any interesting requests and then jump to the real instruction 14450 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14451 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14452 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14453 * bail to the real handler if breakFlags==0. 14454 */ 14455 ldrb r3, [rSELF, #offThread_breakFlags] 14456 adrl lr, dvmAsmInstructionStart + (204 * 64) 14457 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14458 cmp r3, #0 14459 bxeq lr @ nothing to do - jump to real handler 14460 EXPORT_PC() 14461 mov r0, rPC @ arg0 14462 mov r1, rFP @ arg1 14463 mov r2, rSELF @ arg2 14464 b dvmCheckBefore @ (dPC,dFP,self) tail call 14465 14466 /* ------------------------------ */ 14467 .balign 64 14468 .L_ALT_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 14469 /* File: armv5te/alt_stub.S */ 14470 /* 14471 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14472 * any interesting requests and then jump to the real instruction 14473 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14474 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14475 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14476 * bail to the real handler if breakFlags==0. 14477 */ 14478 ldrb r3, [rSELF, #offThread_breakFlags] 14479 adrl lr, dvmAsmInstructionStart + (205 * 64) 14480 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14481 cmp r3, #0 14482 bxeq lr @ nothing to do - jump to real handler 14483 EXPORT_PC() 14484 mov r0, rPC @ arg0 14485 mov r1, rFP @ arg1 14486 mov r2, rSELF @ arg2 14487 b dvmCheckBefore @ (dPC,dFP,self) tail call 14488 14489 /* ------------------------------ */ 14490 .balign 64 14491 .L_ALT_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 14492 /* File: armv5te/alt_stub.S */ 14493 /* 14494 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14495 * any interesting requests and then jump to the real instruction 14496 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14497 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14498 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14499 * bail to the real handler if breakFlags==0. 14500 */ 14501 ldrb r3, [rSELF, #offThread_breakFlags] 14502 adrl lr, dvmAsmInstructionStart + (206 * 64) 14503 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14504 cmp r3, #0 14505 bxeq lr @ nothing to do - jump to real handler 14506 EXPORT_PC() 14507 mov r0, rPC @ arg0 14508 mov r1, rFP @ arg1 14509 mov r2, rSELF @ arg2 14510 b dvmCheckBefore @ (dPC,dFP,self) tail call 14511 14512 /* ------------------------------ */ 14513 .balign 64 14514 .L_ALT_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 14515 /* File: armv5te/alt_stub.S */ 14516 /* 14517 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14518 * any interesting requests and then jump to the real instruction 14519 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14520 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14521 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14522 * bail to the real handler if breakFlags==0. 14523 */ 14524 ldrb r3, [rSELF, #offThread_breakFlags] 14525 adrl lr, dvmAsmInstructionStart + (207 * 64) 14526 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14527 cmp r3, #0 14528 bxeq lr @ nothing to do - jump to real handler 14529 EXPORT_PC() 14530 mov r0, rPC @ arg0 14531 mov r1, rFP @ arg1 14532 mov r2, rSELF @ arg2 14533 b dvmCheckBefore @ (dPC,dFP,self) tail call 14534 14535 /* ------------------------------ */ 14536 .balign 64 14537 .L_ALT_OP_ADD_INT_LIT16: /* 0xd0 */ 14538 /* File: armv5te/alt_stub.S */ 14539 /* 14540 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14541 * any interesting requests and then jump to the real instruction 14542 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14543 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14544 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14545 * bail to the real handler if breakFlags==0. 14546 */ 14547 ldrb r3, [rSELF, #offThread_breakFlags] 14548 adrl lr, dvmAsmInstructionStart + (208 * 64) 14549 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14550 cmp r3, #0 14551 bxeq lr @ nothing to do - jump to real handler 14552 EXPORT_PC() 14553 mov r0, rPC @ arg0 14554 mov r1, rFP @ arg1 14555 mov r2, rSELF @ arg2 14556 b dvmCheckBefore @ (dPC,dFP,self) tail call 14557 14558 /* ------------------------------ */ 14559 .balign 64 14560 .L_ALT_OP_RSUB_INT: /* 0xd1 */ 14561 /* File: armv5te/alt_stub.S */ 14562 /* 14563 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14564 * any interesting requests and then jump to the real instruction 14565 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14566 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14567 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14568 * bail to the real handler if breakFlags==0. 14569 */ 14570 ldrb r3, [rSELF, #offThread_breakFlags] 14571 adrl lr, dvmAsmInstructionStart + (209 * 64) 14572 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14573 cmp r3, #0 14574 bxeq lr @ nothing to do - jump to real handler 14575 EXPORT_PC() 14576 mov r0, rPC @ arg0 14577 mov r1, rFP @ arg1 14578 mov r2, rSELF @ arg2 14579 b dvmCheckBefore @ (dPC,dFP,self) tail call 14580 14581 /* ------------------------------ */ 14582 .balign 64 14583 .L_ALT_OP_MUL_INT_LIT16: /* 0xd2 */ 14584 /* File: armv5te/alt_stub.S */ 14585 /* 14586 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14587 * any interesting requests and then jump to the real instruction 14588 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14589 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14590 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14591 * bail to the real handler if breakFlags==0. 14592 */ 14593 ldrb r3, [rSELF, #offThread_breakFlags] 14594 adrl lr, dvmAsmInstructionStart + (210 * 64) 14595 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14596 cmp r3, #0 14597 bxeq lr @ nothing to do - jump to real handler 14598 EXPORT_PC() 14599 mov r0, rPC @ arg0 14600 mov r1, rFP @ arg1 14601 mov r2, rSELF @ arg2 14602 b dvmCheckBefore @ (dPC,dFP,self) tail call 14603 14604 /* ------------------------------ */ 14605 .balign 64 14606 .L_ALT_OP_DIV_INT_LIT16: /* 0xd3 */ 14607 /* File: armv5te/alt_stub.S */ 14608 /* 14609 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14610 * any interesting requests and then jump to the real instruction 14611 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14612 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14613 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14614 * bail to the real handler if breakFlags==0. 14615 */ 14616 ldrb r3, [rSELF, #offThread_breakFlags] 14617 adrl lr, dvmAsmInstructionStart + (211 * 64) 14618 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14619 cmp r3, #0 14620 bxeq lr @ nothing to do - jump to real handler 14621 EXPORT_PC() 14622 mov r0, rPC @ arg0 14623 mov r1, rFP @ arg1 14624 mov r2, rSELF @ arg2 14625 b dvmCheckBefore @ (dPC,dFP,self) tail call 14626 14627 /* ------------------------------ */ 14628 .balign 64 14629 .L_ALT_OP_REM_INT_LIT16: /* 0xd4 */ 14630 /* File: armv5te/alt_stub.S */ 14631 /* 14632 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14633 * any interesting requests and then jump to the real instruction 14634 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14635 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14636 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14637 * bail to the real handler if breakFlags==0. 14638 */ 14639 ldrb r3, [rSELF, #offThread_breakFlags] 14640 adrl lr, dvmAsmInstructionStart + (212 * 64) 14641 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14642 cmp r3, #0 14643 bxeq lr @ nothing to do - jump to real handler 14644 EXPORT_PC() 14645 mov r0, rPC @ arg0 14646 mov r1, rFP @ arg1 14647 mov r2, rSELF @ arg2 14648 b dvmCheckBefore @ (dPC,dFP,self) tail call 14649 14650 /* ------------------------------ */ 14651 .balign 64 14652 .L_ALT_OP_AND_INT_LIT16: /* 0xd5 */ 14653 /* File: armv5te/alt_stub.S */ 14654 /* 14655 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14656 * any interesting requests and then jump to the real instruction 14657 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14658 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14659 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14660 * bail to the real handler if breakFlags==0. 14661 */ 14662 ldrb r3, [rSELF, #offThread_breakFlags] 14663 adrl lr, dvmAsmInstructionStart + (213 * 64) 14664 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14665 cmp r3, #0 14666 bxeq lr @ nothing to do - jump to real handler 14667 EXPORT_PC() 14668 mov r0, rPC @ arg0 14669 mov r1, rFP @ arg1 14670 mov r2, rSELF @ arg2 14671 b dvmCheckBefore @ (dPC,dFP,self) tail call 14672 14673 /* ------------------------------ */ 14674 .balign 64 14675 .L_ALT_OP_OR_INT_LIT16: /* 0xd6 */ 14676 /* File: armv5te/alt_stub.S */ 14677 /* 14678 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14679 * any interesting requests and then jump to the real instruction 14680 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14681 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14682 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14683 * bail to the real handler if breakFlags==0. 14684 */ 14685 ldrb r3, [rSELF, #offThread_breakFlags] 14686 adrl lr, dvmAsmInstructionStart + (214 * 64) 14687 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14688 cmp r3, #0 14689 bxeq lr @ nothing to do - jump to real handler 14690 EXPORT_PC() 14691 mov r0, rPC @ arg0 14692 mov r1, rFP @ arg1 14693 mov r2, rSELF @ arg2 14694 b dvmCheckBefore @ (dPC,dFP,self) tail call 14695 14696 /* ------------------------------ */ 14697 .balign 64 14698 .L_ALT_OP_XOR_INT_LIT16: /* 0xd7 */ 14699 /* File: armv5te/alt_stub.S */ 14700 /* 14701 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14702 * any interesting requests and then jump to the real instruction 14703 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14704 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14705 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14706 * bail to the real handler if breakFlags==0. 14707 */ 14708 ldrb r3, [rSELF, #offThread_breakFlags] 14709 adrl lr, dvmAsmInstructionStart + (215 * 64) 14710 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14711 cmp r3, #0 14712 bxeq lr @ nothing to do - jump to real handler 14713 EXPORT_PC() 14714 mov r0, rPC @ arg0 14715 mov r1, rFP @ arg1 14716 mov r2, rSELF @ arg2 14717 b dvmCheckBefore @ (dPC,dFP,self) tail call 14718 14719 /* ------------------------------ */ 14720 .balign 64 14721 .L_ALT_OP_ADD_INT_LIT8: /* 0xd8 */ 14722 /* File: armv5te/alt_stub.S */ 14723 /* 14724 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14725 * any interesting requests and then jump to the real instruction 14726 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14727 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14728 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14729 * bail to the real handler if breakFlags==0. 14730 */ 14731 ldrb r3, [rSELF, #offThread_breakFlags] 14732 adrl lr, dvmAsmInstructionStart + (216 * 64) 14733 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14734 cmp r3, #0 14735 bxeq lr @ nothing to do - jump to real handler 14736 EXPORT_PC() 14737 mov r0, rPC @ arg0 14738 mov r1, rFP @ arg1 14739 mov r2, rSELF @ arg2 14740 b dvmCheckBefore @ (dPC,dFP,self) tail call 14741 14742 /* ------------------------------ */ 14743 .balign 64 14744 .L_ALT_OP_RSUB_INT_LIT8: /* 0xd9 */ 14745 /* File: armv5te/alt_stub.S */ 14746 /* 14747 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14748 * any interesting requests and then jump to the real instruction 14749 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14750 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14751 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14752 * bail to the real handler if breakFlags==0. 14753 */ 14754 ldrb r3, [rSELF, #offThread_breakFlags] 14755 adrl lr, dvmAsmInstructionStart + (217 * 64) 14756 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14757 cmp r3, #0 14758 bxeq lr @ nothing to do - jump to real handler 14759 EXPORT_PC() 14760 mov r0, rPC @ arg0 14761 mov r1, rFP @ arg1 14762 mov r2, rSELF @ arg2 14763 b dvmCheckBefore @ (dPC,dFP,self) tail call 14764 14765 /* ------------------------------ */ 14766 .balign 64 14767 .L_ALT_OP_MUL_INT_LIT8: /* 0xda */ 14768 /* File: armv5te/alt_stub.S */ 14769 /* 14770 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14771 * any interesting requests and then jump to the real instruction 14772 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14773 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14774 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14775 * bail to the real handler if breakFlags==0. 14776 */ 14777 ldrb r3, [rSELF, #offThread_breakFlags] 14778 adrl lr, dvmAsmInstructionStart + (218 * 64) 14779 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14780 cmp r3, #0 14781 bxeq lr @ nothing to do - jump to real handler 14782 EXPORT_PC() 14783 mov r0, rPC @ arg0 14784 mov r1, rFP @ arg1 14785 mov r2, rSELF @ arg2 14786 b dvmCheckBefore @ (dPC,dFP,self) tail call 14787 14788 /* ------------------------------ */ 14789 .balign 64 14790 .L_ALT_OP_DIV_INT_LIT8: /* 0xdb */ 14791 /* File: armv5te/alt_stub.S */ 14792 /* 14793 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14794 * any interesting requests and then jump to the real instruction 14795 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14796 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14797 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14798 * bail to the real handler if breakFlags==0. 14799 */ 14800 ldrb r3, [rSELF, #offThread_breakFlags] 14801 adrl lr, dvmAsmInstructionStart + (219 * 64) 14802 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14803 cmp r3, #0 14804 bxeq lr @ nothing to do - jump to real handler 14805 EXPORT_PC() 14806 mov r0, rPC @ arg0 14807 mov r1, rFP @ arg1 14808 mov r2, rSELF @ arg2 14809 b dvmCheckBefore @ (dPC,dFP,self) tail call 14810 14811 /* ------------------------------ */ 14812 .balign 64 14813 .L_ALT_OP_REM_INT_LIT8: /* 0xdc */ 14814 /* File: armv5te/alt_stub.S */ 14815 /* 14816 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14817 * any interesting requests and then jump to the real instruction 14818 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14819 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14820 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14821 * bail to the real handler if breakFlags==0. 14822 */ 14823 ldrb r3, [rSELF, #offThread_breakFlags] 14824 adrl lr, dvmAsmInstructionStart + (220 * 64) 14825 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14826 cmp r3, #0 14827 bxeq lr @ nothing to do - jump to real handler 14828 EXPORT_PC() 14829 mov r0, rPC @ arg0 14830 mov r1, rFP @ arg1 14831 mov r2, rSELF @ arg2 14832 b dvmCheckBefore @ (dPC,dFP,self) tail call 14833 14834 /* ------------------------------ */ 14835 .balign 64 14836 .L_ALT_OP_AND_INT_LIT8: /* 0xdd */ 14837 /* File: armv5te/alt_stub.S */ 14838 /* 14839 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14840 * any interesting requests and then jump to the real instruction 14841 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14842 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14843 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14844 * bail to the real handler if breakFlags==0. 14845 */ 14846 ldrb r3, [rSELF, #offThread_breakFlags] 14847 adrl lr, dvmAsmInstructionStart + (221 * 64) 14848 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14849 cmp r3, #0 14850 bxeq lr @ nothing to do - jump to real handler 14851 EXPORT_PC() 14852 mov r0, rPC @ arg0 14853 mov r1, rFP @ arg1 14854 mov r2, rSELF @ arg2 14855 b dvmCheckBefore @ (dPC,dFP,self) tail call 14856 14857 /* ------------------------------ */ 14858 .balign 64 14859 .L_ALT_OP_OR_INT_LIT8: /* 0xde */ 14860 /* File: armv5te/alt_stub.S */ 14861 /* 14862 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14863 * any interesting requests and then jump to the real instruction 14864 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14865 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14866 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14867 * bail to the real handler if breakFlags==0. 14868 */ 14869 ldrb r3, [rSELF, #offThread_breakFlags] 14870 adrl lr, dvmAsmInstructionStart + (222 * 64) 14871 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14872 cmp r3, #0 14873 bxeq lr @ nothing to do - jump to real handler 14874 EXPORT_PC() 14875 mov r0, rPC @ arg0 14876 mov r1, rFP @ arg1 14877 mov r2, rSELF @ arg2 14878 b dvmCheckBefore @ (dPC,dFP,self) tail call 14879 14880 /* ------------------------------ */ 14881 .balign 64 14882 .L_ALT_OP_XOR_INT_LIT8: /* 0xdf */ 14883 /* File: armv5te/alt_stub.S */ 14884 /* 14885 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14886 * any interesting requests and then jump to the real instruction 14887 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14888 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14889 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14890 * bail to the real handler if breakFlags==0. 14891 */ 14892 ldrb r3, [rSELF, #offThread_breakFlags] 14893 adrl lr, dvmAsmInstructionStart + (223 * 64) 14894 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14895 cmp r3, #0 14896 bxeq lr @ nothing to do - jump to real handler 14897 EXPORT_PC() 14898 mov r0, rPC @ arg0 14899 mov r1, rFP @ arg1 14900 mov r2, rSELF @ arg2 14901 b dvmCheckBefore @ (dPC,dFP,self) tail call 14902 14903 /* ------------------------------ */ 14904 .balign 64 14905 .L_ALT_OP_SHL_INT_LIT8: /* 0xe0 */ 14906 /* File: armv5te/alt_stub.S */ 14907 /* 14908 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14909 * any interesting requests and then jump to the real instruction 14910 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14911 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14912 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14913 * bail to the real handler if breakFlags==0. 14914 */ 14915 ldrb r3, [rSELF, #offThread_breakFlags] 14916 adrl lr, dvmAsmInstructionStart + (224 * 64) 14917 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14918 cmp r3, #0 14919 bxeq lr @ nothing to do - jump to real handler 14920 EXPORT_PC() 14921 mov r0, rPC @ arg0 14922 mov r1, rFP @ arg1 14923 mov r2, rSELF @ arg2 14924 b dvmCheckBefore @ (dPC,dFP,self) tail call 14925 14926 /* ------------------------------ */ 14927 .balign 64 14928 .L_ALT_OP_SHR_INT_LIT8: /* 0xe1 */ 14929 /* File: armv5te/alt_stub.S */ 14930 /* 14931 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14932 * any interesting requests and then jump to the real instruction 14933 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14934 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14935 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14936 * bail to the real handler if breakFlags==0. 14937 */ 14938 ldrb r3, [rSELF, #offThread_breakFlags] 14939 adrl lr, dvmAsmInstructionStart + (225 * 64) 14940 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14941 cmp r3, #0 14942 bxeq lr @ nothing to do - jump to real handler 14943 EXPORT_PC() 14944 mov r0, rPC @ arg0 14945 mov r1, rFP @ arg1 14946 mov r2, rSELF @ arg2 14947 b dvmCheckBefore @ (dPC,dFP,self) tail call 14948 14949 /* ------------------------------ */ 14950 .balign 64 14951 .L_ALT_OP_USHR_INT_LIT8: /* 0xe2 */ 14952 /* File: armv5te/alt_stub.S */ 14953 /* 14954 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14955 * any interesting requests and then jump to the real instruction 14956 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14957 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14958 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14959 * bail to the real handler if breakFlags==0. 14960 */ 14961 ldrb r3, [rSELF, #offThread_breakFlags] 14962 adrl lr, dvmAsmInstructionStart + (226 * 64) 14963 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14964 cmp r3, #0 14965 bxeq lr @ nothing to do - jump to real handler 14966 EXPORT_PC() 14967 mov r0, rPC @ arg0 14968 mov r1, rFP @ arg1 14969 mov r2, rSELF @ arg2 14970 b dvmCheckBefore @ (dPC,dFP,self) tail call 14971 14972 /* ------------------------------ */ 14973 .balign 64 14974 .L_ALT_OP_IGET_VOLATILE: /* 0xe3 */ 14975 /* File: armv5te/alt_stub.S */ 14976 /* 14977 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14978 * any interesting requests and then jump to the real instruction 14979 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14980 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14981 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14982 * bail to the real handler if breakFlags==0. 14983 */ 14984 ldrb r3, [rSELF, #offThread_breakFlags] 14985 adrl lr, dvmAsmInstructionStart + (227 * 64) 14986 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14987 cmp r3, #0 14988 bxeq lr @ nothing to do - jump to real handler 14989 EXPORT_PC() 14990 mov r0, rPC @ arg0 14991 mov r1, rFP @ arg1 14992 mov r2, rSELF @ arg2 14993 b dvmCheckBefore @ (dPC,dFP,self) tail call 14994 14995 /* ------------------------------ */ 14996 .balign 64 14997 .L_ALT_OP_IPUT_VOLATILE: /* 0xe4 */ 14998 /* File: armv5te/alt_stub.S */ 14999 /* 15000 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15001 * any interesting requests and then jump to the real instruction 15002 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15003 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15004 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15005 * bail to the real handler if breakFlags==0. 15006 */ 15007 ldrb r3, [rSELF, #offThread_breakFlags] 15008 adrl lr, dvmAsmInstructionStart + (228 * 64) 15009 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15010 cmp r3, #0 15011 bxeq lr @ nothing to do - jump to real handler 15012 EXPORT_PC() 15013 mov r0, rPC @ arg0 15014 mov r1, rFP @ arg1 15015 mov r2, rSELF @ arg2 15016 b dvmCheckBefore @ (dPC,dFP,self) tail call 15017 15018 /* ------------------------------ */ 15019 .balign 64 15020 .L_ALT_OP_SGET_VOLATILE: /* 0xe5 */ 15021 /* File: armv5te/alt_stub.S */ 15022 /* 15023 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15024 * any interesting requests and then jump to the real instruction 15025 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15026 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15027 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15028 * bail to the real handler if breakFlags==0. 15029 */ 15030 ldrb r3, [rSELF, #offThread_breakFlags] 15031 adrl lr, dvmAsmInstructionStart + (229 * 64) 15032 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15033 cmp r3, #0 15034 bxeq lr @ nothing to do - jump to real handler 15035 EXPORT_PC() 15036 mov r0, rPC @ arg0 15037 mov r1, rFP @ arg1 15038 mov r2, rSELF @ arg2 15039 b dvmCheckBefore @ (dPC,dFP,self) tail call 15040 15041 /* ------------------------------ */ 15042 .balign 64 15043 .L_ALT_OP_SPUT_VOLATILE: /* 0xe6 */ 15044 /* File: armv5te/alt_stub.S */ 15045 /* 15046 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15047 * any interesting requests and then jump to the real instruction 15048 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15049 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15050 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15051 * bail to the real handler if breakFlags==0. 15052 */ 15053 ldrb r3, [rSELF, #offThread_breakFlags] 15054 adrl lr, dvmAsmInstructionStart + (230 * 64) 15055 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15056 cmp r3, #0 15057 bxeq lr @ nothing to do - jump to real handler 15058 EXPORT_PC() 15059 mov r0, rPC @ arg0 15060 mov r1, rFP @ arg1 15061 mov r2, rSELF @ arg2 15062 b dvmCheckBefore @ (dPC,dFP,self) tail call 15063 15064 /* ------------------------------ */ 15065 .balign 64 15066 .L_ALT_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 15067 /* File: armv5te/alt_stub.S */ 15068 /* 15069 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15070 * any interesting requests and then jump to the real instruction 15071 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15072 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15073 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15074 * bail to the real handler if breakFlags==0. 15075 */ 15076 ldrb r3, [rSELF, #offThread_breakFlags] 15077 adrl lr, dvmAsmInstructionStart + (231 * 64) 15078 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15079 cmp r3, #0 15080 bxeq lr @ nothing to do - jump to real handler 15081 EXPORT_PC() 15082 mov r0, rPC @ arg0 15083 mov r1, rFP @ arg1 15084 mov r2, rSELF @ arg2 15085 b dvmCheckBefore @ (dPC,dFP,self) tail call 15086 15087 /* ------------------------------ */ 15088 .balign 64 15089 .L_ALT_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 15090 /* File: armv5te/alt_stub.S */ 15091 /* 15092 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15093 * any interesting requests and then jump to the real instruction 15094 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15095 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15096 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15097 * bail to the real handler if breakFlags==0. 15098 */ 15099 ldrb r3, [rSELF, #offThread_breakFlags] 15100 adrl lr, dvmAsmInstructionStart + (232 * 64) 15101 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15102 cmp r3, #0 15103 bxeq lr @ nothing to do - jump to real handler 15104 EXPORT_PC() 15105 mov r0, rPC @ arg0 15106 mov r1, rFP @ arg1 15107 mov r2, rSELF @ arg2 15108 b dvmCheckBefore @ (dPC,dFP,self) tail call 15109 15110 /* ------------------------------ */ 15111 .balign 64 15112 .L_ALT_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 15113 /* File: armv5te/alt_stub.S */ 15114 /* 15115 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15116 * any interesting requests and then jump to the real instruction 15117 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15118 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15119 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15120 * bail to the real handler if breakFlags==0. 15121 */ 15122 ldrb r3, [rSELF, #offThread_breakFlags] 15123 adrl lr, dvmAsmInstructionStart + (233 * 64) 15124 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15125 cmp r3, #0 15126 bxeq lr @ nothing to do - jump to real handler 15127 EXPORT_PC() 15128 mov r0, rPC @ arg0 15129 mov r1, rFP @ arg1 15130 mov r2, rSELF @ arg2 15131 b dvmCheckBefore @ (dPC,dFP,self) tail call 15132 15133 /* ------------------------------ */ 15134 .balign 64 15135 .L_ALT_OP_SGET_WIDE_VOLATILE: /* 0xea */ 15136 /* File: armv5te/alt_stub.S */ 15137 /* 15138 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15139 * any interesting requests and then jump to the real instruction 15140 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15141 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15142 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15143 * bail to the real handler if breakFlags==0. 15144 */ 15145 ldrb r3, [rSELF, #offThread_breakFlags] 15146 adrl lr, dvmAsmInstructionStart + (234 * 64) 15147 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15148 cmp r3, #0 15149 bxeq lr @ nothing to do - jump to real handler 15150 EXPORT_PC() 15151 mov r0, rPC @ arg0 15152 mov r1, rFP @ arg1 15153 mov r2, rSELF @ arg2 15154 b dvmCheckBefore @ (dPC,dFP,self) tail call 15155 15156 /* ------------------------------ */ 15157 .balign 64 15158 .L_ALT_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 15159 /* File: armv5te/alt_stub.S */ 15160 /* 15161 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15162 * any interesting requests and then jump to the real instruction 15163 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15164 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15165 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15166 * bail to the real handler if breakFlags==0. 15167 */ 15168 ldrb r3, [rSELF, #offThread_breakFlags] 15169 adrl lr, dvmAsmInstructionStart + (235 * 64) 15170 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15171 cmp r3, #0 15172 bxeq lr @ nothing to do - jump to real handler 15173 EXPORT_PC() 15174 mov r0, rPC @ arg0 15175 mov r1, rFP @ arg1 15176 mov r2, rSELF @ arg2 15177 b dvmCheckBefore @ (dPC,dFP,self) tail call 15178 15179 /* ------------------------------ */ 15180 .balign 64 15181 .L_ALT_OP_BREAKPOINT: /* 0xec */ 15182 /* File: armv5te/alt_stub.S */ 15183 /* 15184 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15185 * any interesting requests and then jump to the real instruction 15186 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15187 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15188 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15189 * bail to the real handler if breakFlags==0. 15190 */ 15191 ldrb r3, [rSELF, #offThread_breakFlags] 15192 adrl lr, dvmAsmInstructionStart + (236 * 64) 15193 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15194 cmp r3, #0 15195 bxeq lr @ nothing to do - jump to real handler 15196 EXPORT_PC() 15197 mov r0, rPC @ arg0 15198 mov r1, rFP @ arg1 15199 mov r2, rSELF @ arg2 15200 b dvmCheckBefore @ (dPC,dFP,self) tail call 15201 15202 /* ------------------------------ */ 15203 .balign 64 15204 .L_ALT_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 15205 /* File: armv5te/alt_stub.S */ 15206 /* 15207 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15208 * any interesting requests and then jump to the real instruction 15209 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15210 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15211 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15212 * bail to the real handler if breakFlags==0. 15213 */ 15214 ldrb r3, [rSELF, #offThread_breakFlags] 15215 adrl lr, dvmAsmInstructionStart + (237 * 64) 15216 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15217 cmp r3, #0 15218 bxeq lr @ nothing to do - jump to real handler 15219 EXPORT_PC() 15220 mov r0, rPC @ arg0 15221 mov r1, rFP @ arg1 15222 mov r2, rSELF @ arg2 15223 b dvmCheckBefore @ (dPC,dFP,self) tail call 15224 15225 /* ------------------------------ */ 15226 .balign 64 15227 .L_ALT_OP_EXECUTE_INLINE: /* 0xee */ 15228 /* File: armv5te/alt_stub.S */ 15229 /* 15230 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15231 * any interesting requests and then jump to the real instruction 15232 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15233 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15234 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15235 * bail to the real handler if breakFlags==0. 15236 */ 15237 ldrb r3, [rSELF, #offThread_breakFlags] 15238 adrl lr, dvmAsmInstructionStart + (238 * 64) 15239 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15240 cmp r3, #0 15241 bxeq lr @ nothing to do - jump to real handler 15242 EXPORT_PC() 15243 mov r0, rPC @ arg0 15244 mov r1, rFP @ arg1 15245 mov r2, rSELF @ arg2 15246 b dvmCheckBefore @ (dPC,dFP,self) tail call 15247 15248 /* ------------------------------ */ 15249 .balign 64 15250 .L_ALT_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 15251 /* File: armv5te/alt_stub.S */ 15252 /* 15253 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15254 * any interesting requests and then jump to the real instruction 15255 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15256 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15257 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15258 * bail to the real handler if breakFlags==0. 15259 */ 15260 ldrb r3, [rSELF, #offThread_breakFlags] 15261 adrl lr, dvmAsmInstructionStart + (239 * 64) 15262 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15263 cmp r3, #0 15264 bxeq lr @ nothing to do - jump to real handler 15265 EXPORT_PC() 15266 mov r0, rPC @ arg0 15267 mov r1, rFP @ arg1 15268 mov r2, rSELF @ arg2 15269 b dvmCheckBefore @ (dPC,dFP,self) tail call 15270 15271 /* ------------------------------ */ 15272 .balign 64 15273 .L_ALT_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */ 15274 /* File: armv5te/alt_stub.S */ 15275 /* 15276 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15277 * any interesting requests and then jump to the real instruction 15278 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15279 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15280 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15281 * bail to the real handler if breakFlags==0. 15282 */ 15283 ldrb r3, [rSELF, #offThread_breakFlags] 15284 adrl lr, dvmAsmInstructionStart + (240 * 64) 15285 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15286 cmp r3, #0 15287 bxeq lr @ nothing to do - jump to real handler 15288 EXPORT_PC() 15289 mov r0, rPC @ arg0 15290 mov r1, rFP @ arg1 15291 mov r2, rSELF @ arg2 15292 b dvmCheckBefore @ (dPC,dFP,self) tail call 15293 15294 /* ------------------------------ */ 15295 .balign 64 15296 .L_ALT_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 15297 /* File: armv5te/alt_stub.S */ 15298 /* 15299 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15300 * any interesting requests and then jump to the real instruction 15301 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15302 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15303 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15304 * bail to the real handler if breakFlags==0. 15305 */ 15306 ldrb r3, [rSELF, #offThread_breakFlags] 15307 adrl lr, dvmAsmInstructionStart + (241 * 64) 15308 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15309 cmp r3, #0 15310 bxeq lr @ nothing to do - jump to real handler 15311 EXPORT_PC() 15312 mov r0, rPC @ arg0 15313 mov r1, rFP @ arg1 15314 mov r2, rSELF @ arg2 15315 b dvmCheckBefore @ (dPC,dFP,self) tail call 15316 15317 /* ------------------------------ */ 15318 .balign 64 15319 .L_ALT_OP_IGET_QUICK: /* 0xf2 */ 15320 /* File: armv5te/alt_stub.S */ 15321 /* 15322 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15323 * any interesting requests and then jump to the real instruction 15324 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15325 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15326 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15327 * bail to the real handler if breakFlags==0. 15328 */ 15329 ldrb r3, [rSELF, #offThread_breakFlags] 15330 adrl lr, dvmAsmInstructionStart + (242 * 64) 15331 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15332 cmp r3, #0 15333 bxeq lr @ nothing to do - jump to real handler 15334 EXPORT_PC() 15335 mov r0, rPC @ arg0 15336 mov r1, rFP @ arg1 15337 mov r2, rSELF @ arg2 15338 b dvmCheckBefore @ (dPC,dFP,self) tail call 15339 15340 /* ------------------------------ */ 15341 .balign 64 15342 .L_ALT_OP_IGET_WIDE_QUICK: /* 0xf3 */ 15343 /* File: armv5te/alt_stub.S */ 15344 /* 15345 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15346 * any interesting requests and then jump to the real instruction 15347 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15348 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15349 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15350 * bail to the real handler if breakFlags==0. 15351 */ 15352 ldrb r3, [rSELF, #offThread_breakFlags] 15353 adrl lr, dvmAsmInstructionStart + (243 * 64) 15354 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15355 cmp r3, #0 15356 bxeq lr @ nothing to do - jump to real handler 15357 EXPORT_PC() 15358 mov r0, rPC @ arg0 15359 mov r1, rFP @ arg1 15360 mov r2, rSELF @ arg2 15361 b dvmCheckBefore @ (dPC,dFP,self) tail call 15362 15363 /* ------------------------------ */ 15364 .balign 64 15365 .L_ALT_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 15366 /* File: armv5te/alt_stub.S */ 15367 /* 15368 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15369 * any interesting requests and then jump to the real instruction 15370 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15371 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15372 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15373 * bail to the real handler if breakFlags==0. 15374 */ 15375 ldrb r3, [rSELF, #offThread_breakFlags] 15376 adrl lr, dvmAsmInstructionStart + (244 * 64) 15377 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15378 cmp r3, #0 15379 bxeq lr @ nothing to do - jump to real handler 15380 EXPORT_PC() 15381 mov r0, rPC @ arg0 15382 mov r1, rFP @ arg1 15383 mov r2, rSELF @ arg2 15384 b dvmCheckBefore @ (dPC,dFP,self) tail call 15385 15386 /* ------------------------------ */ 15387 .balign 64 15388 .L_ALT_OP_IPUT_QUICK: /* 0xf5 */ 15389 /* File: armv5te/alt_stub.S */ 15390 /* 15391 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15392 * any interesting requests and then jump to the real instruction 15393 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15394 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15395 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15396 * bail to the real handler if breakFlags==0. 15397 */ 15398 ldrb r3, [rSELF, #offThread_breakFlags] 15399 adrl lr, dvmAsmInstructionStart + (245 * 64) 15400 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15401 cmp r3, #0 15402 bxeq lr @ nothing to do - jump to real handler 15403 EXPORT_PC() 15404 mov r0, rPC @ arg0 15405 mov r1, rFP @ arg1 15406 mov r2, rSELF @ arg2 15407 b dvmCheckBefore @ (dPC,dFP,self) tail call 15408 15409 /* ------------------------------ */ 15410 .balign 64 15411 .L_ALT_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 15412 /* File: armv5te/alt_stub.S */ 15413 /* 15414 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15415 * any interesting requests and then jump to the real instruction 15416 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15417 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15418 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15419 * bail to the real handler if breakFlags==0. 15420 */ 15421 ldrb r3, [rSELF, #offThread_breakFlags] 15422 adrl lr, dvmAsmInstructionStart + (246 * 64) 15423 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15424 cmp r3, #0 15425 bxeq lr @ nothing to do - jump to real handler 15426 EXPORT_PC() 15427 mov r0, rPC @ arg0 15428 mov r1, rFP @ arg1 15429 mov r2, rSELF @ arg2 15430 b dvmCheckBefore @ (dPC,dFP,self) tail call 15431 15432 /* ------------------------------ */ 15433 .balign 64 15434 .L_ALT_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 15435 /* File: armv5te/alt_stub.S */ 15436 /* 15437 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15438 * any interesting requests and then jump to the real instruction 15439 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15440 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15441 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15442 * bail to the real handler if breakFlags==0. 15443 */ 15444 ldrb r3, [rSELF, #offThread_breakFlags] 15445 adrl lr, dvmAsmInstructionStart + (247 * 64) 15446 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15447 cmp r3, #0 15448 bxeq lr @ nothing to do - jump to real handler 15449 EXPORT_PC() 15450 mov r0, rPC @ arg0 15451 mov r1, rFP @ arg1 15452 mov r2, rSELF @ arg2 15453 b dvmCheckBefore @ (dPC,dFP,self) tail call 15454 15455 /* ------------------------------ */ 15456 .balign 64 15457 .L_ALT_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 15458 /* File: armv5te/alt_stub.S */ 15459 /* 15460 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15461 * any interesting requests and then jump to the real instruction 15462 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15463 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15464 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15465 * bail to the real handler if breakFlags==0. 15466 */ 15467 ldrb r3, [rSELF, #offThread_breakFlags] 15468 adrl lr, dvmAsmInstructionStart + (248 * 64) 15469 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15470 cmp r3, #0 15471 bxeq lr @ nothing to do - jump to real handler 15472 EXPORT_PC() 15473 mov r0, rPC @ arg0 15474 mov r1, rFP @ arg1 15475 mov r2, rSELF @ arg2 15476 b dvmCheckBefore @ (dPC,dFP,self) tail call 15477 15478 /* ------------------------------ */ 15479 .balign 64 15480 .L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 15481 /* File: armv5te/alt_stub.S */ 15482 /* 15483 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15484 * any interesting requests and then jump to the real instruction 15485 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15486 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15487 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15488 * bail to the real handler if breakFlags==0. 15489 */ 15490 ldrb r3, [rSELF, #offThread_breakFlags] 15491 adrl lr, dvmAsmInstructionStart + (249 * 64) 15492 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15493 cmp r3, #0 15494 bxeq lr @ nothing to do - jump to real handler 15495 EXPORT_PC() 15496 mov r0, rPC @ arg0 15497 mov r1, rFP @ arg1 15498 mov r2, rSELF @ arg2 15499 b dvmCheckBefore @ (dPC,dFP,self) tail call 15500 15501 /* ------------------------------ */ 15502 .balign 64 15503 .L_ALT_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 15504 /* File: armv5te/alt_stub.S */ 15505 /* 15506 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15507 * any interesting requests and then jump to the real instruction 15508 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15509 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15510 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15511 * bail to the real handler if breakFlags==0. 15512 */ 15513 ldrb r3, [rSELF, #offThread_breakFlags] 15514 adrl lr, dvmAsmInstructionStart + (250 * 64) 15515 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15516 cmp r3, #0 15517 bxeq lr @ nothing to do - jump to real handler 15518 EXPORT_PC() 15519 mov r0, rPC @ arg0 15520 mov r1, rFP @ arg1 15521 mov r2, rSELF @ arg2 15522 b dvmCheckBefore @ (dPC,dFP,self) tail call 15523 15524 /* ------------------------------ */ 15525 .balign 64 15526 .L_ALT_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 15527 /* File: armv5te/alt_stub.S */ 15528 /* 15529 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15530 * any interesting requests and then jump to the real instruction 15531 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15532 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15533 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15534 * bail to the real handler if breakFlags==0. 15535 */ 15536 ldrb r3, [rSELF, #offThread_breakFlags] 15537 adrl lr, dvmAsmInstructionStart + (251 * 64) 15538 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15539 cmp r3, #0 15540 bxeq lr @ nothing to do - jump to real handler 15541 EXPORT_PC() 15542 mov r0, rPC @ arg0 15543 mov r1, rFP @ arg1 15544 mov r2, rSELF @ arg2 15545 b dvmCheckBefore @ (dPC,dFP,self) tail call 15546 15547 /* ------------------------------ */ 15548 .balign 64 15549 .L_ALT_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 15550 /* File: armv5te/alt_stub.S */ 15551 /* 15552 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15553 * any interesting requests and then jump to the real instruction 15554 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15555 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15556 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15557 * bail to the real handler if breakFlags==0. 15558 */ 15559 ldrb r3, [rSELF, #offThread_breakFlags] 15560 adrl lr, dvmAsmInstructionStart + (252 * 64) 15561 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15562 cmp r3, #0 15563 bxeq lr @ nothing to do - jump to real handler 15564 EXPORT_PC() 15565 mov r0, rPC @ arg0 15566 mov r1, rFP @ arg1 15567 mov r2, rSELF @ arg2 15568 b dvmCheckBefore @ (dPC,dFP,self) tail call 15569 15570 /* ------------------------------ */ 15571 .balign 64 15572 .L_ALT_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 15573 /* File: armv5te/alt_stub.S */ 15574 /* 15575 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15576 * any interesting requests and then jump to the real instruction 15577 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15578 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15579 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15580 * bail to the real handler if breakFlags==0. 15581 */ 15582 ldrb r3, [rSELF, #offThread_breakFlags] 15583 adrl lr, dvmAsmInstructionStart + (253 * 64) 15584 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15585 cmp r3, #0 15586 bxeq lr @ nothing to do - jump to real handler 15587 EXPORT_PC() 15588 mov r0, rPC @ arg0 15589 mov r1, rFP @ arg1 15590 mov r2, rSELF @ arg2 15591 b dvmCheckBefore @ (dPC,dFP,self) tail call 15592 15593 /* ------------------------------ */ 15594 .balign 64 15595 .L_ALT_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 15596 /* File: armv5te/alt_stub.S */ 15597 /* 15598 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15599 * any interesting requests and then jump to the real instruction 15600 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15601 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15602 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15603 * bail to the real handler if breakFlags==0. 15604 */ 15605 ldrb r3, [rSELF, #offThread_breakFlags] 15606 adrl lr, dvmAsmInstructionStart + (254 * 64) 15607 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15608 cmp r3, #0 15609 bxeq lr @ nothing to do - jump to real handler 15610 EXPORT_PC() 15611 mov r0, rPC @ arg0 15612 mov r1, rFP @ arg1 15613 mov r2, rSELF @ arg2 15614 b dvmCheckBefore @ (dPC,dFP,self) tail call 15615 15616 /* ------------------------------ */ 15617 .balign 64 15618 .L_ALT_OP_UNUSED_FF: /* 0xff */ 15619 /* File: armv5te/alt_stub.S */ 15620 /* 15621 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15622 * any interesting requests and then jump to the real instruction 15623 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15624 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15625 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15626 * bail to the real handler if breakFlags==0. 15627 */ 15628 ldrb r3, [rSELF, #offThread_breakFlags] 15629 adrl lr, dvmAsmInstructionStart + (255 * 64) 15630 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15631 cmp r3, #0 15632 bxeq lr @ nothing to do - jump to real handler 15633 EXPORT_PC() 15634 mov r0, rPC @ arg0 15635 mov r1, rFP @ arg1 15636 mov r2, rSELF @ arg2 15637 b dvmCheckBefore @ (dPC,dFP,self) tail call 15638 15639 .balign 64 15640 .size dvmAsmAltInstructionStart, .-dvmAsmAltInstructionStart 15641 .global dvmAsmAltInstructionEnd 15642 dvmAsmAltInstructionEnd: 15643 /* File: armv5te/footer.S */ 15644 /* 15645 * =========================================================================== 15646 * Common subroutines and data 15647 * =========================================================================== 15648 */ 15649 15650 .text 15651 .align 2 15652 15653 #if defined(WITH_JIT) 15654 15655 #if defined(WITH_SELF_VERIFICATION) 15656 /* 15657 * "longjmp" to a translation after single-stepping. Before returning 15658 * to translation, must save state for self-verification. 15659 */ 15660 .global dvmJitResumeTranslation @ (Thread* self, u4* dFP) 15661 dvmJitResumeTranslation: 15662 mov rSELF, r0 @ restore self 15663 mov rPC, r1 @ restore Dalvik pc 15664 mov rFP, r2 @ restore Dalvik fp 15665 ldr r10, [rSELF,#offThread_jitResumeNPC] @ resume address 15666 mov r2, #0 15667 str r2, [rSELF,#offThread_jitResumeNPC] @ reset resume address 15668 ldr sp, [rSELF,#offThread_jitResumeNSP] @ cut back native stack 15669 b jitSVShadowRunStart @ resume as if cache hit 15670 @ expects resume addr in r10 15671 15672 .global dvmJitToInterpPunt 15673 dvmJitToInterpPunt: 15674 mov r2,#kSVSPunt @ r2<- interpreter entry point 15675 mov r3, #0 15676 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15677 b jitSVShadowRunEnd @ doesn't return 15678 15679 .global dvmJitToInterpSingleStep 15680 dvmJitToInterpSingleStep: 15681 mov rPC, r0 @ set up dalvik pc 15682 EXPORT_PC() 15683 str lr, [rSELF,#offThread_jitResumeNPC] 15684 str sp, [rSELF,#offThread_jitResumeNSP] 15685 str r1, [rSELF,#offThread_jitResumeDPC] 15686 mov r2,#kSVSSingleStep @ r2<- interpreter entry point 15687 b jitSVShadowRunEnd @ doesn't return 15688 15689 15690 .global dvmJitToInterpNoChainNoProfile 15691 dvmJitToInterpNoChainNoProfile: 15692 mov r0,rPC @ pass our target PC 15693 mov r2,#kSVSNoProfile @ r2<- interpreter entry point 15694 mov r3, #0 @ 0 means !inJitCodeCache 15695 str r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 15696 b jitSVShadowRunEnd @ doesn't return 15697 15698 .global dvmJitToInterpTraceSelectNoChain 15699 dvmJitToInterpTraceSelectNoChain: 15700 mov r0,rPC @ pass our target PC 15701 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 15702 mov r3, #0 @ 0 means !inJitCodeCache 15703 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15704 b jitSVShadowRunEnd @ doesn't return 15705 15706 .global dvmJitToInterpTraceSelect 15707 dvmJitToInterpTraceSelect: 15708 ldr r0,[lr, #-1] @ pass our target PC 15709 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 15710 mov r3, #0 @ 0 means !inJitCodeCache 15711 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15712 b jitSVShadowRunEnd @ doesn't return 15713 15714 .global dvmJitToInterpBackwardBranch 15715 dvmJitToInterpBackwardBranch: 15716 ldr r0,[lr, #-1] @ pass our target PC 15717 mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point 15718 mov r3, #0 @ 0 means !inJitCodeCache 15719 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15720 b jitSVShadowRunEnd @ doesn't return 15721 15722 .global dvmJitToInterpNormal 15723 dvmJitToInterpNormal: 15724 ldr r0,[lr, #-1] @ pass our target PC 15725 mov r2,#kSVSNormal @ r2<- interpreter entry point 15726 mov r3, #0 @ 0 means !inJitCodeCache 15727 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15728 b jitSVShadowRunEnd @ doesn't return 15729 15730 .global dvmJitToInterpNoChain 15731 dvmJitToInterpNoChain: 15732 mov r0,rPC @ pass our target PC 15733 mov r2,#kSVSNoChain @ r2<- interpreter entry point 15734 mov r3, #0 @ 0 means !inJitCodeCache 15735 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15736 b jitSVShadowRunEnd @ doesn't return 15737 #else 15738 15739 /* 15740 * "longjmp" to a translation after single-stepping. 15741 */ 15742 .global dvmJitResumeTranslation @ (Thread* self, u4* dFP) 15743 dvmJitResumeTranslation: 15744 mov rSELF, r0 @ restore self 15745 mov rPC, r1 @ restore Dalvik pc 15746 mov rFP, r2 @ restore Dalvik fp 15747 ldr r0, [rSELF,#offThread_jitResumeNPC] 15748 mov r2, #0 15749 str r2, [rSELF,#offThread_jitResumeNPC] @ reset resume address 15750 ldr sp, [rSELF,#offThread_jitResumeNSP] @ cut back native stack 15751 bx r0 @ resume translation 15752 15753 /* 15754 * Return from the translation cache to the interpreter when the compiler is 15755 * having issues translating/executing a Dalvik instruction. We have to skip 15756 * the code cache lookup otherwise it is possible to indefinitely bouce 15757 * between the interpreter and the code cache if the instruction that fails 15758 * to be compiled happens to be at a trace start. 15759 */ 15760 .global dvmJitToInterpPunt 15761 dvmJitToInterpPunt: 15762 mov rPC, r0 15763 #if defined(WITH_JIT_TUNING) 15764 mov r0,lr 15765 bl dvmBumpPunt; 15766 #endif 15767 EXPORT_PC() 15768 mov r0, #0 15769 str r0, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15770 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15771 FETCH_INST() 15772 GET_INST_OPCODE(ip) 15773 GOTO_OPCODE(ip) 15774 15775 /* 15776 * Return to the interpreter to handle a single instruction. 15777 * We'll use the normal single-stepping mechanism via interpBreak, 15778 * but also save the native pc of the resume point in the translation 15779 * and the native sp so that we can later do the equivalent of a 15780 * longjmp() to resume. 15781 * On entry: 15782 * dPC <= Dalvik PC of instrucion to interpret 15783 * lr <= resume point in translation 15784 * r1 <= Dalvik PC of next instruction 15785 */ 15786 .global dvmJitToInterpSingleStep 15787 dvmJitToInterpSingleStep: 15788 mov rPC, r0 @ set up dalvik pc 15789 EXPORT_PC() 15790 str lr, [rSELF,#offThread_jitResumeNPC] 15791 str sp, [rSELF,#offThread_jitResumeNSP] 15792 str r1, [rSELF,#offThread_jitResumeDPC] 15793 mov r1, #1 15794 str r1, [rSELF,#offThread_singleStepCount] @ just step once 15795 mov r0, rSELF 15796 mov r1, #kSubModeCountedStep 15797 bl dvmEnableSubMode @ (self, newMode) 15798 ldr rIBASE, [rSELF,#offThread_curHandlerTable] 15799 FETCH_INST() 15800 GET_INST_OPCODE(ip) 15801 GOTO_OPCODE(ip) 15802 15803 /* 15804 * Return from the translation cache and immediately request 15805 * a translation for the exit target. Commonly used for callees. 15806 */ 15807 .global dvmJitToInterpTraceSelectNoChain 15808 dvmJitToInterpTraceSelectNoChain: 15809 #if defined(WITH_JIT_TUNING) 15810 bl dvmBumpNoChain 15811 #endif 15812 mov r0,rPC 15813 mov r1,rSELF 15814 bl dvmJitGetTraceAddrThread @ (pc, self) 15815 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15816 mov r1, rPC @ arg1 of translation may need this 15817 mov lr, #0 @ in case target is HANDLER_INTERPRET 15818 cmp r0,#0 @ !0 means translation exists 15819 bxne r0 @ continue native execution if so 15820 b 2f @ branch over to use the interpreter 15821 15822 /* 15823 * Return from the translation cache and immediately request 15824 * a translation for the exit target. Commonly used following 15825 * invokes. 15826 */ 15827 .global dvmJitToInterpTraceSelect 15828 dvmJitToInterpTraceSelect: 15829 ldr rPC,[lr, #-1] @ get our target PC 15830 add rINST,lr,#-5 @ save start of chain branch 15831 add rINST, #-4 @ .. which is 9 bytes back 15832 mov r0,rPC 15833 mov r1,rSELF 15834 bl dvmJitGetTraceAddrThread @ (pc, self) 15835 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15836 cmp r0,#0 15837 beq 2f 15838 mov r1,rINST 15839 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 15840 mov r1, rPC @ arg1 of translation may need this 15841 mov lr, #0 @ in case target is HANDLER_INTERPRET 15842 cmp r0,#0 @ successful chain? 15843 bxne r0 @ continue native execution 15844 b toInterpreter @ didn't chain - resume with interpreter 15845 15846 /* No translation, so request one if profiling isn't disabled*/ 15847 2: 15848 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15849 ldr r0, [rSELF, #offThread_pJitProfTable] 15850 FETCH_INST() 15851 cmp r0, #0 15852 movne r2,#kJitTSelectRequestHot @ ask for trace selection 15853 bne common_selectTrace 15854 GET_INST_OPCODE(ip) 15855 GOTO_OPCODE(ip) 15856 15857 /* 15858 * Return from the translation cache to the interpreter. 15859 * The return was done with a BLX from thumb mode, and 15860 * the following 32-bit word contains the target rPC value. 15861 * Note that lr (r14) will have its low-order bit set to denote 15862 * its thumb-mode origin. 15863 * 15864 * We'll need to stash our lr origin away, recover the new 15865 * target and then check to see if there is a translation available 15866 * for our new target. If so, we do a translation chain and 15867 * go back to native execution. Otherwise, it's back to the 15868 * interpreter (after treating this entry as a potential 15869 * trace start). 15870 */ 15871 .global dvmJitToInterpNormal 15872 dvmJitToInterpNormal: 15873 ldr rPC,[lr, #-1] @ get our target PC 15874 add rINST,lr,#-5 @ save start of chain branch 15875 add rINST,#-4 @ .. which is 9 bytes back 15876 #if defined(WITH_JIT_TUNING) 15877 bl dvmBumpNormal 15878 #endif 15879 mov r0,rPC 15880 mov r1,rSELF 15881 bl dvmJitGetTraceAddrThread @ (pc, self) 15882 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15883 cmp r0,#0 15884 beq toInterpreter @ go if not, otherwise do chain 15885 mov r1,rINST 15886 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 15887 mov r1, rPC @ arg1 of translation may need this 15888 mov lr, #0 @ in case target is HANDLER_INTERPRET 15889 cmp r0,#0 @ successful chain? 15890 bxne r0 @ continue native execution 15891 b toInterpreter @ didn't chain - resume with interpreter 15892 15893 /* 15894 * Return from the translation cache to the interpreter to do method invocation. 15895 * Check if translation exists for the callee, but don't chain to it. 15896 */ 15897 .global dvmJitToInterpNoChainNoProfile 15898 dvmJitToInterpNoChainNoProfile: 15899 #if defined(WITH_JIT_TUNING) 15900 bl dvmBumpNoChain 15901 #endif 15902 mov r0,rPC 15903 mov r1,rSELF 15904 bl dvmJitGetTraceAddrThread @ (pc, self) 15905 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15906 mov r1, rPC @ arg1 of translation may need this 15907 mov lr, #0 @ in case target is HANDLER_INTERPRET 15908 cmp r0,#0 15909 bxne r0 @ continue native execution if so 15910 EXPORT_PC() 15911 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15912 FETCH_INST() 15913 GET_INST_OPCODE(ip) @ extract opcode from rINST 15914 GOTO_OPCODE(ip) @ jump to next instruction 15915 15916 /* 15917 * Return from the translation cache to the interpreter to do method invocation. 15918 * Check if translation exists for the callee, but don't chain to it. 15919 */ 15920 .global dvmJitToInterpNoChain 15921 dvmJitToInterpNoChain: 15922 #if defined(WITH_JIT_TUNING) 15923 bl dvmBumpNoChain 15924 #endif 15925 mov r0,rPC 15926 mov r1,rSELF 15927 bl dvmJitGetTraceAddrThread @ (pc, self) 15928 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15929 mov r1, rPC @ arg1 of translation may need this 15930 mov lr, #0 @ in case target is HANDLER_INTERPRET 15931 cmp r0,#0 15932 bxne r0 @ continue native execution if so 15933 #endif 15934 15935 /* 15936 * No translation, restore interpreter regs and start interpreting. 15937 * rSELF & rFP were preserved in the translated code, and rPC has 15938 * already been restored by the time we get here. We'll need to set 15939 * up rIBASE & rINST, and load the address of the JitTable into r0. 15940 */ 15941 toInterpreter: 15942 EXPORT_PC() 15943 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15944 FETCH_INST() 15945 ldr r0, [rSELF, #offThread_pJitProfTable] 15946 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15947 @ NOTE: intended fallthrough 15948 15949 /* 15950 * Similar to common_updateProfile, but tests for null pJitProfTable 15951 * r0 holds pJifProfTAble, rINST is loaded, rPC is current and 15952 * rIBASE has been recently refreshed. 15953 */ 15954 common_testUpdateProfile: 15955 cmp r0, #0 @ JIT switched off? 15956 beq 4f @ return to interp if so 15957 15958 /* 15959 * Common code to update potential trace start counter, and initiate 15960 * a trace-build if appropriate. 15961 * On entry here: 15962 * r0 <= pJitProfTable (verified non-NULL) 15963 * rPC <= Dalvik PC 15964 * rINST <= next instruction 15965 */ 15966 common_updateProfile: 15967 eor r3,rPC,rPC,lsr #12 @ cheap, but fast hash function 15968 lsl r3,r3,#(32 - JIT_PROF_SIZE_LOG_2) @ shift out excess bits 15969 ldrb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter 15970 GET_INST_OPCODE(ip) 15971 subs r1,r1,#1 @ decrement counter 15972 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it 15973 GOTO_OPCODE_IFNE(ip) @ if not threshold, fallthrough otherwise */ 15974 15975 /* Looks good, reset the counter */ 15976 ldr r1, [rSELF, #offThread_jitThreshold] 15977 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter 15978 EXPORT_PC() 15979 mov r0,rPC 15980 mov r1,rSELF 15981 bl dvmJitGetTraceAddrThread @ (pc, self) 15982 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15983 mov r1, rPC @ arg1 of translation may need this 15984 mov lr, #0 @ in case target is HANDLER_INTERPRET 15985 cmp r0,#0 15986 #if !defined(WITH_SELF_VERIFICATION) 15987 bxne r0 @ jump to the translation 15988 mov r2,#kJitTSelectRequest @ ask for trace selection 15989 @ fall-through to common_selectTrace 15990 #else 15991 moveq r2,#kJitTSelectRequest @ ask for trace selection 15992 beq common_selectTrace 15993 /* 15994 * At this point, we have a target translation. However, if 15995 * that translation is actually the interpret-only pseudo-translation 15996 * we want to treat it the same as no translation. 15997 */ 15998 mov r10, r0 @ save target 15999 bl dvmCompilerGetInterpretTemplate 16000 cmp r0, r10 @ special case? 16001 bne jitSVShadowRunStart @ set up self verification shadow space 16002 @ Need to clear the inJitCodeCache flag 16003 mov r3, #0 @ 0 means not in the JIT code cache 16004 str r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 16005 GET_INST_OPCODE(ip) 16006 GOTO_OPCODE(ip) 16007 /* no return */ 16008 #endif 16009 16010 /* 16011 * On entry: 16012 * r2 is jit state. 16013 */ 16014 common_selectTrace: 16015 ldrh r0,[rSELF,#offThread_subMode] 16016 ands r0, #(kSubModeJitTraceBuild | kSubModeJitSV) 16017 bne 3f @ already doing JIT work, continue 16018 str r2,[rSELF,#offThread_jitState] 16019 mov r0, rSELF 16020 /* 16021 * Call out to validate trace-building request. If successful, 16022 * rIBASE will be swapped to to send us into single-stepping trace 16023 * building mode, so we need to refresh before we continue. 16024 */ 16025 EXPORT_PC() 16026 SAVE_PC_FP_TO_SELF() @ copy of pc/fp to Thread 16027 bl dvmJitCheckTraceRequest 16028 3: 16029 FETCH_INST() 16030 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16031 4: 16032 GET_INST_OPCODE(ip) @ extract opcode from rINST 16033 GOTO_OPCODE(ip) 16034 /* no return */ 16035 #endif 16036 16037 #if defined(WITH_SELF_VERIFICATION) 16038 /* 16039 * Save PC and registers to shadow memory for self verification mode 16040 * before jumping to native translation. 16041 * On entry: 16042 * rPC, rFP, rSELF: the values that they should contain 16043 * r10: the address of the target translation. 16044 */ 16045 jitSVShadowRunStart: 16046 mov r0,rPC @ r0<- program counter 16047 mov r1,rFP @ r1<- frame pointer 16048 mov r2,rSELF @ r2<- self (Thread) pointer 16049 mov r3,r10 @ r3<- target translation 16050 bl dvmSelfVerificationSaveState @ save registers to shadow space 16051 ldr rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space 16052 bx r10 @ jump to the translation 16053 16054 /* 16055 * Restore PC, registers, and interpreter state to original values 16056 * before jumping back to the interpreter. 16057 * On entry: 16058 * r0: dPC 16059 * r2: self verification state 16060 */ 16061 jitSVShadowRunEnd: 16062 mov r1,rFP @ pass ending fp 16063 mov r3,rSELF @ pass self ptr for convenience 16064 bl dvmSelfVerificationRestoreState @ restore pc and fp values 16065 LOAD_PC_FP_FROM_SELF() @ restore pc, fp 16066 ldr r1,[r0,#offShadowSpace_svState] @ get self verification state 16067 cmp r1,#0 @ check for punt condition 16068 beq 1f 16069 @ Set up SV single-stepping 16070 mov r0, rSELF 16071 mov r1, #kSubModeJitSV 16072 bl dvmEnableSubMode @ (self, subMode) 16073 mov r2,#kJitSelfVerification @ ask for self verification 16074 str r2,[rSELF,#offThread_jitState] 16075 @ intentional fallthrough 16076 1: @ exit to interpreter without check 16077 EXPORT_PC() 16078 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16079 FETCH_INST() 16080 GET_INST_OPCODE(ip) 16081 GOTO_OPCODE(ip) 16082 #endif 16083 16084 /* 16085 * The equivalent of "goto bail", this calls through the "bail handler". 16086 * It will end this interpreter activation, and return to the caller 16087 * of dvmMterpStdRun. 16088 * 16089 * State registers will be saved to the "thread" area before bailing 16090 * debugging purposes 16091 */ 16092 common_gotoBail: 16093 SAVE_PC_FP_TO_SELF() @ export state to "thread" 16094 mov r0, rSELF @ r0<- self ptr 16095 b dvmMterpStdBail @ call(self, changeInterp) 16096 16097 /* 16098 * The JIT's invoke method needs to remember the callsite class and 16099 * target pair. Save them here so that they are available to 16100 * dvmCheckJit following the interpretation of this invoke. 16101 */ 16102 #if defined(WITH_JIT) 16103 save_callsiteinfo: 16104 cmp r9, #0 16105 ldrne r9, [r9, #offObject_clazz] 16106 str r0, [rSELF, #offThread_methodToCall] 16107 str r9, [rSELF, #offThread_callsiteClass] 16108 bx lr 16109 #endif 16110 16111 /* 16112 * Common code for method invocation with range. 16113 * 16114 * On entry: 16115 * r0 is "Method* methodToCall", r9 is "this" 16116 */ 16117 common_invokeMethodRange: 16118 .LinvokeNewRange: 16119 #if defined(WITH_JIT) 16120 ldrh r1, [rSELF, #offThread_subMode] 16121 ands r1, #kSubModeJitTraceBuild 16122 blne save_callsiteinfo 16123 #endif 16124 @ prepare to copy args to "outs" area of current frame 16125 movs r2, rINST, lsr #8 @ r2<- AA (arg count) -- test for zero 16126 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 16127 beq .LinvokeArgsDone @ if no args, skip the rest 16128 FETCH(r1, 2) @ r1<- CCCC 16129 16130 .LinvokeRangeArgs: 16131 @ r0=methodToCall, r1=CCCC, r2=count, r10=outs 16132 @ (very few methods have > 10 args; could unroll for common cases) 16133 add r3, rFP, r1, lsl #2 @ r3<- &fp[CCCC] 16134 sub r10, r10, r2, lsl #2 @ r10<- "outs" area, for call args 16135 1: ldr r1, [r3], #4 @ val = *fp++ 16136 subs r2, r2, #1 @ count-- 16137 str r1, [r10], #4 @ *outs++ = val 16138 bne 1b @ ...while count != 0 16139 b .LinvokeArgsDone 16140 16141 /* 16142 * Common code for method invocation without range. 16143 * 16144 * On entry: 16145 * r0 is "Method* methodToCall", r9 is "this" 16146 */ 16147 common_invokeMethodNoRange: 16148 .LinvokeNewNoRange: 16149 #if defined(WITH_JIT) 16150 ldrh r1, [rSELF, #offThread_subMode] 16151 ands r1, #kSubModeJitTraceBuild 16152 blne save_callsiteinfo 16153 #endif 16154 @ prepare to copy args to "outs" area of current frame 16155 movs r2, rINST, lsr #12 @ r2<- B (arg count) -- test for zero 16156 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 16157 FETCH(r1, 2) @ r1<- GFED (load here to hide latency) 16158 beq .LinvokeArgsDone 16159 16160 @ r0=methodToCall, r1=GFED, r2=count, r10=outs 16161 .LinvokeNonRange: 16162 rsb r2, r2, #5 @ r2<- 5-r2 16163 add pc, pc, r2, lsl #4 @ computed goto, 4 instrs each 16164 bl common_abort @ (skipped due to ARM prefetch) 16165 5: and ip, rINST, #0x0f00 @ isolate A 16166 ldr r2, [rFP, ip, lsr #6] @ r2<- vA (shift right 8, left 2) 16167 mov r0, r0 @ nop 16168 str r2, [r10, #-4]! @ *--outs = vA 16169 4: and ip, r1, #0xf000 @ isolate G 16170 ldr r2, [rFP, ip, lsr #10] @ r2<- vG (shift right 12, left 2) 16171 mov r0, r0 @ nop 16172 str r2, [r10, #-4]! @ *--outs = vG 16173 3: and ip, r1, #0x0f00 @ isolate F 16174 ldr r2, [rFP, ip, lsr #6] @ r2<- vF 16175 mov r0, r0 @ nop 16176 str r2, [r10, #-4]! @ *--outs = vF 16177 2: and ip, r1, #0x00f0 @ isolate E 16178 ldr r2, [rFP, ip, lsr #2] @ r2<- vE 16179 mov r0, r0 @ nop 16180 str r2, [r10, #-4]! @ *--outs = vE 16181 1: and ip, r1, #0x000f @ isolate D 16182 ldr r2, [rFP, ip, lsl #2] @ r2<- vD 16183 mov r0, r0 @ nop 16184 str r2, [r10, #-4]! @ *--outs = vD 16185 0: @ fall through to .LinvokeArgsDone 16186 16187 .LinvokeArgsDone: @ r0=methodToCall 16188 ldrh r9, [r0, #offMethod_registersSize] @ r9<- methodToCall->regsSize 16189 ldrh r3, [r0, #offMethod_outsSize] @ r3<- methodToCall->outsSize 16190 ldr r2, [r0, #offMethod_insns] @ r2<- method->insns 16191 ldr rINST, [r0, #offMethod_clazz] @ rINST<- method->clazz 16192 @ find space for the new stack frame, check for overflow 16193 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area 16194 sub r1, r1, r9, lsl #2 @ r1<- newFp (old savearea - regsSize) 16195 SAVEAREA_FROM_FP(r10, r1) @ r10<- newSaveArea 16196 @ bl common_dumpRegs 16197 ldr r9, [rSELF, #offThread_interpStackEnd] @ r9<- interpStackEnd 16198 sub r3, r10, r3, lsl #2 @ r3<- bottom (newsave - outsSize) 16199 cmp r3, r9 @ bottom < interpStackEnd? 16200 ldrh lr, [rSELF, #offThread_subMode] 16201 ldr r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags 16202 blo .LstackOverflow @ yes, this frame will overflow stack 16203 16204 @ set up newSaveArea 16205 #ifdef EASY_GDB 16206 SAVEAREA_FROM_FP(ip, rFP) @ ip<- stack save area 16207 str ip, [r10, #offStackSaveArea_prevSave] 16208 #endif 16209 str rFP, [r10, #offStackSaveArea_prevFrame] 16210 str rPC, [r10, #offStackSaveArea_savedPc] 16211 #if defined(WITH_JIT) 16212 mov r9, #0 16213 str r9, [r10, #offStackSaveArea_returnAddr] 16214 #endif 16215 str r0, [r10, #offStackSaveArea_method] 16216 16217 @ Profiling? 16218 cmp lr, #0 @ any special modes happening? 16219 bne 2f @ go if so 16220 1: 16221 tst r3, #ACC_NATIVE 16222 bne .LinvokeNative 16223 16224 /* 16225 stmfd sp!, {r0-r3} 16226 bl common_printNewline 16227 mov r0, rFP 16228 mov r1, #0 16229 bl dvmDumpFp 16230 ldmfd sp!, {r0-r3} 16231 stmfd sp!, {r0-r3} 16232 mov r0, r1 16233 mov r1, r10 16234 bl dvmDumpFp 16235 bl common_printNewline 16236 ldmfd sp!, {r0-r3} 16237 */ 16238 16239 ldrh r9, [r2] @ r9 <- load INST from new PC 16240 ldr r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex 16241 mov rPC, r2 @ publish new rPC 16242 16243 @ Update state values for the new method 16244 @ r0=methodToCall, r1=newFp, r3=newMethodClass, r9=newINST 16245 str r0, [rSELF, #offThread_method] @ self->method = methodToCall 16246 str r3, [rSELF, #offThread_methodClassDex] @ self->methodClassDex = ... 16247 mov r2, #1 16248 str r2, [rSELF, #offThread_debugIsMethodEntry] 16249 #if defined(WITH_JIT) 16250 ldr r0, [rSELF, #offThread_pJitProfTable] 16251 mov rFP, r1 @ fp = newFp 16252 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 16253 mov rINST, r9 @ publish new rINST 16254 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16255 cmp r0,#0 16256 bne common_updateProfile 16257 GOTO_OPCODE(ip) @ jump to next instruction 16258 #else 16259 mov rFP, r1 @ fp = newFp 16260 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 16261 mov rINST, r9 @ publish new rINST 16262 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16263 GOTO_OPCODE(ip) @ jump to next instruction 16264 #endif 16265 16266 2: 16267 @ Profiling - record method entry. r0: methodToCall 16268 stmfd sp!, {r0-r3} @ preserve r0-r3 16269 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16270 mov r1, r0 16271 mov r0, rSELF 16272 bl dvmReportInvoke @ (self, method) 16273 ldmfd sp!, {r0-r3} @ restore r0-r3 16274 b 1b 16275 16276 .LinvokeNative: 16277 @ Prep for the native call 16278 @ r0=methodToCall, r1=newFp, r10=newSaveArea 16279 ldrh lr, [rSELF, #offThread_subMode] 16280 ldr r9, [rSELF, #offThread_jniLocal_topCookie]@r9<-thread->localRef->... 16281 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16282 str r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top 16283 mov r2, r0 @ r2<- methodToCall 16284 mov r0, r1 @ r0<- newFp (points to args) 16285 add r1, rSELF, #offThread_retval @ r1<- &retval 16286 mov r3, rSELF @ arg3<- self 16287 16288 #ifdef ASSIST_DEBUGGER 16289 /* insert fake function header to help gdb find the stack frame */ 16290 b .Lskip 16291 .type dalvik_mterp, %function 16292 dalvik_mterp: 16293 .fnstart 16294 MTERP_ENTRY1 16295 MTERP_ENTRY2 16296 .Lskip: 16297 #endif 16298 16299 cmp lr, #0 @ any special SubModes active? 16300 bne 11f @ go handle them if so 16301 mov lr, pc @ set return addr 16302 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 16303 7: 16304 16305 @ native return; r10=newSaveArea 16306 @ equivalent to dvmPopJniLocals 16307 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top 16308 ldr r1, [rSELF, #offThread_exception] @ check for exception 16309 str rFP, [rSELF, #offThread_curFrame] @ curFrame = fp 16310 cmp r1, #0 @ null? 16311 str r0, [rSELF, #offThread_jniLocal_topCookie] @ new top <- old top 16312 bne common_exceptionThrown @ no, handle exception 16313 16314 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 16315 GET_INST_OPCODE(ip) @ extract opcode from rINST 16316 GOTO_OPCODE(ip) @ jump to next instruction 16317 16318 11: 16319 @ r0=newFp, r1=&retval, r2=methodToCall, r3=self, lr=subModes 16320 stmfd sp!, {r0-r3} @ save all but subModes 16321 mov r0, r2 @ r0<- methodToCall 16322 mov r1, rSELF 16323 mov r2, rFP 16324 bl dvmReportPreNativeInvoke @ (methodToCall, self, fp) 16325 ldmfd sp, {r0-r3} @ refresh. NOTE: no sp autoincrement 16326 16327 @ Call the native method 16328 mov lr, pc @ set return addr 16329 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 16330 16331 @ Restore the pre-call arguments 16332 ldmfd sp!, {r0-r3} @ r2<- methodToCall (others unneeded) 16333 16334 @ Finish up any post-invoke subMode requirements 16335 mov r0, r2 @ r0<- methodToCall 16336 mov r1, rSELF 16337 mov r2, rFP 16338 bl dvmReportPostNativeInvoke @ (methodToCall, self, fp) 16339 b 7b @ resume 16340 16341 .LstackOverflow: @ r0=methodToCall 16342 mov r1, r0 @ r1<- methodToCall 16343 mov r0, rSELF @ r0<- self 16344 bl dvmHandleStackOverflow 16345 b common_exceptionThrown 16346 #ifdef ASSIST_DEBUGGER 16347 .fnend 16348 .size dalvik_mterp, .-dalvik_mterp 16349 #endif 16350 16351 16352 /* 16353 * Common code for method invocation, calling through "glue code". 16354 * 16355 * TODO: now that we have range and non-range invoke handlers, this 16356 * needs to be split into two. Maybe just create entry points 16357 * that set r9 and jump here? 16358 * 16359 * On entry: 16360 * r0 is "Method* methodToCall", the method we're trying to call 16361 * r9 is "bool methodCallRange", indicating if this is a /range variant 16362 */ 16363 .if 0 16364 .LinvokeOld: 16365 sub sp, sp, #8 @ space for args + pad 16366 FETCH(ip, 2) @ ip<- FEDC or CCCC 16367 mov r2, r0 @ A2<- methodToCall 16368 mov r0, rSELF @ A0<- self 16369 SAVE_PC_FP_TO_SELF() @ export state to "self" 16370 mov r1, r9 @ A1<- methodCallRange 16371 mov r3, rINST, lsr #8 @ A3<- AA 16372 str ip, [sp, #0] @ A4<- ip 16373 bl dvmMterp_invokeMethod @ call the C invokeMethod 16374 add sp, sp, #8 @ remove arg area 16375 b common_resumeAfterGlueCall @ continue to next instruction 16376 .endif 16377 16378 16379 16380 /* 16381 * Common code for handling a return instruction. 16382 * 16383 * This does not return. 16384 */ 16385 common_returnFromMethod: 16386 .LreturnNew: 16387 ldrh lr, [rSELF, #offThread_subMode] 16388 SAVEAREA_FROM_FP(r0, rFP) 16389 ldr r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc 16390 cmp lr, #0 @ any special subMode handling needed? 16391 bne 19f 16392 14: 16393 ldr rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame 16394 ldr r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)] 16395 @ r2<- method we're returning to 16396 cmp r2, #0 @ is this a break frame? 16397 #if defined(WORKAROUND_CORTEX_A9_745320) 16398 /* Don't use conditional loads if the HW defect exists */ 16399 beq 15f 16400 ldr r10, [r2, #offMethod_clazz] @ r10<- method->clazz 16401 15: 16402 #else 16403 ldrne r10, [r2, #offMethod_clazz] @ r10<- method->clazz 16404 #endif 16405 beq common_gotoBail @ break frame, bail out completely 16406 16407 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 16408 PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST 16409 str r2, [rSELF, #offThread_method]@ self->method = newSave->method 16410 ldr r1, [r10, #offClassObject_pDvmDex] @ r1<- method->clazz->pDvmDex 16411 str rFP, [rSELF, #offThread_curFrame] @ curFrame = fp 16412 #if defined(WITH_JIT) 16413 ldr r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr 16414 mov rPC, r9 @ publish new rPC 16415 str r1, [rSELF, #offThread_methodClassDex] 16416 str r10, [rSELF, #offThread_inJitCodeCache] @ may return to JIT'ed land 16417 cmp r10, #0 @ caller is compiled code 16418 blxne r10 16419 GET_INST_OPCODE(ip) @ extract opcode from rINST 16420 GOTO_OPCODE(ip) @ jump to next instruction 16421 #else 16422 GET_INST_OPCODE(ip) @ extract opcode from rINST 16423 mov rPC, r9 @ publish new rPC 16424 str r1, [rSELF, #offThread_methodClassDex] 16425 GOTO_OPCODE(ip) @ jump to next instruction 16426 #endif 16427 16428 19: 16429 @ Handle special actions 16430 @ On entry, r0: StackSaveArea 16431 ldr r1, [r0, #offStackSaveArea_prevFrame] @ r2<- prevFP 16432 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16433 str r1, [rSELF, #offThread_curFrame] @ update interpSave.curFrame 16434 mov r0, rSELF 16435 bl dvmReportReturn @ (self) 16436 SAVEAREA_FROM_FP(r0, rFP) @ restore StackSaveArea 16437 b 14b @ continue 16438 16439 /* 16440 * Return handling, calls through "glue code". 16441 */ 16442 .if 0 16443 .LreturnOld: 16444 SAVE_PC_FP_TO_SELF() @ export state 16445 mov r0, rSELF @ arg to function 16446 bl dvmMterp_returnFromMethod 16447 b common_resumeAfterGlueCall 16448 .endif 16449 16450 16451 /* 16452 * Somebody has thrown an exception. Handle it. 16453 * 16454 * If the exception processing code returns to us (instead of falling 16455 * out of the interpreter), continue with whatever the next instruction 16456 * now happens to be. 16457 * 16458 * This does not return. 16459 */ 16460 .global dvmMterpCommonExceptionThrown 16461 dvmMterpCommonExceptionThrown: 16462 common_exceptionThrown: 16463 .LexceptionNew: 16464 16465 EXPORT_PC() 16466 16467 mov r0, rSELF 16468 bl dvmCheckSuspendPending 16469 16470 ldr r9, [rSELF, #offThread_exception] @ r9<- self->exception 16471 mov r1, rSELF @ r1<- self 16472 mov r0, r9 @ r0<- exception 16473 bl dvmAddTrackedAlloc @ don't let the exception be GCed 16474 ldrh r2, [rSELF, #offThread_subMode] @ get subMode flags 16475 mov r3, #0 @ r3<- NULL 16476 str r3, [rSELF, #offThread_exception] @ self->exception = NULL 16477 16478 @ Special subMode? 16479 cmp r2, #0 @ any special subMode handling needed? 16480 bne 7f @ go if so 16481 8: 16482 /* set up args and a local for "&fp" */ 16483 /* (str sp, [sp, #-4]! would be perfect here, but is discouraged) */ 16484 str rFP, [sp, #-4]! @ *--sp = fp 16485 mov ip, sp @ ip<- &fp 16486 mov r3, #0 @ r3<- false 16487 str ip, [sp, #-4]! @ *--sp = &fp 16488 ldr r1, [rSELF, #offThread_method] @ r1<- self->method 16489 mov r0, rSELF @ r0<- self 16490 ldr r1, [r1, #offMethod_insns] @ r1<- method->insns 16491 ldrh lr, [rSELF, #offThread_subMode] @ lr<- subMode flags 16492 mov r2, r9 @ r2<- exception 16493 sub r1, rPC, r1 @ r1<- pc - method->insns 16494 mov r1, r1, asr #1 @ r1<- offset in code units 16495 16496 /* call, r0 gets catchRelPc (a code-unit offset) */ 16497 bl dvmFindCatchBlock @ call(self, relPc, exc, scan?, &fp) 16498 16499 /* fix earlier stack overflow if necessary; may trash rFP */ 16500 ldrb r1, [rSELF, #offThread_stackOverflowed] 16501 cmp r1, #0 @ did we overflow earlier? 16502 beq 1f @ no, skip ahead 16503 mov rFP, r0 @ save relPc result in rFP 16504 mov r0, rSELF @ r0<- self 16505 mov r1, r9 @ r1<- exception 16506 bl dvmCleanupStackOverflow @ call(self) 16507 mov r0, rFP @ restore result 16508 1: 16509 16510 /* update frame pointer and check result from dvmFindCatchBlock */ 16511 ldr rFP, [sp, #4] @ retrieve the updated rFP 16512 cmp r0, #0 @ is catchRelPc < 0? 16513 add sp, sp, #8 @ restore stack 16514 bmi .LnotCaughtLocally 16515 16516 /* adjust locals to match self->interpSave.curFrame and updated PC */ 16517 SAVEAREA_FROM_FP(r1, rFP) @ r1<- new save area 16518 ldr r1, [r1, #offStackSaveArea_method] @ r1<- new method 16519 str r1, [rSELF, #offThread_method] @ self->method = new method 16520 ldr r2, [r1, #offMethod_clazz] @ r2<- method->clazz 16521 ldr r3, [r1, #offMethod_insns] @ r3<- method->insns 16522 ldr r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex 16523 add rPC, r3, r0, asl #1 @ rPC<- method->insns + catchRelPc 16524 str r2, [rSELF, #offThread_methodClassDex] @ self->pDvmDex = meth... 16525 16526 /* release the tracked alloc on the exception */ 16527 mov r0, r9 @ r0<- exception 16528 mov r1, rSELF @ r1<- self 16529 bl dvmReleaseTrackedAlloc @ release the exception 16530 16531 /* restore the exception if the handler wants it */ 16532 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 16533 FETCH_INST() @ load rINST from rPC 16534 GET_INST_OPCODE(ip) @ extract opcode from rINST 16535 cmp ip, #OP_MOVE_EXCEPTION @ is it "move-exception"? 16536 streq r9, [rSELF, #offThread_exception] @ yes, restore the exception 16537 GOTO_OPCODE(ip) @ jump to next instruction 16538 16539 @ Manage debugger bookkeeping 16540 7: 16541 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16542 str rFP, [rSELF, #offThread_curFrame] @ update interpSave.curFrame 16543 mov r0, rSELF @ arg0<- self 16544 mov r1, r9 @ arg1<- exception 16545 bl dvmReportExceptionThrow @ (self, exception) 16546 b 8b @ resume with normal handling 16547 16548 .LnotCaughtLocally: @ r9=exception 16549 /* fix stack overflow if necessary */ 16550 ldrb r1, [rSELF, #offThread_stackOverflowed] 16551 cmp r1, #0 @ did we overflow earlier? 16552 movne r0, rSELF @ if yes: r0<- self 16553 movne r1, r9 @ if yes: r1<- exception 16554 blne dvmCleanupStackOverflow @ if yes: call(self) 16555 16556 @ may want to show "not caught locally" debug messages here 16557 #if DVM_SHOW_EXCEPTION >= 2 16558 /* call __android_log_print(prio, tag, format, ...) */ 16559 /* "Exception %s from %s:%d not caught locally" */ 16560 @ dvmLineNumFromPC(method, pc - method->insns) 16561 ldr r0, [rSELF, #offThread_method] 16562 ldr r1, [r0, #offMethod_insns] 16563 sub r1, rPC, r1 16564 asr r1, r1, #1 16565 bl dvmLineNumFromPC 16566 str r0, [sp, #-4]! 16567 @ dvmGetMethodSourceFile(method) 16568 ldr r0, [rSELF, #offThread_method] 16569 bl dvmGetMethodSourceFile 16570 str r0, [sp, #-4]! 16571 @ exception->clazz->descriptor 16572 ldr r3, [r9, #offObject_clazz] 16573 ldr r3, [r3, #offClassObject_descriptor] 16574 @ 16575 ldr r2, strExceptionNotCaughtLocally 16576 ldr r1, strLogTag 16577 mov r0, #3 @ LOG_DEBUG 16578 bl __android_log_print 16579 #endif 16580 str r9, [rSELF, #offThread_exception] @ restore exception 16581 mov r0, r9 @ r0<- exception 16582 mov r1, rSELF @ r1<- self 16583 bl dvmReleaseTrackedAlloc @ release the exception 16584 b common_gotoBail @ bail out 16585 16586 16587 /* 16588 * Exception handling, calls through "glue code". 16589 */ 16590 .if 0 16591 .LexceptionOld: 16592 SAVE_PC_FP_TO_SELF() @ export state 16593 mov r0, rSELF @ arg to function 16594 bl dvmMterp_exceptionThrown 16595 b common_resumeAfterGlueCall 16596 .endif 16597 16598 #if defined(WITH_JIT) 16599 /* 16600 * If the JIT is actively building a trace we need to make sure 16601 * that the field is fully resolved before including the current 16602 * instruction. 16603 * 16604 * On entry: 16605 * r10: &dvmDex->pResFields[field] 16606 * r0: field pointer (must preserve) 16607 */ 16608 common_verifyField: 16609 ldrh r3, [rSELF, #offThread_subMode] @ r3 <- submode byte 16610 ands r3, #kSubModeJitTraceBuild 16611 bxeq lr @ Not building trace, continue 16612 ldr r1, [r10] @ r1<- reload resolved StaticField ptr 16613 cmp r1, #0 @ resolution complete? 16614 bxne lr @ yes, continue 16615 stmfd sp!, {r0-r2,lr} @ save regs 16616 mov r0, rSELF 16617 mov r1, rPC 16618 bl dvmJitEndTraceSelect @ (self,pc) end trace before this inst 16619 ldmfd sp!, {r0-r2, lr} 16620 bx lr @ return 16621 #endif 16622 16623 /* 16624 * After returning from a "glued" function, pull out the updated 16625 * values and start executing at the next instruction. 16626 */ 16627 common_resumeAfterGlueCall: 16628 LOAD_PC_FP_FROM_SELF() @ pull rPC and rFP out of thread 16629 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh 16630 FETCH_INST() @ load rINST from rPC 16631 GET_INST_OPCODE(ip) @ extract opcode from rINST 16632 GOTO_OPCODE(ip) @ jump to next instruction 16633 16634 /* 16635 * Invalid array index. Note that our calling convention is strange; we use r1 16636 * and r3 because those just happen to be the registers all our callers are 16637 * using. We move r3 before calling the C function, but r1 happens to match. 16638 * r1: index 16639 * r3: size 16640 */ 16641 common_errArrayIndex: 16642 EXPORT_PC() 16643 mov r0, r3 16644 bl dvmThrowArrayIndexOutOfBoundsException 16645 b common_exceptionThrown 16646 16647 /* 16648 * Integer divide or mod by zero. 16649 */ 16650 common_errDivideByZero: 16651 EXPORT_PC() 16652 ldr r0, strDivideByZero 16653 bl dvmThrowArithmeticException 16654 b common_exceptionThrown 16655 16656 /* 16657 * Attempt to allocate an array with a negative size. 16658 * On entry: length in r1 16659 */ 16660 common_errNegativeArraySize: 16661 EXPORT_PC() 16662 mov r0, r1 @ arg0 <- len 16663 bl dvmThrowNegativeArraySizeException @ (len) 16664 b common_exceptionThrown 16665 16666 /* 16667 * Invocation of a non-existent method. 16668 * On entry: method name in r1 16669 */ 16670 common_errNoSuchMethod: 16671 EXPORT_PC() 16672 mov r0, r1 16673 bl dvmThrowNoSuchMethodError 16674 b common_exceptionThrown 16675 16676 /* 16677 * We encountered a null object when we weren't expecting one. We 16678 * export the PC, throw a NullPointerException, and goto the exception 16679 * processing code. 16680 */ 16681 common_errNullObject: 16682 EXPORT_PC() 16683 mov r0, #0 16684 bl dvmThrowNullPointerException 16685 b common_exceptionThrown 16686 16687 /* 16688 * For debugging, cause an immediate fault. The source address will 16689 * be in lr (use a bl instruction to jump here). 16690 */ 16691 common_abort: 16692 ldr pc, .LdeadFood 16693 .LdeadFood: 16694 .word 0xdeadf00d 16695 16696 /* 16697 * Spit out a "we were here", preserving all registers. (The attempt 16698 * to save ip won't work, but we need to save an even number of 16699 * registers for EABI 64-bit stack alignment.) 16700 */ 16701 .macro SQUEAK num 16702 common_squeak\num: 16703 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16704 ldr r0, strSqueak 16705 mov r1, #\num 16706 bl printf 16707 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16708 bx lr 16709 .endm 16710 16711 SQUEAK 0 16712 SQUEAK 1 16713 SQUEAK 2 16714 SQUEAK 3 16715 SQUEAK 4 16716 SQUEAK 5 16717 16718 /* 16719 * Spit out the number in r0, preserving registers. 16720 */ 16721 common_printNum: 16722 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16723 mov r1, r0 16724 ldr r0, strSqueak 16725 bl printf 16726 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16727 bx lr 16728 16729 /* 16730 * Print a newline, preserving registers. 16731 */ 16732 common_printNewline: 16733 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16734 ldr r0, strNewline 16735 bl printf 16736 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16737 bx lr 16738 16739 /* 16740 * Print the 32-bit quantity in r0 as a hex value, preserving registers. 16741 */ 16742 common_printHex: 16743 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16744 mov r1, r0 16745 ldr r0, strPrintHex 16746 bl printf 16747 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16748 bx lr 16749 16750 /* 16751 * Print the 64-bit quantity in r0-r1, preserving registers. 16752 */ 16753 common_printLong: 16754 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16755 mov r3, r1 16756 mov r2, r0 16757 ldr r0, strPrintLong 16758 bl printf 16759 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16760 bx lr 16761 16762 /* 16763 * Print full method info. Pass the Method* in r0. Preserves regs. 16764 */ 16765 common_printMethod: 16766 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16767 bl dvmMterpPrintMethod 16768 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16769 bx lr 16770 16771 /* 16772 * Call a C helper function that dumps regs and possibly some 16773 * additional info. Requires the C function to be compiled in. 16774 */ 16775 .if 0 16776 common_dumpRegs: 16777 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16778 bl dvmMterpDumpArmRegs 16779 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16780 bx lr 16781 .endif 16782 16783 #if 0 16784 /* 16785 * Experiment on VFP mode. 16786 * 16787 * uint32_t setFPSCR(uint32_t val, uint32_t mask) 16788 * 16789 * Updates the bits specified by "mask", setting them to the values in "val". 16790 */ 16791 setFPSCR: 16792 and r0, r0, r1 @ make sure no stray bits are set 16793 fmrx r2, fpscr @ get VFP reg 16794 mvn r1, r1 @ bit-invert mask 16795 and r2, r2, r1 @ clear masked bits 16796 orr r2, r2, r0 @ set specified bits 16797 fmxr fpscr, r2 @ set VFP reg 16798 mov r0, r2 @ return new value 16799 bx lr 16800 16801 .align 2 16802 .global dvmConfigureFP 16803 .type dvmConfigureFP, %function 16804 dvmConfigureFP: 16805 stmfd sp!, {ip, lr} 16806 /* 0x03000000 sets DN/FZ */ 16807 /* 0x00009f00 clears the six exception enable flags */ 16808 bl common_squeak0 16809 mov r0, #0x03000000 @ r0<- 0x03000000 16810 add r1, r0, #0x9f00 @ r1<- 0x03009f00 16811 bl setFPSCR 16812 ldmfd sp!, {ip, pc} 16813 #endif 16814 16815 16816 /* 16817 * String references, must be close to the code that uses them. 16818 */ 16819 .align 2 16820 strDivideByZero: 16821 .word .LstrDivideByZero 16822 strLogTag: 16823 .word .LstrLogTag 16824 strExceptionNotCaughtLocally: 16825 .word .LstrExceptionNotCaughtLocally 16826 16827 strNewline: 16828 .word .LstrNewline 16829 strSqueak: 16830 .word .LstrSqueak 16831 strPrintHex: 16832 .word .LstrPrintHex 16833 strPrintLong: 16834 .word .LstrPrintLong 16835 16836 /* 16837 * Zero-terminated ASCII string data. 16838 * 16839 * On ARM we have two choices: do like gcc does, and LDR from a .word 16840 * with the address, or use an ADR pseudo-op to get the address 16841 * directly. ADR saves 4 bytes and an indirection, but it's using a 16842 * PC-relative addressing mode and hence has a limited range, which 16843 * makes it not work well with mergeable string sections. 16844 */ 16845 .section .rodata.str1.4,"aMS",%progbits,1 16846 16847 .LstrBadEntryPoint: 16848 .asciz "Bad entry point %d\n" 16849 .LstrFilledNewArrayNotImpl: 16850 .asciz "filled-new-array only implemented for objects and 'int'" 16851 .LstrDivideByZero: 16852 .asciz "divide by zero" 16853 .LstrLogTag: 16854 .asciz "mterp" 16855 .LstrExceptionNotCaughtLocally: 16856 .asciz "Exception %s from %s:%d not caught locally\n" 16857 16858 .LstrNewline: 16859 .asciz "\n" 16860 .LstrSqueak: 16861 .asciz "<%d>" 16862 .LstrPrintHex: 16863 .asciz "<%#x>" 16864 .LstrPrintLong: 16865 .asciz "<%lld>" 16866 16867