1 /* 2 * This file was generated automatically by gen-mterp.py for 'armv7-a-neon'. 3 * 4 * --> DO NOT EDIT <-- 5 */ 6 7 /* File: armv5te/header.S */ 8 /* 9 * Copyright (C) 2008 The Android Open Source Project 10 * 11 * Licensed under the Apache License, Version 2.0 (the "License"); 12 * you may not use this file except in compliance with the License. 13 * You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, software 18 * distributed under the License is distributed on an "AS IS" BASIS, 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 * See the License for the specific language governing permissions and 21 * limitations under the License. 22 */ 23 24 /* 25 * ARMv5 definitions and declarations. 26 */ 27 28 /* 29 ARM EABI general notes: 30 31 r0-r3 hold first 4 args to a method; they are not preserved across method calls 32 r4-r8 are available for general use 33 r9 is given special treatment in some situations, but not for us 34 r10 (sl) seems to be generally available 35 r11 (fp) is used by gcc (unless -fomit-frame-pointer is set) 36 r12 (ip) is scratch -- not preserved across method calls 37 r13 (sp) should be managed carefully in case a signal arrives 38 r14 (lr) must be preserved 39 r15 (pc) can be tinkered with directly 40 41 r0 holds returns of <= 4 bytes 42 r0-r1 hold returns of 8 bytes, low word in r0 43 44 Callee must save/restore r4+ (except r12) if it modifies them. If VFP 45 is present, registers s16-s31 (a/k/a d8-d15, a/k/a q4-q7) must be preserved, 46 s0-s15 (d0-d7, q0-a3) do not need to be. 47 48 Stack is "full descending". Only the arguments that don't fit in the first 4 49 registers are placed on the stack. "sp" points at the first stacked argument 50 (i.e. the 5th arg). 51 52 VFP: single-precision results in s0, double-precision results in d0. 53 54 In the EABI, "sp" must be 64-bit aligned on entry to a function, and any 55 64-bit quantities (long long, double) must be 64-bit aligned. 56 */ 57 58 /* 59 Mterp and ARM notes: 60 61 The following registers have fixed assignments: 62 63 reg nick purpose 64 r4 rPC interpreted program counter, used for fetching instructions 65 r5 rFP interpreted frame pointer, used for accessing locals and args 66 r6 rSELF self (Thread) pointer 67 r7 rINST first 16-bit code unit of current instruction 68 r8 rIBASE interpreted instruction base pointer, used for computed goto 69 70 Macros are provided for common operations. Each macro MUST emit only 71 one instruction to make instruction-counting easier. They MUST NOT alter 72 unspecified registers or condition codes. 73 */ 74 75 /* single-purpose registers, given names for clarity */ 76 #define rPC r4 77 #define rFP r5 78 #define rSELF r6 79 #define rINST r7 80 #define rIBASE r8 81 82 /* save/restore the PC and/or FP from the thread struct */ 83 #define LOAD_PC_FROM_SELF() ldr rPC, [rSELF, #offThread_pc] 84 #define SAVE_PC_TO_SELF() str rPC, [rSELF, #offThread_pc] 85 #define LOAD_FP_FROM_SELF() ldr rFP, [rSELF, #offThread_curFrame] 86 #define SAVE_FP_TO_SELF() str rFP, [rSELF, #offThread_curFrame] 87 #define LOAD_PC_FP_FROM_SELF() ldmia rSELF, {rPC, rFP} 88 #define SAVE_PC_FP_TO_SELF() stmia rSELF, {rPC, rFP} 89 90 /* 91 * "export" the PC to the stack frame, f/b/o future exception objects. Must 92 * be done *before* something throws. 93 * 94 * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e. 95 * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc) 96 * 97 * It's okay to do this more than once. 98 */ 99 #define EXPORT_PC() \ 100 str rPC, [rFP, #(-sizeofStackSaveArea + offStackSaveArea_currentPc)] 101 102 /* 103 * Given a frame pointer, find the stack save area. 104 * 105 * In C this is "((StackSaveArea*)(_fp) -1)". 106 */ 107 #define SAVEAREA_FROM_FP(_reg, _fpreg) \ 108 sub _reg, _fpreg, #sizeofStackSaveArea 109 110 /* 111 * Fetch the next instruction from rPC into rINST. Does not advance rPC. 112 */ 113 #define FETCH_INST() ldrh rINST, [rPC] 114 115 /* 116 * Fetch the next instruction from the specified offset. Advances rPC 117 * to point to the next instruction. "_count" is in 16-bit code units. 118 * 119 * Because of the limited size of immediate constants on ARM, this is only 120 * suitable for small forward movements (i.e. don't try to implement "goto" 121 * with this). 122 * 123 * This must come AFTER anything that can throw an exception, or the 124 * exception catch may miss. (This also implies that it must come after 125 * EXPORT_PC().) 126 */ 127 #define FETCH_ADVANCE_INST(_count) ldrh rINST, [rPC, #((_count)*2)]! 128 129 /* 130 * The operation performed here is similar to FETCH_ADVANCE_INST, except the 131 * src and dest registers are parameterized (not hard-wired to rPC and rINST). 132 */ 133 #define PREFETCH_ADVANCE_INST(_dreg, _sreg, _count) \ 134 ldrh _dreg, [_sreg, #((_count)*2)]! 135 136 /* 137 * Fetch the next instruction from an offset specified by _reg. Updates 138 * rPC to point to the next instruction. "_reg" must specify the distance 139 * in bytes, *not* 16-bit code units, and may be a signed value. 140 * 141 * We want to write "ldrh rINST, [rPC, _reg, lsl #1]!", but some of the 142 * bits that hold the shift distance are used for the half/byte/sign flags. 143 * In some cases we can pre-double _reg for free, so we require a byte offset 144 * here. 145 */ 146 #define FETCH_ADVANCE_INST_RB(_reg) ldrh rINST, [rPC, _reg]! 147 148 /* 149 * Fetch a half-word code unit from an offset past the current PC. The 150 * "_count" value is in 16-bit code units. Does not advance rPC. 151 * 152 * The "_S" variant works the same but treats the value as signed. 153 */ 154 #define FETCH(_reg, _count) ldrh _reg, [rPC, #((_count)*2)] 155 #define FETCH_S(_reg, _count) ldrsh _reg, [rPC, #((_count)*2)] 156 157 /* 158 * Fetch one byte from an offset past the current PC. Pass in the same 159 * "_count" as you would for FETCH, and an additional 0/1 indicating which 160 * byte of the halfword you want (lo/hi). 161 */ 162 #define FETCH_B(_reg, _count, _byte) ldrb _reg, [rPC, #((_count)*2+(_byte))] 163 164 /* 165 * Put the instruction's opcode field into the specified register. 166 */ 167 #define GET_INST_OPCODE(_reg) and _reg, rINST, #255 168 169 /* 170 * Put the prefetched instruction's opcode field into the specified register. 171 */ 172 #define GET_PREFETCHED_OPCODE(_oreg, _ireg) and _oreg, _ireg, #255 173 174 /* 175 * Begin executing the opcode in _reg. Because this only jumps within the 176 * interpreter, we don't have to worry about pre-ARMv5 THUMB interwork. 177 */ 178 #define GOTO_OPCODE(_reg) add pc, rIBASE, _reg, lsl #6 179 #define GOTO_OPCODE_BASE(_base,_reg) add pc, _base, _reg, lsl #6 180 #define GOTO_OPCODE_IFEQ(_reg) addeq pc, rIBASE, _reg, lsl #6 181 #define GOTO_OPCODE_IFNE(_reg) addne pc, rIBASE, _reg, lsl #6 182 183 /* 184 * Get/set the 32-bit value from a Dalvik register. 185 */ 186 #define GET_VREG(_reg, _vreg) ldr _reg, [rFP, _vreg, lsl #2] 187 #define SET_VREG(_reg, _vreg) str _reg, [rFP, _vreg, lsl #2] 188 189 /* 190 * Convert a virtual register index into an address. 191 */ 192 #define VREG_INDEX_TO_ADDR(_reg, _vreg) \ 193 add _reg, rFP, _vreg, lsl #2 194 195 /* 196 * This is a #include, not a %include, because we want the C pre-processor 197 * to expand the macros into assembler assignment statements. 198 */ 199 #include "../common/asm-constants.h" 200 201 #if defined(WITH_JIT) 202 #include "../common/jit-config.h" 203 #endif 204 205 /* File: armv7-a/platform.S */ 206 /* 207 * =========================================================================== 208 * CPU-version-specific defines 209 * =========================================================================== 210 */ 211 212 #if !defined(ANDROID_SMP) 213 # error "Must define ANDROID_SMP" 214 #endif 215 216 /* 217 * Macro for data memory barrier. 218 */ 219 .macro SMP_DMB 220 #if ANDROID_SMP != 0 221 dmb 222 #else 223 /* not SMP */ 224 #endif 225 .endm 226 227 /* 228 * Macro for data memory barrier (store/store variant). 229 */ 230 .macro SMP_DMB_ST 231 #if ANDROID_SMP != 0 232 dmb st 233 #else 234 /* not SMP */ 235 #endif 236 .endm 237 238 /* File: armv5te/entry.S */ 239 /* 240 * Copyright (C) 2008 The Android Open Source Project 241 * 242 * Licensed under the Apache License, Version 2.0 (the "License"); 243 * you may not use this file except in compliance with the License. 244 * You may obtain a copy of the License at 245 * 246 * http://www.apache.org/licenses/LICENSE-2.0 247 * 248 * Unless required by applicable law or agreed to in writing, software 249 * distributed under the License is distributed on an "AS IS" BASIS, 250 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 251 * See the License for the specific language governing permissions and 252 * limitations under the License. 253 */ 254 /* 255 * Interpreter entry point. 256 */ 257 258 /* 259 * We don't have formal stack frames, so gdb scans upward in the code 260 * to find the start of the function (a label with the %function type), 261 * and then looks at the next few instructions to figure out what 262 * got pushed onto the stack. From this it figures out how to restore 263 * the registers, including PC, for the previous stack frame. If gdb 264 * sees a non-function label, it stops scanning, so either we need to 265 * have nothing but assembler-local labels between the entry point and 266 * the break, or we need to fake it out. 267 * 268 * When this is defined, we add some stuff to make gdb less confused. 269 */ 270 #define ASSIST_DEBUGGER 1 271 272 .text 273 .align 2 274 .global dvmMterpStdRun 275 .type dvmMterpStdRun, %function 276 277 /* 278 * On entry: 279 * r0 Thread* self 280 * 281 * The return comes via a call to dvmMterpStdBail(). 282 */ 283 dvmMterpStdRun: 284 #define MTERP_ENTRY1 \ 285 .save {r4-r10,fp,lr}; \ 286 stmfd sp!, {r4-r10,fp,lr} @ save 9 regs 287 #define MTERP_ENTRY2 \ 288 .pad #4; \ 289 sub sp, sp, #4 @ align 64 290 291 .fnstart 292 MTERP_ENTRY1 293 MTERP_ENTRY2 294 295 /* save stack pointer, add magic word for debuggerd */ 296 str sp, [r0, #offThread_bailPtr] @ save SP for eventual return 297 298 /* set up "named" registers, figure out entry point */ 299 mov rSELF, r0 @ set rSELF 300 LOAD_PC_FP_FROM_SELF() @ load rPC and rFP from "thread" 301 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ set rIBASE 302 303 #if defined(WITH_JIT) 304 .LentryInstr: 305 /* Entry is always a possible trace start */ 306 ldr r0, [rSELF, #offThread_pJitProfTable] 307 FETCH_INST() 308 mov r1, #0 @ prepare the value for the new state 309 str r1, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 310 cmp r0,#0 @ is profiling disabled? 311 #if !defined(WITH_SELF_VERIFICATION) 312 bne common_updateProfile @ profiling is enabled 313 #else 314 ldr r2, [rSELF, #offThread_shadowSpace] @ to find out the jit exit state 315 beq 1f @ profiling is disabled 316 ldr r3, [r2, #offShadowSpace_jitExitState] @ jit exit state 317 cmp r3, #kSVSTraceSelect @ hot trace following? 318 moveq r2,#kJitTSelectRequestHot @ ask for trace selection 319 beq common_selectTrace @ go build the trace 320 cmp r3, #kSVSNoProfile @ don't profile the next instruction? 321 beq 1f @ intrepret the next instruction 322 b common_updateProfile @ collect profiles 323 #endif 324 1: 325 GET_INST_OPCODE(ip) 326 GOTO_OPCODE(ip) 327 #else 328 /* start executing the instruction at rPC */ 329 FETCH_INST() @ load rINST from rPC 330 GET_INST_OPCODE(ip) @ extract opcode from rINST 331 GOTO_OPCODE(ip) @ jump to next instruction 332 #endif 333 334 .Lbad_arg: 335 ldr r0, strBadEntryPoint 336 0: add r0, pc 337 @ r1 holds value of entryPoint 338 bl printf 339 bl dvmAbort 340 .fnend 341 .size dvmMterpStdRun, .-dvmMterpStdRun 342 343 strBadEntryPoint: 344 .word PCREL_REF(.LstrBadEntryPoint,0b) 345 346 .global dvmMterpStdBail 347 .type dvmMterpStdBail, %function 348 349 /* 350 * Restore the stack pointer and PC from the save point established on entry. 351 * This is essentially the same as a longjmp, but should be cheaper. The 352 * last instruction causes us to return to whoever called dvmMterpStdRun. 353 * 354 * We pushed some registers on the stack in dvmMterpStdRun, then saved 355 * SP and LR. Here we restore SP, restore the registers, and then restore 356 * LR to PC. 357 * 358 * On entry: 359 * r0 Thread* self 360 */ 361 dvmMterpStdBail: 362 ldr sp, [r0, #offThread_bailPtr] @ sp<- saved SP 363 add sp, sp, #4 @ un-align 64 364 ldmfd sp!, {r4-r10,fp,pc} @ restore 9 regs and return 365 366 367 368 .global dvmAsmInstructionStart 369 .type dvmAsmInstructionStart, %function 370 dvmAsmInstructionStart = .L_OP_NOP 371 .text 372 373 /* ------------------------------ */ 374 .balign 64 375 .L_OP_NOP: /* 0x00 */ 376 /* File: armv5te/OP_NOP.S */ 377 FETCH_ADVANCE_INST(1) @ advance to next instr, load rINST 378 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 379 GOTO_OPCODE(ip) @ execute it 380 381 #ifdef ASSIST_DEBUGGER 382 /* insert fake function header to help gdb find the stack frame */ 383 .type dalvik_inst, %function 384 dalvik_inst: 385 .fnstart 386 MTERP_ENTRY1 387 MTERP_ENTRY2 388 .fnend 389 #endif 390 391 /* ------------------------------ */ 392 .balign 64 393 .L_OP_MOVE: /* 0x01 */ 394 /* File: armv6t2/OP_MOVE.S */ 395 /* for move, move-object, long-to-int */ 396 /* op vA, vB */ 397 mov r1, rINST, lsr #12 @ r1<- B from 15:12 398 ubfx r0, rINST, #8, #4 @ r0<- A from 11:8 399 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 400 GET_VREG(r2, r1) @ r2<- fp[B] 401 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 402 SET_VREG(r2, r0) @ fp[A]<- r2 403 GOTO_OPCODE(ip) @ execute next instruction 404 405 /* ------------------------------ */ 406 .balign 64 407 .L_OP_MOVE_FROM16: /* 0x02 */ 408 /* File: armv5te/OP_MOVE_FROM16.S */ 409 /* for: move/from16, move-object/from16 */ 410 /* op vAA, vBBBB */ 411 FETCH(r1, 1) @ r1<- BBBB 412 mov r0, rINST, lsr #8 @ r0<- AA 413 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 414 GET_VREG(r2, r1) @ r2<- fp[BBBB] 415 GET_INST_OPCODE(ip) @ extract opcode from rINST 416 SET_VREG(r2, r0) @ fp[AA]<- r2 417 GOTO_OPCODE(ip) @ jump to next instruction 418 419 /* ------------------------------ */ 420 .balign 64 421 .L_OP_MOVE_16: /* 0x03 */ 422 /* File: armv5te/OP_MOVE_16.S */ 423 /* for: move/16, move-object/16 */ 424 /* op vAAAA, vBBBB */ 425 FETCH(r1, 2) @ r1<- BBBB 426 FETCH(r0, 1) @ r0<- AAAA 427 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 428 GET_VREG(r2, r1) @ r2<- fp[BBBB] 429 GET_INST_OPCODE(ip) @ extract opcode from rINST 430 SET_VREG(r2, r0) @ fp[AAAA]<- r2 431 GOTO_OPCODE(ip) @ jump to next instruction 432 433 /* ------------------------------ */ 434 .balign 64 435 .L_OP_MOVE_WIDE: /* 0x04 */ 436 /* File: armv6t2/OP_MOVE_WIDE.S */ 437 /* move-wide vA, vB */ 438 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 439 mov r3, rINST, lsr #12 @ r3<- B 440 ubfx r2, rINST, #8, #4 @ r2<- A 441 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 442 add r2, rFP, r2, lsl #2 @ r2<- &fp[A] 443 ldmia r3, {r0-r1} @ r0/r1<- fp[B] 444 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 445 GET_INST_OPCODE(ip) @ extract opcode from rINST 446 stmia r2, {r0-r1} @ fp[A]<- r0/r1 447 GOTO_OPCODE(ip) @ jump to next instruction 448 449 /* ------------------------------ */ 450 .balign 64 451 .L_OP_MOVE_WIDE_FROM16: /* 0x05 */ 452 /* File: armv5te/OP_MOVE_WIDE_FROM16.S */ 453 /* move-wide/from16 vAA, vBBBB */ 454 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 455 FETCH(r3, 1) @ r3<- BBBB 456 mov r2, rINST, lsr #8 @ r2<- AA 457 add r3, rFP, r3, lsl #2 @ r3<- &fp[BBBB] 458 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 459 ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB] 460 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 461 GET_INST_OPCODE(ip) @ extract opcode from rINST 462 stmia r2, {r0-r1} @ fp[AA]<- r0/r1 463 GOTO_OPCODE(ip) @ jump to next instruction 464 465 /* ------------------------------ */ 466 .balign 64 467 .L_OP_MOVE_WIDE_16: /* 0x06 */ 468 /* File: armv5te/OP_MOVE_WIDE_16.S */ 469 /* move-wide/16 vAAAA, vBBBB */ 470 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 471 FETCH(r3, 2) @ r3<- BBBB 472 FETCH(r2, 1) @ r2<- AAAA 473 add r3, rFP, r3, lsl #2 @ r3<- &fp[BBBB] 474 add r2, rFP, r2, lsl #2 @ r2<- &fp[AAAA] 475 ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB] 476 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 477 stmia r2, {r0-r1} @ fp[AAAA]<- r0/r1 478 GET_INST_OPCODE(ip) @ extract opcode from rINST 479 GOTO_OPCODE(ip) @ jump to next instruction 480 481 /* ------------------------------ */ 482 .balign 64 483 .L_OP_MOVE_OBJECT: /* 0x07 */ 484 /* File: armv5te/OP_MOVE_OBJECT.S */ 485 /* File: armv5te/OP_MOVE.S */ 486 /* for move, move-object, long-to-int */ 487 /* op vA, vB */ 488 mov r1, rINST, lsr #12 @ r1<- B from 15:12 489 mov r0, rINST, lsr #8 @ r0<- A from 11:8 490 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 491 GET_VREG(r2, r1) @ r2<- fp[B] 492 and r0, r0, #15 493 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 494 SET_VREG(r2, r0) @ fp[A]<- r2 495 GOTO_OPCODE(ip) @ execute next instruction 496 497 498 /* ------------------------------ */ 499 .balign 64 500 .L_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 501 /* File: armv5te/OP_MOVE_OBJECT_FROM16.S */ 502 /* File: armv5te/OP_MOVE_FROM16.S */ 503 /* for: move/from16, move-object/from16 */ 504 /* op vAA, vBBBB */ 505 FETCH(r1, 1) @ r1<- BBBB 506 mov r0, rINST, lsr #8 @ r0<- AA 507 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 508 GET_VREG(r2, r1) @ r2<- fp[BBBB] 509 GET_INST_OPCODE(ip) @ extract opcode from rINST 510 SET_VREG(r2, r0) @ fp[AA]<- r2 511 GOTO_OPCODE(ip) @ jump to next instruction 512 513 514 /* ------------------------------ */ 515 .balign 64 516 .L_OP_MOVE_OBJECT_16: /* 0x09 */ 517 /* File: armv5te/OP_MOVE_OBJECT_16.S */ 518 /* File: armv5te/OP_MOVE_16.S */ 519 /* for: move/16, move-object/16 */ 520 /* op vAAAA, vBBBB */ 521 FETCH(r1, 2) @ r1<- BBBB 522 FETCH(r0, 1) @ r0<- AAAA 523 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 524 GET_VREG(r2, r1) @ r2<- fp[BBBB] 525 GET_INST_OPCODE(ip) @ extract opcode from rINST 526 SET_VREG(r2, r0) @ fp[AAAA]<- r2 527 GOTO_OPCODE(ip) @ jump to next instruction 528 529 530 /* ------------------------------ */ 531 .balign 64 532 .L_OP_MOVE_RESULT: /* 0x0a */ 533 /* File: armv5te/OP_MOVE_RESULT.S */ 534 /* for: move-result, move-result-object */ 535 /* op vAA */ 536 mov r2, rINST, lsr #8 @ r2<- AA 537 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 538 ldr r0, [rSELF, #offThread_retval] @ r0<- self->retval.i 539 GET_INST_OPCODE(ip) @ extract opcode from rINST 540 SET_VREG(r0, r2) @ fp[AA]<- r0 541 GOTO_OPCODE(ip) @ jump to next instruction 542 543 /* ------------------------------ */ 544 .balign 64 545 .L_OP_MOVE_RESULT_WIDE: /* 0x0b */ 546 /* File: armv5te/OP_MOVE_RESULT_WIDE.S */ 547 /* move-result-wide vAA */ 548 mov r2, rINST, lsr #8 @ r2<- AA 549 add r3, rSELF, #offThread_retval @ r3<- &self->retval 550 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 551 ldmia r3, {r0-r1} @ r0/r1<- retval.j 552 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 553 stmia r2, {r0-r1} @ fp[AA]<- r0/r1 554 GET_INST_OPCODE(ip) @ extract opcode from rINST 555 GOTO_OPCODE(ip) @ jump to next instruction 556 557 /* ------------------------------ */ 558 .balign 64 559 .L_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 560 /* File: armv5te/OP_MOVE_RESULT_OBJECT.S */ 561 /* File: armv5te/OP_MOVE_RESULT.S */ 562 /* for: move-result, move-result-object */ 563 /* op vAA */ 564 mov r2, rINST, lsr #8 @ r2<- AA 565 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 566 ldr r0, [rSELF, #offThread_retval] @ r0<- self->retval.i 567 GET_INST_OPCODE(ip) @ extract opcode from rINST 568 SET_VREG(r0, r2) @ fp[AA]<- r0 569 GOTO_OPCODE(ip) @ jump to next instruction 570 571 572 /* ------------------------------ */ 573 .balign 64 574 .L_OP_MOVE_EXCEPTION: /* 0x0d */ 575 /* File: armv5te/OP_MOVE_EXCEPTION.S */ 576 /* move-exception vAA */ 577 mov r2, rINST, lsr #8 @ r2<- AA 578 ldr r3, [rSELF, #offThread_exception] @ r3<- dvmGetException bypass 579 mov r1, #0 @ r1<- 0 580 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 581 SET_VREG(r3, r2) @ fp[AA]<- exception obj 582 GET_INST_OPCODE(ip) @ extract opcode from rINST 583 str r1, [rSELF, #offThread_exception] @ dvmClearException bypass 584 GOTO_OPCODE(ip) @ jump to next instruction 585 586 /* ------------------------------ */ 587 .balign 64 588 .L_OP_RETURN_VOID: /* 0x0e */ 589 /* File: armv5te/OP_RETURN_VOID.S */ 590 b common_returnFromMethod 591 592 /* ------------------------------ */ 593 .balign 64 594 .L_OP_RETURN: /* 0x0f */ 595 /* File: armv5te/OP_RETURN.S */ 596 /* 597 * Return a 32-bit value. Copies the return value into the "thread" 598 * structure, then jumps to the return handler. 599 * 600 * for: return, return-object 601 */ 602 /* op vAA */ 603 mov r2, rINST, lsr #8 @ r2<- AA 604 GET_VREG(r0, r2) @ r0<- vAA 605 str r0, [rSELF, #offThread_retval] @ retval.i <- vAA 606 b common_returnFromMethod 607 608 /* ------------------------------ */ 609 .balign 64 610 .L_OP_RETURN_WIDE: /* 0x10 */ 611 /* File: armv5te/OP_RETURN_WIDE.S */ 612 /* 613 * Return a 64-bit value. Copies the return value into the "thread" 614 * structure, then jumps to the return handler. 615 */ 616 /* return-wide vAA */ 617 mov r2, rINST, lsr #8 @ r2<- AA 618 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 619 add r3, rSELF, #offThread_retval @ r3<- &self->retval 620 ldmia r2, {r0-r1} @ r0/r1 <- vAA/vAA+1 621 stmia r3, {r0-r1} @ retval<- r0/r1 622 b common_returnFromMethod 623 624 /* ------------------------------ */ 625 .balign 64 626 .L_OP_RETURN_OBJECT: /* 0x11 */ 627 /* File: armv5te/OP_RETURN_OBJECT.S */ 628 /* File: armv5te/OP_RETURN.S */ 629 /* 630 * Return a 32-bit value. Copies the return value into the "thread" 631 * structure, then jumps to the return handler. 632 * 633 * for: return, return-object 634 */ 635 /* op vAA */ 636 mov r2, rINST, lsr #8 @ r2<- AA 637 GET_VREG(r0, r2) @ r0<- vAA 638 str r0, [rSELF, #offThread_retval] @ retval.i <- vAA 639 b common_returnFromMethod 640 641 642 /* ------------------------------ */ 643 .balign 64 644 .L_OP_CONST_4: /* 0x12 */ 645 /* File: armv6t2/OP_CONST_4.S */ 646 /* const/4 vA, #+B */ 647 mov r1, rINST, lsl #16 @ r1<- Bxxx0000 648 ubfx r0, rINST, #8, #4 @ r0<- A 649 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 650 mov r1, r1, asr #28 @ r1<- sssssssB (sign-extended) 651 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 652 SET_VREG(r1, r0) @ fp[A]<- r1 653 GOTO_OPCODE(ip) @ execute next instruction 654 655 /* ------------------------------ */ 656 .balign 64 657 .L_OP_CONST_16: /* 0x13 */ 658 /* File: armv5te/OP_CONST_16.S */ 659 /* const/16 vAA, #+BBBB */ 660 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 661 mov r3, rINST, lsr #8 @ r3<- AA 662 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 663 SET_VREG(r0, r3) @ vAA<- r0 664 GET_INST_OPCODE(ip) @ extract opcode from rINST 665 GOTO_OPCODE(ip) @ jump to next instruction 666 667 /* ------------------------------ */ 668 .balign 64 669 .L_OP_CONST: /* 0x14 */ 670 /* File: armv5te/OP_CONST.S */ 671 /* const vAA, #+BBBBbbbb */ 672 mov r3, rINST, lsr #8 @ r3<- AA 673 FETCH(r0, 1) @ r0<- bbbb (low) 674 FETCH(r1, 2) @ r1<- BBBB (high) 675 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 676 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 677 GET_INST_OPCODE(ip) @ extract opcode from rINST 678 SET_VREG(r0, r3) @ vAA<- r0 679 GOTO_OPCODE(ip) @ jump to next instruction 680 681 /* ------------------------------ */ 682 .balign 64 683 .L_OP_CONST_HIGH16: /* 0x15 */ 684 /* File: armv5te/OP_CONST_HIGH16.S */ 685 /* const/high16 vAA, #+BBBB0000 */ 686 FETCH(r0, 1) @ r0<- 0000BBBB (zero-extended) 687 mov r3, rINST, lsr #8 @ r3<- AA 688 mov r0, r0, lsl #16 @ r0<- BBBB0000 689 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 690 SET_VREG(r0, r3) @ vAA<- r0 691 GET_INST_OPCODE(ip) @ extract opcode from rINST 692 GOTO_OPCODE(ip) @ jump to next instruction 693 694 /* ------------------------------ */ 695 .balign 64 696 .L_OP_CONST_WIDE_16: /* 0x16 */ 697 /* File: armv5te/OP_CONST_WIDE_16.S */ 698 /* const-wide/16 vAA, #+BBBB */ 699 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 700 mov r3, rINST, lsr #8 @ r3<- AA 701 mov r1, r0, asr #31 @ r1<- ssssssss 702 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 703 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 704 GET_INST_OPCODE(ip) @ extract opcode from rINST 705 stmia r3, {r0-r1} @ vAA<- r0/r1 706 GOTO_OPCODE(ip) @ jump to next instruction 707 708 /* ------------------------------ */ 709 .balign 64 710 .L_OP_CONST_WIDE_32: /* 0x17 */ 711 /* File: armv5te/OP_CONST_WIDE_32.S */ 712 /* const-wide/32 vAA, #+BBBBbbbb */ 713 FETCH(r0, 1) @ r0<- 0000bbbb (low) 714 mov r3, rINST, lsr #8 @ r3<- AA 715 FETCH_S(r2, 2) @ r2<- ssssBBBB (high) 716 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 717 orr r0, r0, r2, lsl #16 @ r0<- BBBBbbbb 718 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 719 mov r1, r0, asr #31 @ r1<- ssssssss 720 GET_INST_OPCODE(ip) @ extract opcode from rINST 721 stmia r3, {r0-r1} @ vAA<- r0/r1 722 GOTO_OPCODE(ip) @ jump to next instruction 723 724 /* ------------------------------ */ 725 .balign 64 726 .L_OP_CONST_WIDE: /* 0x18 */ 727 /* File: armv5te/OP_CONST_WIDE.S */ 728 /* const-wide vAA, #+HHHHhhhhBBBBbbbb */ 729 FETCH(r0, 1) @ r0<- bbbb (low) 730 FETCH(r1, 2) @ r1<- BBBB (low middle) 731 FETCH(r2, 3) @ r2<- hhhh (high middle) 732 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb (low word) 733 FETCH(r3, 4) @ r3<- HHHH (high) 734 mov r9, rINST, lsr #8 @ r9<- AA 735 orr r1, r2, r3, lsl #16 @ r1<- HHHHhhhh (high word) 736 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 737 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 738 GET_INST_OPCODE(ip) @ extract opcode from rINST 739 stmia r9, {r0-r1} @ vAA<- r0/r1 740 GOTO_OPCODE(ip) @ jump to next instruction 741 742 /* ------------------------------ */ 743 .balign 64 744 .L_OP_CONST_WIDE_HIGH16: /* 0x19 */ 745 /* File: armv5te/OP_CONST_WIDE_HIGH16.S */ 746 /* const-wide/high16 vAA, #+BBBB000000000000 */ 747 FETCH(r1, 1) @ r1<- 0000BBBB (zero-extended) 748 mov r3, rINST, lsr #8 @ r3<- AA 749 mov r0, #0 @ r0<- 00000000 750 mov r1, r1, lsl #16 @ r1<- BBBB0000 751 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 752 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 753 GET_INST_OPCODE(ip) @ extract opcode from rINST 754 stmia r3, {r0-r1} @ vAA<- r0/r1 755 GOTO_OPCODE(ip) @ jump to next instruction 756 757 /* ------------------------------ */ 758 .balign 64 759 .L_OP_CONST_STRING: /* 0x1a */ 760 /* File: armv5te/OP_CONST_STRING.S */ 761 /* const/string vAA, String@BBBB */ 762 FETCH(r1, 1) @ r1<- BBBB 763 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 764 mov r9, rINST, lsr #8 @ r9<- AA 765 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 766 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 767 cmp r0, #0 @ not yet resolved? 768 beq .LOP_CONST_STRING_resolve 769 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 770 SET_VREG(r0, r9) @ vAA<- r0 771 GET_INST_OPCODE(ip) @ extract opcode from rINST 772 GOTO_OPCODE(ip) @ jump to next instruction 773 774 /* ------------------------------ */ 775 .balign 64 776 .L_OP_CONST_STRING_JUMBO: /* 0x1b */ 777 /* File: armv5te/OP_CONST_STRING_JUMBO.S */ 778 /* const/string vAA, String@BBBBBBBB */ 779 FETCH(r0, 1) @ r0<- bbbb (low) 780 FETCH(r1, 2) @ r1<- BBBB (high) 781 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 782 mov r9, rINST, lsr #8 @ r9<- AA 783 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 784 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 785 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 786 cmp r0, #0 787 beq .LOP_CONST_STRING_JUMBO_resolve 788 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 789 SET_VREG(r0, r9) @ vAA<- r0 790 GET_INST_OPCODE(ip) @ extract opcode from rINST 791 GOTO_OPCODE(ip) @ jump to next instruction 792 793 /* ------------------------------ */ 794 .balign 64 795 .L_OP_CONST_CLASS: /* 0x1c */ 796 /* File: armv5te/OP_CONST_CLASS.S */ 797 /* const/class vAA, Class@BBBB */ 798 FETCH(r1, 1) @ r1<- BBBB 799 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 800 mov r9, rINST, lsr #8 @ r9<- AA 801 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- dvmDex->pResClasses 802 ldr r0, [r2, r1, lsl #2] @ r0<- pResClasses[BBBB] 803 cmp r0, #0 @ not yet resolved? 804 beq .LOP_CONST_CLASS_resolve 805 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 806 SET_VREG(r0, r9) @ vAA<- r0 807 GET_INST_OPCODE(ip) @ extract opcode from rINST 808 GOTO_OPCODE(ip) @ jump to next instruction 809 810 /* ------------------------------ */ 811 .balign 64 812 .L_OP_MONITOR_ENTER: /* 0x1d */ 813 /* File: armv5te/OP_MONITOR_ENTER.S */ 814 /* 815 * Synchronize on an object. 816 */ 817 /* monitor-enter vAA */ 818 mov r2, rINST, lsr #8 @ r2<- AA 819 GET_VREG(r1, r2) @ r1<- vAA (object) 820 mov r0, rSELF @ r0<- self 821 cmp r1, #0 @ null object? 822 EXPORT_PC() @ need for precise GC 823 beq common_errNullObject @ null object, throw an exception 824 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 825 bl dvmLockObject @ call(self, obj) 826 GET_INST_OPCODE(ip) @ extract opcode from rINST 827 GOTO_OPCODE(ip) @ jump to next instruction 828 829 /* ------------------------------ */ 830 .balign 64 831 .L_OP_MONITOR_EXIT: /* 0x1e */ 832 /* File: armv5te/OP_MONITOR_EXIT.S */ 833 /* 834 * Unlock an object. 835 * 836 * Exceptions that occur when unlocking a monitor need to appear as 837 * if they happened at the following instruction. See the Dalvik 838 * instruction spec. 839 */ 840 /* monitor-exit vAA */ 841 mov r2, rINST, lsr #8 @ r2<- AA 842 EXPORT_PC() @ before fetch: export the PC 843 GET_VREG(r1, r2) @ r1<- vAA (object) 844 cmp r1, #0 @ null object? 845 beq 1f @ yes 846 mov r0, rSELF @ r0<- self 847 bl dvmUnlockObject @ r0<- success for unlock(self, obj) 848 cmp r0, #0 @ failed? 849 FETCH_ADVANCE_INST(1) @ before throw: advance rPC, load rINST 850 beq common_exceptionThrown @ yes, exception is pending 851 GET_INST_OPCODE(ip) @ extract opcode from rINST 852 GOTO_OPCODE(ip) @ jump to next instruction 853 1: 854 FETCH_ADVANCE_INST(1) @ advance before throw 855 b common_errNullObject 856 857 /* ------------------------------ */ 858 .balign 64 859 .L_OP_CHECK_CAST: /* 0x1f */ 860 /* File: armv5te/OP_CHECK_CAST.S */ 861 /* 862 * Check to see if a cast from one class to another is allowed. 863 */ 864 /* check-cast vAA, class@BBBB */ 865 mov r3, rINST, lsr #8 @ r3<- AA 866 FETCH(r2, 1) @ r2<- BBBB 867 GET_VREG(r9, r3) @ r9<- object 868 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- pDvmDex 869 cmp r9, #0 @ is object null? 870 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 871 beq .LOP_CHECK_CAST_okay @ null obj, cast always succeeds 872 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 873 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 874 cmp r1, #0 @ have we resolved this before? 875 beq .LOP_CHECK_CAST_resolve @ not resolved, do it now 876 .LOP_CHECK_CAST_resolved: 877 cmp r0, r1 @ same class (trivial success)? 878 bne .LOP_CHECK_CAST_fullcheck @ no, do full check 879 .LOP_CHECK_CAST_okay: 880 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 881 GET_INST_OPCODE(ip) @ extract opcode from rINST 882 GOTO_OPCODE(ip) @ jump to next instruction 883 884 /* ------------------------------ */ 885 .balign 64 886 .L_OP_INSTANCE_OF: /* 0x20 */ 887 /* File: armv5te/OP_INSTANCE_OF.S */ 888 /* 889 * Check to see if an object reference is an instance of a class. 890 * 891 * Most common situation is a non-null object, being compared against 892 * an already-resolved class. 893 */ 894 /* instance-of vA, vB, class@CCCC */ 895 mov r3, rINST, lsr #12 @ r3<- B 896 mov r9, rINST, lsr #8 @ r9<- A+ 897 GET_VREG(r0, r3) @ r0<- vB (object) 898 and r9, r9, #15 @ r9<- A 899 cmp r0, #0 @ is object null? 900 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- pDvmDex 901 beq .LOP_INSTANCE_OF_store @ null obj, not an instance, store r0 902 FETCH(r3, 1) @ r3<- CCCC 903 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 904 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 905 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 906 cmp r1, #0 @ have we resolved this before? 907 beq .LOP_INSTANCE_OF_resolve @ not resolved, do it now 908 .LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class 909 cmp r0, r1 @ same class (trivial success)? 910 beq .LOP_INSTANCE_OF_trivial @ yes, trivial finish 911 b .LOP_INSTANCE_OF_fullcheck @ no, do full check 912 913 /* ------------------------------ */ 914 .balign 64 915 .L_OP_ARRAY_LENGTH: /* 0x21 */ 916 /* File: armv6t2/OP_ARRAY_LENGTH.S */ 917 /* 918 * Return the length of an array. 919 */ 920 mov r1, rINST, lsr #12 @ r1<- B 921 ubfx r2, rINST, #8, #4 @ r2<- A 922 GET_VREG(r0, r1) @ r0<- vB (object ref) 923 cmp r0, #0 @ is object null? 924 beq common_errNullObject @ yup, fail 925 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 926 ldr r3, [r0, #offArrayObject_length] @ r3<- array length 927 GET_INST_OPCODE(ip) @ extract opcode from rINST 928 SET_VREG(r3, r2) @ vB<- length 929 GOTO_OPCODE(ip) @ jump to next instruction 930 931 /* ------------------------------ */ 932 .balign 64 933 .L_OP_NEW_INSTANCE: /* 0x22 */ 934 /* File: armv5te/OP_NEW_INSTANCE.S */ 935 /* 936 * Create a new instance of a class. 937 */ 938 /* new-instance vAA, class@BBBB */ 939 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 940 FETCH(r1, 1) @ r1<- BBBB 941 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 942 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 943 #if defined(WITH_JIT) 944 add r10, r3, r1, lsl #2 @ r10<- &resolved_class 945 #endif 946 EXPORT_PC() @ req'd for init, resolve, alloc 947 cmp r0, #0 @ already resolved? 948 beq .LOP_NEW_INSTANCE_resolve @ no, resolve it now 949 .LOP_NEW_INSTANCE_resolved: @ r0=class 950 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 951 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 952 bne .LOP_NEW_INSTANCE_needinit @ no, init class now 953 .LOP_NEW_INSTANCE_initialized: @ r0=class 954 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 955 bl dvmAllocObject @ r0<- new object 956 b .LOP_NEW_INSTANCE_finish @ continue 957 958 /* ------------------------------ */ 959 .balign 64 960 .L_OP_NEW_ARRAY: /* 0x23 */ 961 /* File: armv5te/OP_NEW_ARRAY.S */ 962 /* 963 * Allocate an array of objects, specified with the array class 964 * and a count. 965 * 966 * The verifier guarantees that this is an array class, so we don't 967 * check for it here. 968 */ 969 /* new-array vA, vB, class@CCCC */ 970 mov r0, rINST, lsr #12 @ r0<- B 971 FETCH(r2, 1) @ r2<- CCCC 972 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 973 GET_VREG(r1, r0) @ r1<- vB (array length) 974 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 975 cmp r1, #0 @ check length 976 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 977 bmi common_errNegativeArraySize @ negative length, bail - len in r1 978 cmp r0, #0 @ already resolved? 979 EXPORT_PC() @ req'd for resolve, alloc 980 bne .LOP_NEW_ARRAY_finish @ resolved, continue 981 b .LOP_NEW_ARRAY_resolve @ do resolve now 982 983 /* ------------------------------ */ 984 .balign 64 985 .L_OP_FILLED_NEW_ARRAY: /* 0x24 */ 986 /* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 987 /* 988 * Create a new array with elements filled from registers. 989 * 990 * for: filled-new-array, filled-new-array/range 991 */ 992 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 993 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 994 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 995 FETCH(r1, 1) @ r1<- BBBB 996 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 997 EXPORT_PC() @ need for resolve and alloc 998 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 999 mov r10, rINST, lsr #8 @ r10<- AA or BA 1000 cmp r0, #0 @ already resolved? 1001 bne .LOP_FILLED_NEW_ARRAY_continue @ yes, continue on 1002 8: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 1003 mov r2, #0 @ r2<- false 1004 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1005 bl dvmResolveClass @ r0<- call(clazz, ref) 1006 cmp r0, #0 @ got null? 1007 beq common_exceptionThrown @ yes, handle exception 1008 b .LOP_FILLED_NEW_ARRAY_continue 1009 1010 /* ------------------------------ */ 1011 .balign 64 1012 .L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 1013 /* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */ 1014 /* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1015 /* 1016 * Create a new array with elements filled from registers. 1017 * 1018 * for: filled-new-array, filled-new-array/range 1019 */ 1020 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1021 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1022 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 1023 FETCH(r1, 1) @ r1<- BBBB 1024 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1025 EXPORT_PC() @ need for resolve and alloc 1026 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1027 mov r10, rINST, lsr #8 @ r10<- AA or BA 1028 cmp r0, #0 @ already resolved? 1029 bne .LOP_FILLED_NEW_ARRAY_RANGE_continue @ yes, continue on 1030 8: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 1031 mov r2, #0 @ r2<- false 1032 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1033 bl dvmResolveClass @ r0<- call(clazz, ref) 1034 cmp r0, #0 @ got null? 1035 beq common_exceptionThrown @ yes, handle exception 1036 b .LOP_FILLED_NEW_ARRAY_RANGE_continue 1037 1038 1039 /* ------------------------------ */ 1040 .balign 64 1041 .L_OP_FILL_ARRAY_DATA: /* 0x26 */ 1042 /* File: armv5te/OP_FILL_ARRAY_DATA.S */ 1043 /* fill-array-data vAA, +BBBBBBBB */ 1044 FETCH(r0, 1) @ r0<- bbbb (lo) 1045 FETCH(r1, 2) @ r1<- BBBB (hi) 1046 mov r3, rINST, lsr #8 @ r3<- AA 1047 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 1048 GET_VREG(r0, r3) @ r0<- vAA (array object) 1049 add r1, rPC, r1, lsl #1 @ r1<- PC + BBBBbbbb*2 (array data off.) 1050 EXPORT_PC(); 1051 bl dvmInterpHandleFillArrayData@ fill the array with predefined data 1052 cmp r0, #0 @ 0 means an exception is thrown 1053 beq common_exceptionThrown @ has exception 1054 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 1055 GET_INST_OPCODE(ip) @ extract opcode from rINST 1056 GOTO_OPCODE(ip) @ jump to next instruction 1057 1058 /* ------------------------------ */ 1059 .balign 64 1060 .L_OP_THROW: /* 0x27 */ 1061 /* File: armv5te/OP_THROW.S */ 1062 /* 1063 * Throw an exception object in the current thread. 1064 */ 1065 /* throw vAA */ 1066 mov r2, rINST, lsr #8 @ r2<- AA 1067 GET_VREG(r1, r2) @ r1<- vAA (exception object) 1068 EXPORT_PC() @ exception handler can throw 1069 cmp r1, #0 @ null object? 1070 beq common_errNullObject @ yes, throw an NPE instead 1071 @ bypass dvmSetException, just store it 1072 str r1, [rSELF, #offThread_exception] @ thread->exception<- obj 1073 b common_exceptionThrown 1074 1075 /* ------------------------------ */ 1076 .balign 64 1077 .L_OP_GOTO: /* 0x28 */ 1078 /* File: armv5te/OP_GOTO.S */ 1079 /* 1080 * Unconditional branch, 8-bit offset. 1081 * 1082 * The branch distance is a signed code-unit offset, which we need to 1083 * double to get a byte offset. 1084 */ 1085 /* goto +AA */ 1086 /* tuning: use sbfx for 6t2+ targets */ 1087 mov r0, rINST, lsl #16 @ r0<- AAxx0000 1088 movs r1, r0, asr #24 @ r1<- ssssssAA (sign-extended) 1089 add r2, r1, r1 @ r2<- byte offset, set flags 1090 @ If backwards branch refresh rIBASE 1091 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1092 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1093 #if defined(WITH_JIT) 1094 ldr r0, [rSELF, #offThread_pJitProfTable] 1095 bmi common_testUpdateProfile @ (r0) check for trace hotness 1096 #endif 1097 GET_INST_OPCODE(ip) @ extract opcode from rINST 1098 GOTO_OPCODE(ip) @ jump to next instruction 1099 1100 /* ------------------------------ */ 1101 .balign 64 1102 .L_OP_GOTO_16: /* 0x29 */ 1103 /* File: armv5te/OP_GOTO_16.S */ 1104 /* 1105 * Unconditional branch, 16-bit offset. 1106 * 1107 * The branch distance is a signed code-unit offset, which we need to 1108 * double to get a byte offset. 1109 */ 1110 /* goto/16 +AAAA */ 1111 FETCH_S(r0, 1) @ r0<- ssssAAAA (sign-extended) 1112 adds r1, r0, r0 @ r1<- byte offset, flags set 1113 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1114 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1115 #if defined(WITH_JIT) 1116 ldr r0, [rSELF, #offThread_pJitProfTable] 1117 bmi common_testUpdateProfile @ (r0) hot trace head? 1118 #endif 1119 GET_INST_OPCODE(ip) @ extract opcode from rINST 1120 GOTO_OPCODE(ip) @ jump to next instruction 1121 1122 /* ------------------------------ */ 1123 .balign 64 1124 .L_OP_GOTO_32: /* 0x2a */ 1125 /* File: armv5te/OP_GOTO_32.S */ 1126 /* 1127 * Unconditional branch, 32-bit offset. 1128 * 1129 * The branch distance is a signed code-unit offset, which we need to 1130 * double to get a byte offset. 1131 * 1132 * Unlike most opcodes, this one is allowed to branch to itself, so 1133 * our "backward branch" test must be "<=0" instead of "<0". Because 1134 * we need the V bit set, we'll use an adds to convert from Dalvik 1135 * offset to byte offset. 1136 */ 1137 /* goto/32 +AAAAAAAA */ 1138 FETCH(r0, 1) @ r0<- aaaa (lo) 1139 FETCH(r1, 2) @ r1<- AAAA (hi) 1140 orr r0, r0, r1, lsl #16 @ r0<- AAAAaaaa 1141 adds r1, r0, r0 @ r1<- byte offset 1142 #if defined(WITH_JIT) 1143 ldr r0, [rSELF, #offThread_pJitProfTable] 1144 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1145 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1146 ble common_testUpdateProfile @ (r0) hot trace head? 1147 #else 1148 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1149 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1150 #endif 1151 GET_INST_OPCODE(ip) @ extract opcode from rINST 1152 GOTO_OPCODE(ip) @ jump to next instruction 1153 1154 /* ------------------------------ */ 1155 .balign 64 1156 .L_OP_PACKED_SWITCH: /* 0x2b */ 1157 /* File: armv5te/OP_PACKED_SWITCH.S */ 1158 /* 1159 * Handle a packed-switch or sparse-switch instruction. In both cases 1160 * we decode it and hand it off to a helper function. 1161 * 1162 * We don't really expect backward branches in a switch statement, but 1163 * they're perfectly legal, so we check for them here. 1164 * 1165 * When the JIT is present, all targets are considered treated as 1166 * a potential trace heads regardless of branch direction. 1167 * 1168 * for: packed-switch, sparse-switch 1169 */ 1170 /* op vAA, +BBBB */ 1171 FETCH(r0, 1) @ r0<- bbbb (lo) 1172 FETCH(r1, 2) @ r1<- BBBB (hi) 1173 mov r3, rINST, lsr #8 @ r3<- AA 1174 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1175 GET_VREG(r1, r3) @ r1<- vAA 1176 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1177 bl dvmInterpHandlePackedSwitch @ r0<- code-unit branch offset 1178 adds r1, r0, r0 @ r1<- byte offset; clear V 1179 #if defined(WITH_JIT) 1180 ldr r0, [rSELF, #offThread_pJitProfTable] 1181 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1182 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1183 cmp r0, #0 1184 bne common_updateProfile 1185 #else 1186 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1187 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1188 #endif 1189 GET_INST_OPCODE(ip) @ extract opcode from rINST 1190 GOTO_OPCODE(ip) @ jump to next instruction 1191 1192 /* ------------------------------ */ 1193 .balign 64 1194 .L_OP_SPARSE_SWITCH: /* 0x2c */ 1195 /* File: armv5te/OP_SPARSE_SWITCH.S */ 1196 /* File: armv5te/OP_PACKED_SWITCH.S */ 1197 /* 1198 * Handle a packed-switch or sparse-switch instruction. In both cases 1199 * we decode it and hand it off to a helper function. 1200 * 1201 * We don't really expect backward branches in a switch statement, but 1202 * they're perfectly legal, so we check for them here. 1203 * 1204 * When the JIT is present, all targets are considered treated as 1205 * a potential trace heads regardless of branch direction. 1206 * 1207 * for: packed-switch, sparse-switch 1208 */ 1209 /* op vAA, +BBBB */ 1210 FETCH(r0, 1) @ r0<- bbbb (lo) 1211 FETCH(r1, 2) @ r1<- BBBB (hi) 1212 mov r3, rINST, lsr #8 @ r3<- AA 1213 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1214 GET_VREG(r1, r3) @ r1<- vAA 1215 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1216 bl dvmInterpHandleSparseSwitch @ r0<- code-unit branch offset 1217 adds r1, r0, r0 @ r1<- byte offset; clear V 1218 #if defined(WITH_JIT) 1219 ldr r0, [rSELF, #offThread_pJitProfTable] 1220 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1221 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1222 cmp r0, #0 1223 bne common_updateProfile 1224 #else 1225 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1226 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1227 #endif 1228 GET_INST_OPCODE(ip) @ extract opcode from rINST 1229 GOTO_OPCODE(ip) @ jump to next instruction 1230 1231 1232 /* ------------------------------ */ 1233 .balign 64 1234 .L_OP_CMPL_FLOAT: /* 0x2d */ 1235 /* File: arm-vfp/OP_CMPL_FLOAT.S */ 1236 /* 1237 * Compare two floating-point values. Puts 0, 1, or -1 into the 1238 * destination register based on the results of the comparison. 1239 * 1240 * int compare(x, y) { 1241 * if (x == y) { 1242 * return 0; 1243 * } else if (x > y) { 1244 * return 1; 1245 * } else if (x < y) { 1246 * return -1; 1247 * } else { 1248 * return -1; 1249 * } 1250 * } 1251 */ 1252 /* op vAA, vBB, vCC */ 1253 FETCH(r0, 1) @ r0<- CCBB 1254 mov r9, rINST, lsr #8 @ r9<- AA 1255 and r2, r0, #255 @ r2<- BB 1256 mov r3, r0, lsr #8 @ r3<- CC 1257 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1258 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1259 flds s0, [r2] @ s0<- vBB 1260 flds s1, [r3] @ s1<- vCC 1261 fcmpes s0, s1 @ compare (vBB, vCC) 1262 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1263 mvn r0, #0 @ r0<- -1 (default) 1264 GET_INST_OPCODE(ip) @ extract opcode from rINST 1265 fmstat @ export status flags 1266 movgt r0, #1 @ (greater than) r1<- 1 1267 moveq r0, #0 @ (equal) r1<- 0 1268 b .LOP_CMPL_FLOAT_finish @ argh 1269 1270 1271 /* ------------------------------ */ 1272 .balign 64 1273 .L_OP_CMPG_FLOAT: /* 0x2e */ 1274 /* File: arm-vfp/OP_CMPG_FLOAT.S */ 1275 /* 1276 * Compare two floating-point values. Puts 0, 1, or -1 into the 1277 * destination register based on the results of the comparison. 1278 * 1279 * int compare(x, y) { 1280 * if (x == y) { 1281 * return 0; 1282 * } else if (x < y) { 1283 * return -1; 1284 * } else if (x > y) { 1285 * return 1; 1286 * } else { 1287 * return 1; 1288 * } 1289 * } 1290 */ 1291 /* op vAA, vBB, vCC */ 1292 FETCH(r0, 1) @ r0<- CCBB 1293 mov r9, rINST, lsr #8 @ r9<- AA 1294 and r2, r0, #255 @ r2<- BB 1295 mov r3, r0, lsr #8 @ r3<- CC 1296 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1297 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1298 flds s0, [r2] @ s0<- vBB 1299 flds s1, [r3] @ s1<- vCC 1300 fcmpes s0, s1 @ compare (vBB, vCC) 1301 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1302 mov r0, #1 @ r0<- 1 (default) 1303 GET_INST_OPCODE(ip) @ extract opcode from rINST 1304 fmstat @ export status flags 1305 mvnmi r0, #0 @ (less than) r1<- -1 1306 moveq r0, #0 @ (equal) r1<- 0 1307 b .LOP_CMPG_FLOAT_finish @ argh 1308 1309 1310 /* ------------------------------ */ 1311 .balign 64 1312 .L_OP_CMPL_DOUBLE: /* 0x2f */ 1313 /* File: arm-vfp/OP_CMPL_DOUBLE.S */ 1314 /* 1315 * Compare two floating-point values. Puts 0, 1, or -1 into the 1316 * destination register based on the results of the comparison. 1317 * 1318 * int compare(x, y) { 1319 * if (x == y) { 1320 * return 0; 1321 * } else if (x > y) { 1322 * return 1; 1323 * } else if (x < y) { 1324 * return -1; 1325 * } else { 1326 * return -1; 1327 * } 1328 * } 1329 */ 1330 /* op vAA, vBB, vCC */ 1331 FETCH(r0, 1) @ r0<- CCBB 1332 mov r9, rINST, lsr #8 @ r9<- AA 1333 and r2, r0, #255 @ r2<- BB 1334 mov r3, r0, lsr #8 @ r3<- CC 1335 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1336 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1337 fldd d0, [r2] @ d0<- vBB 1338 fldd d1, [r3] @ d1<- vCC 1339 fcmped d0, d1 @ compare (vBB, vCC) 1340 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1341 mvn r0, #0 @ r0<- -1 (default) 1342 GET_INST_OPCODE(ip) @ extract opcode from rINST 1343 fmstat @ export status flags 1344 movgt r0, #1 @ (greater than) r1<- 1 1345 moveq r0, #0 @ (equal) r1<- 0 1346 b .LOP_CMPL_DOUBLE_finish @ argh 1347 1348 1349 /* ------------------------------ */ 1350 .balign 64 1351 .L_OP_CMPG_DOUBLE: /* 0x30 */ 1352 /* File: arm-vfp/OP_CMPG_DOUBLE.S */ 1353 /* 1354 * Compare two floating-point values. Puts 0, 1, or -1 into the 1355 * destination register based on the results of the comparison. 1356 * 1357 * int compare(x, y) { 1358 * if (x == y) { 1359 * return 0; 1360 * } else if (x < y) { 1361 * return -1; 1362 * } else if (x > y) { 1363 * return 1; 1364 * } else { 1365 * return 1; 1366 * } 1367 * } 1368 */ 1369 /* op vAA, vBB, vCC */ 1370 FETCH(r0, 1) @ r0<- CCBB 1371 mov r9, rINST, lsr #8 @ r9<- AA 1372 and r2, r0, #255 @ r2<- BB 1373 mov r3, r0, lsr #8 @ r3<- CC 1374 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1375 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1376 fldd d0, [r2] @ d0<- vBB 1377 fldd d1, [r3] @ d1<- vCC 1378 fcmped d0, d1 @ compare (vBB, vCC) 1379 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1380 mov r0, #1 @ r0<- 1 (default) 1381 GET_INST_OPCODE(ip) @ extract opcode from rINST 1382 fmstat @ export status flags 1383 mvnmi r0, #0 @ (less than) r1<- -1 1384 moveq r0, #0 @ (equal) r1<- 0 1385 b .LOP_CMPG_DOUBLE_finish @ argh 1386 1387 1388 /* ------------------------------ */ 1389 .balign 64 1390 .L_OP_CMP_LONG: /* 0x31 */ 1391 /* File: armv5te/OP_CMP_LONG.S */ 1392 /* 1393 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 1394 * register based on the results of the comparison. 1395 * 1396 * We load the full values with LDM, but in practice many values could 1397 * be resolved by only looking at the high word. This could be made 1398 * faster or slower by splitting the LDM into a pair of LDRs. 1399 * 1400 * If we just wanted to set condition flags, we could do this: 1401 * subs ip, r0, r2 1402 * sbcs ip, r1, r3 1403 * subeqs ip, r0, r2 1404 * Leaving { <0, 0, >0 } in ip. However, we have to set it to a specific 1405 * integer value, which we can do with 2 conditional mov/mvn instructions 1406 * (set 1, set -1; if they're equal we already have 0 in ip), giving 1407 * us a constant 5-cycle path plus a branch at the end to the 1408 * instruction epilogue code. The multi-compare approach below needs 1409 * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch 1410 * in the worst case (the 64-bit values are equal). 1411 */ 1412 /* cmp-long vAA, vBB, vCC */ 1413 FETCH(r0, 1) @ r0<- CCBB 1414 mov r9, rINST, lsr #8 @ r9<- AA 1415 and r2, r0, #255 @ r2<- BB 1416 mov r3, r0, lsr #8 @ r3<- CC 1417 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 1418 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 1419 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 1420 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 1421 cmp r1, r3 @ compare (vBB+1, vCC+1) 1422 blt .LOP_CMP_LONG_less @ signed compare on high part 1423 bgt .LOP_CMP_LONG_greater 1424 subs r1, r0, r2 @ r1<- r0 - r2 1425 bhi .LOP_CMP_LONG_greater @ unsigned compare on low part 1426 bne .LOP_CMP_LONG_less 1427 b .LOP_CMP_LONG_finish @ equal; r1 already holds 0 1428 1429 /* ------------------------------ */ 1430 .balign 64 1431 .L_OP_IF_EQ: /* 0x32 */ 1432 /* File: armv6t2/OP_IF_EQ.S */ 1433 /* File: armv6t2/bincmp.S */ 1434 /* 1435 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1436 * fragment that specifies the *reverse* comparison to perform, e.g. 1437 * for "if-le" you would use "gt". 1438 * 1439 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1440 */ 1441 /* if-cmp vA, vB, +CCCC */ 1442 mov r1, rINST, lsr #12 @ r1<- B 1443 ubfx r0, rINST, #8, #4 @ r0<- A 1444 GET_VREG(r3, r1) @ r3<- vB 1445 GET_VREG(r2, r0) @ r2<- vA 1446 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1447 cmp r2, r3 @ compare (vA, vB) 1448 movne r1, #2 @ r1<- BYTE branch dist for not-taken 1449 adds r2, r1, r1 @ convert to bytes, check sign 1450 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1451 #if defined(WITH_JIT) 1452 ldr r0, [rSELF, #offThread_pJitProfTable] 1453 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1454 cmp r0, #0 1455 bne common_updateProfile 1456 #else 1457 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1458 #endif 1459 GET_INST_OPCODE(ip) @ extract opcode from rINST 1460 GOTO_OPCODE(ip) @ jump to next instruction 1461 1462 1463 /* ------------------------------ */ 1464 .balign 64 1465 .L_OP_IF_NE: /* 0x33 */ 1466 /* File: armv6t2/OP_IF_NE.S */ 1467 /* File: armv6t2/bincmp.S */ 1468 /* 1469 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1470 * fragment that specifies the *reverse* comparison to perform, e.g. 1471 * for "if-le" you would use "gt". 1472 * 1473 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1474 */ 1475 /* if-cmp vA, vB, +CCCC */ 1476 mov r1, rINST, lsr #12 @ r1<- B 1477 ubfx r0, rINST, #8, #4 @ r0<- A 1478 GET_VREG(r3, r1) @ r3<- vB 1479 GET_VREG(r2, r0) @ r2<- vA 1480 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1481 cmp r2, r3 @ compare (vA, vB) 1482 moveq r1, #2 @ r1<- BYTE branch dist for not-taken 1483 adds r2, r1, r1 @ convert to bytes, check sign 1484 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1485 #if defined(WITH_JIT) 1486 ldr r0, [rSELF, #offThread_pJitProfTable] 1487 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1488 cmp r0, #0 1489 bne common_updateProfile 1490 #else 1491 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1492 #endif 1493 GET_INST_OPCODE(ip) @ extract opcode from rINST 1494 GOTO_OPCODE(ip) @ jump to next instruction 1495 1496 1497 /* ------------------------------ */ 1498 .balign 64 1499 .L_OP_IF_LT: /* 0x34 */ 1500 /* File: armv6t2/OP_IF_LT.S */ 1501 /* File: armv6t2/bincmp.S */ 1502 /* 1503 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1504 * fragment that specifies the *reverse* comparison to perform, e.g. 1505 * for "if-le" you would use "gt". 1506 * 1507 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1508 */ 1509 /* if-cmp vA, vB, +CCCC */ 1510 mov r1, rINST, lsr #12 @ r1<- B 1511 ubfx r0, rINST, #8, #4 @ r0<- A 1512 GET_VREG(r3, r1) @ r3<- vB 1513 GET_VREG(r2, r0) @ r2<- vA 1514 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1515 cmp r2, r3 @ compare (vA, vB) 1516 movge r1, #2 @ r1<- BYTE branch dist for not-taken 1517 adds r2, r1, r1 @ convert to bytes, check sign 1518 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1519 #if defined(WITH_JIT) 1520 ldr r0, [rSELF, #offThread_pJitProfTable] 1521 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1522 cmp r0, #0 1523 bne common_updateProfile 1524 #else 1525 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1526 #endif 1527 GET_INST_OPCODE(ip) @ extract opcode from rINST 1528 GOTO_OPCODE(ip) @ jump to next instruction 1529 1530 1531 /* ------------------------------ */ 1532 .balign 64 1533 .L_OP_IF_GE: /* 0x35 */ 1534 /* File: armv6t2/OP_IF_GE.S */ 1535 /* File: armv6t2/bincmp.S */ 1536 /* 1537 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1538 * fragment that specifies the *reverse* comparison to perform, e.g. 1539 * for "if-le" you would use "gt". 1540 * 1541 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1542 */ 1543 /* if-cmp vA, vB, +CCCC */ 1544 mov r1, rINST, lsr #12 @ r1<- B 1545 ubfx r0, rINST, #8, #4 @ r0<- A 1546 GET_VREG(r3, r1) @ r3<- vB 1547 GET_VREG(r2, r0) @ r2<- vA 1548 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1549 cmp r2, r3 @ compare (vA, vB) 1550 movlt r1, #2 @ r1<- BYTE branch dist for not-taken 1551 adds r2, r1, r1 @ convert to bytes, check sign 1552 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1553 #if defined(WITH_JIT) 1554 ldr r0, [rSELF, #offThread_pJitProfTable] 1555 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1556 cmp r0, #0 1557 bne common_updateProfile 1558 #else 1559 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1560 #endif 1561 GET_INST_OPCODE(ip) @ extract opcode from rINST 1562 GOTO_OPCODE(ip) @ jump to next instruction 1563 1564 1565 /* ------------------------------ */ 1566 .balign 64 1567 .L_OP_IF_GT: /* 0x36 */ 1568 /* File: armv6t2/OP_IF_GT.S */ 1569 /* File: armv6t2/bincmp.S */ 1570 /* 1571 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1572 * fragment that specifies the *reverse* comparison to perform, e.g. 1573 * for "if-le" you would use "gt". 1574 * 1575 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1576 */ 1577 /* if-cmp vA, vB, +CCCC */ 1578 mov r1, rINST, lsr #12 @ r1<- B 1579 ubfx r0, rINST, #8, #4 @ r0<- A 1580 GET_VREG(r3, r1) @ r3<- vB 1581 GET_VREG(r2, r0) @ r2<- vA 1582 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1583 cmp r2, r3 @ compare (vA, vB) 1584 movle r1, #2 @ r1<- BYTE branch dist for not-taken 1585 adds r2, r1, r1 @ convert to bytes, check sign 1586 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1587 #if defined(WITH_JIT) 1588 ldr r0, [rSELF, #offThread_pJitProfTable] 1589 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1590 cmp r0, #0 1591 bne common_updateProfile 1592 #else 1593 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1594 #endif 1595 GET_INST_OPCODE(ip) @ extract opcode from rINST 1596 GOTO_OPCODE(ip) @ jump to next instruction 1597 1598 1599 /* ------------------------------ */ 1600 .balign 64 1601 .L_OP_IF_LE: /* 0x37 */ 1602 /* File: armv6t2/OP_IF_LE.S */ 1603 /* File: armv6t2/bincmp.S */ 1604 /* 1605 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1606 * fragment that specifies the *reverse* comparison to perform, e.g. 1607 * for "if-le" you would use "gt". 1608 * 1609 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1610 */ 1611 /* if-cmp vA, vB, +CCCC */ 1612 mov r1, rINST, lsr #12 @ r1<- B 1613 ubfx r0, rINST, #8, #4 @ r0<- A 1614 GET_VREG(r3, r1) @ r3<- vB 1615 GET_VREG(r2, r0) @ r2<- vA 1616 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1617 cmp r2, r3 @ compare (vA, vB) 1618 movgt r1, #2 @ r1<- BYTE branch dist for not-taken 1619 adds r2, r1, r1 @ convert to bytes, check sign 1620 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1621 #if defined(WITH_JIT) 1622 ldr r0, [rSELF, #offThread_pJitProfTable] 1623 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1624 cmp r0, #0 1625 bne common_updateProfile 1626 #else 1627 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1628 #endif 1629 GET_INST_OPCODE(ip) @ extract opcode from rINST 1630 GOTO_OPCODE(ip) @ jump to next instruction 1631 1632 1633 /* ------------------------------ */ 1634 .balign 64 1635 .L_OP_IF_EQZ: /* 0x38 */ 1636 /* File: armv5te/OP_IF_EQZ.S */ 1637 /* File: armv5te/zcmp.S */ 1638 /* 1639 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1640 * fragment that specifies the *reverse* comparison to perform, e.g. 1641 * for "if-le" you would use "gt". 1642 * 1643 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1644 */ 1645 /* if-cmp vAA, +BBBB */ 1646 mov r0, rINST, lsr #8 @ r0<- AA 1647 GET_VREG(r2, r0) @ r2<- vAA 1648 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1649 cmp r2, #0 @ compare (vA, 0) 1650 movne r1, #2 @ r1<- inst branch dist for not-taken 1651 adds r1, r1, r1 @ convert to bytes & set flags 1652 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1653 #if defined(WITH_JIT) 1654 ldr r0, [rSELF, #offThread_pJitProfTable] 1655 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1656 cmp r0,#0 1657 bne common_updateProfile @ test for JIT off at target 1658 #else 1659 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1660 #endif 1661 GET_INST_OPCODE(ip) @ extract opcode from rINST 1662 GOTO_OPCODE(ip) @ jump to next instruction 1663 1664 1665 /* ------------------------------ */ 1666 .balign 64 1667 .L_OP_IF_NEZ: /* 0x39 */ 1668 /* File: armv5te/OP_IF_NEZ.S */ 1669 /* File: armv5te/zcmp.S */ 1670 /* 1671 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1672 * fragment that specifies the *reverse* comparison to perform, e.g. 1673 * for "if-le" you would use "gt". 1674 * 1675 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1676 */ 1677 /* if-cmp vAA, +BBBB */ 1678 mov r0, rINST, lsr #8 @ r0<- AA 1679 GET_VREG(r2, r0) @ r2<- vAA 1680 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1681 cmp r2, #0 @ compare (vA, 0) 1682 moveq r1, #2 @ r1<- inst branch dist for not-taken 1683 adds r1, r1, r1 @ convert to bytes & set flags 1684 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1685 #if defined(WITH_JIT) 1686 ldr r0, [rSELF, #offThread_pJitProfTable] 1687 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1688 cmp r0,#0 1689 bne common_updateProfile @ test for JIT off at target 1690 #else 1691 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1692 #endif 1693 GET_INST_OPCODE(ip) @ extract opcode from rINST 1694 GOTO_OPCODE(ip) @ jump to next instruction 1695 1696 1697 /* ------------------------------ */ 1698 .balign 64 1699 .L_OP_IF_LTZ: /* 0x3a */ 1700 /* File: armv5te/OP_IF_LTZ.S */ 1701 /* File: armv5te/zcmp.S */ 1702 /* 1703 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1704 * fragment that specifies the *reverse* comparison to perform, e.g. 1705 * for "if-le" you would use "gt". 1706 * 1707 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1708 */ 1709 /* if-cmp vAA, +BBBB */ 1710 mov r0, rINST, lsr #8 @ r0<- AA 1711 GET_VREG(r2, r0) @ r2<- vAA 1712 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1713 cmp r2, #0 @ compare (vA, 0) 1714 movge r1, #2 @ r1<- inst branch dist for not-taken 1715 adds r1, r1, r1 @ convert to bytes & set flags 1716 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1717 #if defined(WITH_JIT) 1718 ldr r0, [rSELF, #offThread_pJitProfTable] 1719 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1720 cmp r0,#0 1721 bne common_updateProfile @ test for JIT off at target 1722 #else 1723 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1724 #endif 1725 GET_INST_OPCODE(ip) @ extract opcode from rINST 1726 GOTO_OPCODE(ip) @ jump to next instruction 1727 1728 1729 /* ------------------------------ */ 1730 .balign 64 1731 .L_OP_IF_GEZ: /* 0x3b */ 1732 /* File: armv5te/OP_IF_GEZ.S */ 1733 /* File: armv5te/zcmp.S */ 1734 /* 1735 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1736 * fragment that specifies the *reverse* comparison to perform, e.g. 1737 * for "if-le" you would use "gt". 1738 * 1739 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1740 */ 1741 /* if-cmp vAA, +BBBB */ 1742 mov r0, rINST, lsr #8 @ r0<- AA 1743 GET_VREG(r2, r0) @ r2<- vAA 1744 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1745 cmp r2, #0 @ compare (vA, 0) 1746 movlt r1, #2 @ r1<- inst branch dist for not-taken 1747 adds r1, r1, r1 @ convert to bytes & set flags 1748 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1749 #if defined(WITH_JIT) 1750 ldr r0, [rSELF, #offThread_pJitProfTable] 1751 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1752 cmp r0,#0 1753 bne common_updateProfile @ test for JIT off at target 1754 #else 1755 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1756 #endif 1757 GET_INST_OPCODE(ip) @ extract opcode from rINST 1758 GOTO_OPCODE(ip) @ jump to next instruction 1759 1760 1761 /* ------------------------------ */ 1762 .balign 64 1763 .L_OP_IF_GTZ: /* 0x3c */ 1764 /* File: armv5te/OP_IF_GTZ.S */ 1765 /* File: armv5te/zcmp.S */ 1766 /* 1767 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1768 * fragment that specifies the *reverse* comparison to perform, e.g. 1769 * for "if-le" you would use "gt". 1770 * 1771 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1772 */ 1773 /* if-cmp vAA, +BBBB */ 1774 mov r0, rINST, lsr #8 @ r0<- AA 1775 GET_VREG(r2, r0) @ r2<- vAA 1776 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1777 cmp r2, #0 @ compare (vA, 0) 1778 movle r1, #2 @ r1<- inst branch dist for not-taken 1779 adds r1, r1, r1 @ convert to bytes & set flags 1780 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1781 #if defined(WITH_JIT) 1782 ldr r0, [rSELF, #offThread_pJitProfTable] 1783 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1784 cmp r0,#0 1785 bne common_updateProfile @ test for JIT off at target 1786 #else 1787 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1788 #endif 1789 GET_INST_OPCODE(ip) @ extract opcode from rINST 1790 GOTO_OPCODE(ip) @ jump to next instruction 1791 1792 1793 /* ------------------------------ */ 1794 .balign 64 1795 .L_OP_IF_LEZ: /* 0x3d */ 1796 /* File: armv5te/OP_IF_LEZ.S */ 1797 /* File: armv5te/zcmp.S */ 1798 /* 1799 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1800 * fragment that specifies the *reverse* comparison to perform, e.g. 1801 * for "if-le" you would use "gt". 1802 * 1803 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1804 */ 1805 /* if-cmp vAA, +BBBB */ 1806 mov r0, rINST, lsr #8 @ r0<- AA 1807 GET_VREG(r2, r0) @ r2<- vAA 1808 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1809 cmp r2, #0 @ compare (vA, 0) 1810 movgt r1, #2 @ r1<- inst branch dist for not-taken 1811 adds r1, r1, r1 @ convert to bytes & set flags 1812 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1813 #if defined(WITH_JIT) 1814 ldr r0, [rSELF, #offThread_pJitProfTable] 1815 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1816 cmp r0,#0 1817 bne common_updateProfile @ test for JIT off at target 1818 #else 1819 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1820 #endif 1821 GET_INST_OPCODE(ip) @ extract opcode from rINST 1822 GOTO_OPCODE(ip) @ jump to next instruction 1823 1824 1825 /* ------------------------------ */ 1826 .balign 64 1827 .L_OP_UNUSED_3E: /* 0x3e */ 1828 /* File: armv5te/OP_UNUSED_3E.S */ 1829 /* File: armv5te/unused.S */ 1830 bl common_abort 1831 1832 1833 /* ------------------------------ */ 1834 .balign 64 1835 .L_OP_UNUSED_3F: /* 0x3f */ 1836 /* File: armv5te/OP_UNUSED_3F.S */ 1837 /* File: armv5te/unused.S */ 1838 bl common_abort 1839 1840 1841 /* ------------------------------ */ 1842 .balign 64 1843 .L_OP_UNUSED_40: /* 0x40 */ 1844 /* File: armv5te/OP_UNUSED_40.S */ 1845 /* File: armv5te/unused.S */ 1846 bl common_abort 1847 1848 1849 /* ------------------------------ */ 1850 .balign 64 1851 .L_OP_UNUSED_41: /* 0x41 */ 1852 /* File: armv5te/OP_UNUSED_41.S */ 1853 /* File: armv5te/unused.S */ 1854 bl common_abort 1855 1856 1857 /* ------------------------------ */ 1858 .balign 64 1859 .L_OP_UNUSED_42: /* 0x42 */ 1860 /* File: armv5te/OP_UNUSED_42.S */ 1861 /* File: armv5te/unused.S */ 1862 bl common_abort 1863 1864 1865 /* ------------------------------ */ 1866 .balign 64 1867 .L_OP_UNUSED_43: /* 0x43 */ 1868 /* File: armv5te/OP_UNUSED_43.S */ 1869 /* File: armv5te/unused.S */ 1870 bl common_abort 1871 1872 1873 /* ------------------------------ */ 1874 .balign 64 1875 .L_OP_AGET: /* 0x44 */ 1876 /* File: armv5te/OP_AGET.S */ 1877 /* 1878 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1879 * 1880 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1881 * instructions. We use a pair of FETCH_Bs instead. 1882 * 1883 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1884 */ 1885 /* op vAA, vBB, vCC */ 1886 FETCH_B(r2, 1, 0) @ r2<- BB 1887 mov r9, rINST, lsr #8 @ r9<- AA 1888 FETCH_B(r3, 1, 1) @ r3<- CC 1889 GET_VREG(r0, r2) @ r0<- vBB (array object) 1890 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1891 cmp r0, #0 @ null array object? 1892 beq common_errNullObject @ yes, bail 1893 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1894 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1895 cmp r1, r3 @ compare unsigned index, length 1896 bcs common_errArrayIndex @ index >= length, bail 1897 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1898 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1899 GET_INST_OPCODE(ip) @ extract opcode from rINST 1900 SET_VREG(r2, r9) @ vAA<- r2 1901 GOTO_OPCODE(ip) @ jump to next instruction 1902 1903 /* ------------------------------ */ 1904 .balign 64 1905 .L_OP_AGET_WIDE: /* 0x45 */ 1906 /* File: armv5te/OP_AGET_WIDE.S */ 1907 /* 1908 * Array get, 64 bits. vAA <- vBB[vCC]. 1909 * 1910 * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD. 1911 */ 1912 /* aget-wide vAA, vBB, vCC */ 1913 FETCH(r0, 1) @ r0<- CCBB 1914 mov r9, rINST, lsr #8 @ r9<- AA 1915 and r2, r0, #255 @ r2<- BB 1916 mov r3, r0, lsr #8 @ r3<- CC 1917 GET_VREG(r0, r2) @ r0<- vBB (array object) 1918 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1919 cmp r0, #0 @ null array object? 1920 beq common_errNullObject @ yes, bail 1921 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1922 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 1923 cmp r1, r3 @ compare unsigned index, length 1924 bcc .LOP_AGET_WIDE_finish @ okay, continue below 1925 b common_errArrayIndex @ index >= length, bail 1926 @ May want to swap the order of these two branches depending on how the 1927 @ branch prediction (if any) handles conditional forward branches vs. 1928 @ unconditional forward branches. 1929 1930 /* ------------------------------ */ 1931 .balign 64 1932 .L_OP_AGET_OBJECT: /* 0x46 */ 1933 /* File: armv5te/OP_AGET_OBJECT.S */ 1934 /* File: armv5te/OP_AGET.S */ 1935 /* 1936 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1937 * 1938 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1939 * instructions. We use a pair of FETCH_Bs instead. 1940 * 1941 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1942 */ 1943 /* op vAA, vBB, vCC */ 1944 FETCH_B(r2, 1, 0) @ r2<- BB 1945 mov r9, rINST, lsr #8 @ r9<- AA 1946 FETCH_B(r3, 1, 1) @ r3<- CC 1947 GET_VREG(r0, r2) @ r0<- vBB (array object) 1948 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1949 cmp r0, #0 @ null array object? 1950 beq common_errNullObject @ yes, bail 1951 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1952 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1953 cmp r1, r3 @ compare unsigned index, length 1954 bcs common_errArrayIndex @ index >= length, bail 1955 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1956 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1957 GET_INST_OPCODE(ip) @ extract opcode from rINST 1958 SET_VREG(r2, r9) @ vAA<- r2 1959 GOTO_OPCODE(ip) @ jump to next instruction 1960 1961 1962 /* ------------------------------ */ 1963 .balign 64 1964 .L_OP_AGET_BOOLEAN: /* 0x47 */ 1965 /* File: armv5te/OP_AGET_BOOLEAN.S */ 1966 /* File: armv5te/OP_AGET.S */ 1967 /* 1968 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1969 * 1970 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1971 * instructions. We use a pair of FETCH_Bs instead. 1972 * 1973 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1974 */ 1975 /* op vAA, vBB, vCC */ 1976 FETCH_B(r2, 1, 0) @ r2<- BB 1977 mov r9, rINST, lsr #8 @ r9<- AA 1978 FETCH_B(r3, 1, 1) @ r3<- CC 1979 GET_VREG(r0, r2) @ r0<- vBB (array object) 1980 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1981 cmp r0, #0 @ null array object? 1982 beq common_errNullObject @ yes, bail 1983 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1984 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 1985 cmp r1, r3 @ compare unsigned index, length 1986 bcs common_errArrayIndex @ index >= length, bail 1987 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1988 ldrb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1989 GET_INST_OPCODE(ip) @ extract opcode from rINST 1990 SET_VREG(r2, r9) @ vAA<- r2 1991 GOTO_OPCODE(ip) @ jump to next instruction 1992 1993 1994 /* ------------------------------ */ 1995 .balign 64 1996 .L_OP_AGET_BYTE: /* 0x48 */ 1997 /* File: armv5te/OP_AGET_BYTE.S */ 1998 /* File: armv5te/OP_AGET.S */ 1999 /* 2000 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2001 * 2002 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2003 * instructions. We use a pair of FETCH_Bs instead. 2004 * 2005 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2006 */ 2007 /* op vAA, vBB, vCC */ 2008 FETCH_B(r2, 1, 0) @ r2<- BB 2009 mov r9, rINST, lsr #8 @ r9<- AA 2010 FETCH_B(r3, 1, 1) @ r3<- CC 2011 GET_VREG(r0, r2) @ r0<- vBB (array object) 2012 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2013 cmp r0, #0 @ null array object? 2014 beq common_errNullObject @ yes, bail 2015 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2016 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2017 cmp r1, r3 @ compare unsigned index, length 2018 bcs common_errArrayIndex @ index >= length, bail 2019 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2020 ldrsb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2021 GET_INST_OPCODE(ip) @ extract opcode from rINST 2022 SET_VREG(r2, r9) @ vAA<- r2 2023 GOTO_OPCODE(ip) @ jump to next instruction 2024 2025 2026 /* ------------------------------ */ 2027 .balign 64 2028 .L_OP_AGET_CHAR: /* 0x49 */ 2029 /* File: armv5te/OP_AGET_CHAR.S */ 2030 /* File: armv5te/OP_AGET.S */ 2031 /* 2032 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2033 * 2034 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2035 * instructions. We use a pair of FETCH_Bs instead. 2036 * 2037 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2038 */ 2039 /* op vAA, vBB, vCC */ 2040 FETCH_B(r2, 1, 0) @ r2<- BB 2041 mov r9, rINST, lsr #8 @ r9<- AA 2042 FETCH_B(r3, 1, 1) @ r3<- CC 2043 GET_VREG(r0, r2) @ r0<- vBB (array object) 2044 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2045 cmp r0, #0 @ null array object? 2046 beq common_errNullObject @ yes, bail 2047 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2048 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2049 cmp r1, r3 @ compare unsigned index, length 2050 bcs common_errArrayIndex @ index >= length, bail 2051 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2052 ldrh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2053 GET_INST_OPCODE(ip) @ extract opcode from rINST 2054 SET_VREG(r2, r9) @ vAA<- r2 2055 GOTO_OPCODE(ip) @ jump to next instruction 2056 2057 2058 /* ------------------------------ */ 2059 .balign 64 2060 .L_OP_AGET_SHORT: /* 0x4a */ 2061 /* File: armv5te/OP_AGET_SHORT.S */ 2062 /* File: armv5te/OP_AGET.S */ 2063 /* 2064 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2065 * 2066 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2067 * instructions. We use a pair of FETCH_Bs instead. 2068 * 2069 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2070 */ 2071 /* op vAA, vBB, vCC */ 2072 FETCH_B(r2, 1, 0) @ r2<- BB 2073 mov r9, rINST, lsr #8 @ r9<- AA 2074 FETCH_B(r3, 1, 1) @ r3<- CC 2075 GET_VREG(r0, r2) @ r0<- vBB (array object) 2076 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2077 cmp r0, #0 @ null array object? 2078 beq common_errNullObject @ yes, bail 2079 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2080 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2081 cmp r1, r3 @ compare unsigned index, length 2082 bcs common_errArrayIndex @ index >= length, bail 2083 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2084 ldrsh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2085 GET_INST_OPCODE(ip) @ extract opcode from rINST 2086 SET_VREG(r2, r9) @ vAA<- r2 2087 GOTO_OPCODE(ip) @ jump to next instruction 2088 2089 2090 /* ------------------------------ */ 2091 .balign 64 2092 .L_OP_APUT: /* 0x4b */ 2093 /* File: armv5te/OP_APUT.S */ 2094 /* 2095 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2096 * 2097 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2098 * instructions. We use a pair of FETCH_Bs instead. 2099 * 2100 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2101 */ 2102 /* op vAA, vBB, vCC */ 2103 FETCH_B(r2, 1, 0) @ r2<- BB 2104 mov r9, rINST, lsr #8 @ r9<- AA 2105 FETCH_B(r3, 1, 1) @ r3<- CC 2106 GET_VREG(r0, r2) @ r0<- vBB (array object) 2107 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2108 cmp r0, #0 @ null array object? 2109 beq common_errNullObject @ yes, bail 2110 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2111 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2112 cmp r1, r3 @ compare unsigned index, length 2113 bcs common_errArrayIndex @ index >= length, bail 2114 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2115 GET_VREG(r2, r9) @ r2<- vAA 2116 GET_INST_OPCODE(ip) @ extract opcode from rINST 2117 str r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2118 GOTO_OPCODE(ip) @ jump to next instruction 2119 2120 /* ------------------------------ */ 2121 .balign 64 2122 .L_OP_APUT_WIDE: /* 0x4c */ 2123 /* File: armv5te/OP_APUT_WIDE.S */ 2124 /* 2125 * Array put, 64 bits. vBB[vCC] <- vAA. 2126 * 2127 * Arrays of long/double are 64-bit aligned, so it's okay to use STRD. 2128 */ 2129 /* aput-wide vAA, vBB, vCC */ 2130 FETCH(r0, 1) @ r0<- CCBB 2131 mov r9, rINST, lsr #8 @ r9<- AA 2132 and r2, r0, #255 @ r2<- BB 2133 mov r3, r0, lsr #8 @ r3<- CC 2134 GET_VREG(r0, r2) @ r0<- vBB (array object) 2135 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2136 cmp r0, #0 @ null array object? 2137 beq common_errNullObject @ yes, bail 2138 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2139 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2140 cmp r1, r3 @ compare unsigned index, length 2141 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2142 bcc .LOP_APUT_WIDE_finish @ okay, continue below 2143 b common_errArrayIndex @ index >= length, bail 2144 @ May want to swap the order of these two branches depending on how the 2145 @ branch prediction (if any) handles conditional forward branches vs. 2146 @ unconditional forward branches. 2147 2148 /* ------------------------------ */ 2149 .balign 64 2150 .L_OP_APUT_OBJECT: /* 0x4d */ 2151 /* File: armv5te/OP_APUT_OBJECT.S */ 2152 /* 2153 * Store an object into an array. vBB[vCC] <- vAA. 2154 */ 2155 /* op vAA, vBB, vCC */ 2156 FETCH(r0, 1) @ r0<- CCBB 2157 mov r9, rINST, lsr #8 @ r9<- AA 2158 and r2, r0, #255 @ r2<- BB 2159 mov r3, r0, lsr #8 @ r3<- CC 2160 GET_VREG(rINST, r2) @ rINST<- vBB (array object) 2161 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2162 cmp rINST, #0 @ null array object? 2163 GET_VREG(r9, r9) @ r9<- vAA 2164 beq common_errNullObject @ yes, bail 2165 ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length 2166 add r10, rINST, r1, lsl #2 @ r10<- arrayObj + index*width 2167 cmp r1, r3 @ compare unsigned index, length 2168 bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on 2169 b common_errArrayIndex @ index >= length, bail 2170 2171 2172 /* ------------------------------ */ 2173 .balign 64 2174 .L_OP_APUT_BOOLEAN: /* 0x4e */ 2175 /* File: armv5te/OP_APUT_BOOLEAN.S */ 2176 /* File: armv5te/OP_APUT.S */ 2177 /* 2178 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2179 * 2180 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2181 * instructions. We use a pair of FETCH_Bs instead. 2182 * 2183 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2184 */ 2185 /* op vAA, vBB, vCC */ 2186 FETCH_B(r2, 1, 0) @ r2<- BB 2187 mov r9, rINST, lsr #8 @ r9<- AA 2188 FETCH_B(r3, 1, 1) @ r3<- CC 2189 GET_VREG(r0, r2) @ r0<- vBB (array object) 2190 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2191 cmp r0, #0 @ null array object? 2192 beq common_errNullObject @ yes, bail 2193 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2194 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2195 cmp r1, r3 @ compare unsigned index, length 2196 bcs common_errArrayIndex @ index >= length, bail 2197 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2198 GET_VREG(r2, r9) @ r2<- vAA 2199 GET_INST_OPCODE(ip) @ extract opcode from rINST 2200 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2201 GOTO_OPCODE(ip) @ jump to next instruction 2202 2203 2204 /* ------------------------------ */ 2205 .balign 64 2206 .L_OP_APUT_BYTE: /* 0x4f */ 2207 /* File: armv5te/OP_APUT_BYTE.S */ 2208 /* File: armv5te/OP_APUT.S */ 2209 /* 2210 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2211 * 2212 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2213 * instructions. We use a pair of FETCH_Bs instead. 2214 * 2215 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2216 */ 2217 /* op vAA, vBB, vCC */ 2218 FETCH_B(r2, 1, 0) @ r2<- BB 2219 mov r9, rINST, lsr #8 @ r9<- AA 2220 FETCH_B(r3, 1, 1) @ r3<- CC 2221 GET_VREG(r0, r2) @ r0<- vBB (array object) 2222 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2223 cmp r0, #0 @ null array object? 2224 beq common_errNullObject @ yes, bail 2225 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2226 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2227 cmp r1, r3 @ compare unsigned index, length 2228 bcs common_errArrayIndex @ index >= length, bail 2229 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2230 GET_VREG(r2, r9) @ r2<- vAA 2231 GET_INST_OPCODE(ip) @ extract opcode from rINST 2232 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2233 GOTO_OPCODE(ip) @ jump to next instruction 2234 2235 2236 /* ------------------------------ */ 2237 .balign 64 2238 .L_OP_APUT_CHAR: /* 0x50 */ 2239 /* File: armv5te/OP_APUT_CHAR.S */ 2240 /* File: armv5te/OP_APUT.S */ 2241 /* 2242 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2243 * 2244 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2245 * instructions. We use a pair of FETCH_Bs instead. 2246 * 2247 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2248 */ 2249 /* op vAA, vBB, vCC */ 2250 FETCH_B(r2, 1, 0) @ r2<- BB 2251 mov r9, rINST, lsr #8 @ r9<- AA 2252 FETCH_B(r3, 1, 1) @ r3<- CC 2253 GET_VREG(r0, r2) @ r0<- vBB (array object) 2254 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2255 cmp r0, #0 @ null array object? 2256 beq common_errNullObject @ yes, bail 2257 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2258 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2259 cmp r1, r3 @ compare unsigned index, length 2260 bcs common_errArrayIndex @ index >= length, bail 2261 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2262 GET_VREG(r2, r9) @ r2<- vAA 2263 GET_INST_OPCODE(ip) @ extract opcode from rINST 2264 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2265 GOTO_OPCODE(ip) @ jump to next instruction 2266 2267 2268 /* ------------------------------ */ 2269 .balign 64 2270 .L_OP_APUT_SHORT: /* 0x51 */ 2271 /* File: armv5te/OP_APUT_SHORT.S */ 2272 /* File: armv5te/OP_APUT.S */ 2273 /* 2274 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2275 * 2276 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2277 * instructions. We use a pair of FETCH_Bs instead. 2278 * 2279 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2280 */ 2281 /* op vAA, vBB, vCC */ 2282 FETCH_B(r2, 1, 0) @ r2<- BB 2283 mov r9, rINST, lsr #8 @ r9<- AA 2284 FETCH_B(r3, 1, 1) @ r3<- CC 2285 GET_VREG(r0, r2) @ r0<- vBB (array object) 2286 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2287 cmp r0, #0 @ null array object? 2288 beq common_errNullObject @ yes, bail 2289 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2290 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2291 cmp r1, r3 @ compare unsigned index, length 2292 bcs common_errArrayIndex @ index >= length, bail 2293 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2294 GET_VREG(r2, r9) @ r2<- vAA 2295 GET_INST_OPCODE(ip) @ extract opcode from rINST 2296 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2297 GOTO_OPCODE(ip) @ jump to next instruction 2298 2299 2300 /* ------------------------------ */ 2301 .balign 64 2302 .L_OP_IGET: /* 0x52 */ 2303 /* File: armv6t2/OP_IGET.S */ 2304 /* 2305 * General 32-bit instance field get. 2306 * 2307 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2308 */ 2309 /* op vA, vB, field@CCCC */ 2310 mov r0, rINST, lsr #12 @ r0<- B 2311 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2312 FETCH(r1, 1) @ r1<- field ref CCCC 2313 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2314 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2315 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2316 cmp r0, #0 @ is resolved entry null? 2317 bne .LOP_IGET_finish @ no, already resolved 2318 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2319 EXPORT_PC() @ resolve() could throw 2320 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2321 bl dvmResolveInstField @ r0<- resolved InstField ptr 2322 cmp r0, #0 2323 bne .LOP_IGET_finish 2324 b common_exceptionThrown 2325 2326 /* ------------------------------ */ 2327 .balign 64 2328 .L_OP_IGET_WIDE: /* 0x53 */ 2329 /* File: armv6t2/OP_IGET_WIDE.S */ 2330 /* 2331 * Wide 32-bit instance field get. 2332 */ 2333 /* iget-wide vA, vB, field@CCCC */ 2334 mov r0, rINST, lsr #12 @ r0<- B 2335 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2336 FETCH(r1, 1) @ r1<- field ref CCCC 2337 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2338 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2339 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2340 cmp r0, #0 @ is resolved entry null? 2341 bne .LOP_IGET_WIDE_finish @ no, already resolved 2342 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2343 EXPORT_PC() @ resolve() could throw 2344 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2345 bl dvmResolveInstField @ r0<- resolved InstField ptr 2346 cmp r0, #0 2347 bne .LOP_IGET_WIDE_finish 2348 b common_exceptionThrown 2349 2350 /* ------------------------------ */ 2351 .balign 64 2352 .L_OP_IGET_OBJECT: /* 0x54 */ 2353 /* File: armv5te/OP_IGET_OBJECT.S */ 2354 /* File: armv5te/OP_IGET.S */ 2355 /* 2356 * General 32-bit instance field get. 2357 * 2358 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2359 */ 2360 /* op vA, vB, field@CCCC */ 2361 mov r0, rINST, lsr #12 @ r0<- B 2362 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2363 FETCH(r1, 1) @ r1<- field ref CCCC 2364 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2365 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2366 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2367 cmp r0, #0 @ is resolved entry null? 2368 bne .LOP_IGET_OBJECT_finish @ no, already resolved 2369 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2370 EXPORT_PC() @ resolve() could throw 2371 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2372 bl dvmResolveInstField @ r0<- resolved InstField ptr 2373 cmp r0, #0 2374 bne .LOP_IGET_OBJECT_finish 2375 b common_exceptionThrown 2376 2377 2378 /* ------------------------------ */ 2379 .balign 64 2380 .L_OP_IGET_BOOLEAN: /* 0x55 */ 2381 /* File: armv5te/OP_IGET_BOOLEAN.S */ 2382 @include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" } 2383 /* File: armv5te/OP_IGET.S */ 2384 /* 2385 * General 32-bit instance field get. 2386 * 2387 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2388 */ 2389 /* op vA, vB, field@CCCC */ 2390 mov r0, rINST, lsr #12 @ r0<- B 2391 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2392 FETCH(r1, 1) @ r1<- field ref CCCC 2393 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2394 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2395 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2396 cmp r0, #0 @ is resolved entry null? 2397 bne .LOP_IGET_BOOLEAN_finish @ no, already resolved 2398 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2399 EXPORT_PC() @ resolve() could throw 2400 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2401 bl dvmResolveInstField @ r0<- resolved InstField ptr 2402 cmp r0, #0 2403 bne .LOP_IGET_BOOLEAN_finish 2404 b common_exceptionThrown 2405 2406 2407 /* ------------------------------ */ 2408 .balign 64 2409 .L_OP_IGET_BYTE: /* 0x56 */ 2410 /* File: armv5te/OP_IGET_BYTE.S */ 2411 @include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" } 2412 /* File: armv5te/OP_IGET.S */ 2413 /* 2414 * General 32-bit instance field get. 2415 * 2416 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2417 */ 2418 /* op vA, vB, field@CCCC */ 2419 mov r0, rINST, lsr #12 @ r0<- B 2420 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2421 FETCH(r1, 1) @ r1<- field ref CCCC 2422 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2423 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2424 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2425 cmp r0, #0 @ is resolved entry null? 2426 bne .LOP_IGET_BYTE_finish @ no, already resolved 2427 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2428 EXPORT_PC() @ resolve() could throw 2429 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2430 bl dvmResolveInstField @ r0<- resolved InstField ptr 2431 cmp r0, #0 2432 bne .LOP_IGET_BYTE_finish 2433 b common_exceptionThrown 2434 2435 2436 /* ------------------------------ */ 2437 .balign 64 2438 .L_OP_IGET_CHAR: /* 0x57 */ 2439 /* File: armv5te/OP_IGET_CHAR.S */ 2440 @include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" } 2441 /* File: armv5te/OP_IGET.S */ 2442 /* 2443 * General 32-bit instance field get. 2444 * 2445 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2446 */ 2447 /* op vA, vB, field@CCCC */ 2448 mov r0, rINST, lsr #12 @ r0<- B 2449 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2450 FETCH(r1, 1) @ r1<- field ref CCCC 2451 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2452 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2453 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2454 cmp r0, #0 @ is resolved entry null? 2455 bne .LOP_IGET_CHAR_finish @ no, already resolved 2456 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2457 EXPORT_PC() @ resolve() could throw 2458 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2459 bl dvmResolveInstField @ r0<- resolved InstField ptr 2460 cmp r0, #0 2461 bne .LOP_IGET_CHAR_finish 2462 b common_exceptionThrown 2463 2464 2465 /* ------------------------------ */ 2466 .balign 64 2467 .L_OP_IGET_SHORT: /* 0x58 */ 2468 /* File: armv5te/OP_IGET_SHORT.S */ 2469 @include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" } 2470 /* File: armv5te/OP_IGET.S */ 2471 /* 2472 * General 32-bit instance field get. 2473 * 2474 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2475 */ 2476 /* op vA, vB, field@CCCC */ 2477 mov r0, rINST, lsr #12 @ r0<- B 2478 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2479 FETCH(r1, 1) @ r1<- field ref CCCC 2480 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2481 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2482 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2483 cmp r0, #0 @ is resolved entry null? 2484 bne .LOP_IGET_SHORT_finish @ no, already resolved 2485 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2486 EXPORT_PC() @ resolve() could throw 2487 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2488 bl dvmResolveInstField @ r0<- resolved InstField ptr 2489 cmp r0, #0 2490 bne .LOP_IGET_SHORT_finish 2491 b common_exceptionThrown 2492 2493 2494 /* ------------------------------ */ 2495 .balign 64 2496 .L_OP_IPUT: /* 0x59 */ 2497 /* File: armv6t2/OP_IPUT.S */ 2498 /* 2499 * General 32-bit instance field put. 2500 * 2501 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2502 */ 2503 /* op vA, vB, field@CCCC */ 2504 mov r0, rINST, lsr #12 @ r0<- B 2505 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2506 FETCH(r1, 1) @ r1<- field ref CCCC 2507 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2508 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2509 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2510 cmp r0, #0 @ is resolved entry null? 2511 bne .LOP_IPUT_finish @ no, already resolved 2512 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2513 EXPORT_PC() @ resolve() could throw 2514 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2515 bl dvmResolveInstField @ r0<- resolved InstField ptr 2516 cmp r0, #0 @ success? 2517 bne .LOP_IPUT_finish @ yes, finish up 2518 b common_exceptionThrown 2519 2520 /* ------------------------------ */ 2521 .balign 64 2522 .L_OP_IPUT_WIDE: /* 0x5a */ 2523 /* File: armv6t2/OP_IPUT_WIDE.S */ 2524 /* iput-wide vA, vB, field@CCCC */ 2525 mov r0, rINST, lsr #12 @ r0<- B 2526 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2527 FETCH(r1, 1) @ r1<- field ref CCCC 2528 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2529 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2530 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2531 cmp r0, #0 @ is resolved entry null? 2532 bne .LOP_IPUT_WIDE_finish @ no, already resolved 2533 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2534 EXPORT_PC() @ resolve() could throw 2535 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2536 bl dvmResolveInstField @ r0<- resolved InstField ptr 2537 cmp r0, #0 @ success? 2538 bne .LOP_IPUT_WIDE_finish @ yes, finish up 2539 b common_exceptionThrown 2540 2541 /* ------------------------------ */ 2542 .balign 64 2543 .L_OP_IPUT_OBJECT: /* 0x5b */ 2544 /* File: armv5te/OP_IPUT_OBJECT.S */ 2545 /* 2546 * 32-bit instance field put. 2547 * 2548 * for: iput-object, iput-object-volatile 2549 */ 2550 /* op vA, vB, field@CCCC */ 2551 mov r0, rINST, lsr #12 @ r0<- B 2552 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2553 FETCH(r1, 1) @ r1<- field ref CCCC 2554 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2555 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2556 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2557 cmp r0, #0 @ is resolved entry null? 2558 bne .LOP_IPUT_OBJECT_finish @ no, already resolved 2559 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2560 EXPORT_PC() @ resolve() could throw 2561 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2562 bl dvmResolveInstField @ r0<- resolved InstField ptr 2563 cmp r0, #0 @ success? 2564 bne .LOP_IPUT_OBJECT_finish @ yes, finish up 2565 b common_exceptionThrown 2566 2567 /* ------------------------------ */ 2568 .balign 64 2569 .L_OP_IPUT_BOOLEAN: /* 0x5c */ 2570 /* File: armv5te/OP_IPUT_BOOLEAN.S */ 2571 @include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" } 2572 /* File: armv5te/OP_IPUT.S */ 2573 /* 2574 * General 32-bit instance field put. 2575 * 2576 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2577 */ 2578 /* op vA, vB, field@CCCC */ 2579 mov r0, rINST, lsr #12 @ r0<- B 2580 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2581 FETCH(r1, 1) @ r1<- field ref CCCC 2582 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2583 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2584 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2585 cmp r0, #0 @ is resolved entry null? 2586 bne .LOP_IPUT_BOOLEAN_finish @ no, already resolved 2587 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2588 EXPORT_PC() @ resolve() could throw 2589 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2590 bl dvmResolveInstField @ r0<- resolved InstField ptr 2591 cmp r0, #0 @ success? 2592 bne .LOP_IPUT_BOOLEAN_finish @ yes, finish up 2593 b common_exceptionThrown 2594 2595 2596 /* ------------------------------ */ 2597 .balign 64 2598 .L_OP_IPUT_BYTE: /* 0x5d */ 2599 /* File: armv5te/OP_IPUT_BYTE.S */ 2600 @include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" } 2601 /* File: armv5te/OP_IPUT.S */ 2602 /* 2603 * General 32-bit instance field put. 2604 * 2605 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2606 */ 2607 /* op vA, vB, field@CCCC */ 2608 mov r0, rINST, lsr #12 @ r0<- B 2609 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2610 FETCH(r1, 1) @ r1<- field ref CCCC 2611 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2612 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2613 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2614 cmp r0, #0 @ is resolved entry null? 2615 bne .LOP_IPUT_BYTE_finish @ no, already resolved 2616 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2617 EXPORT_PC() @ resolve() could throw 2618 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2619 bl dvmResolveInstField @ r0<- resolved InstField ptr 2620 cmp r0, #0 @ success? 2621 bne .LOP_IPUT_BYTE_finish @ yes, finish up 2622 b common_exceptionThrown 2623 2624 2625 /* ------------------------------ */ 2626 .balign 64 2627 .L_OP_IPUT_CHAR: /* 0x5e */ 2628 /* File: armv5te/OP_IPUT_CHAR.S */ 2629 @include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" } 2630 /* File: armv5te/OP_IPUT.S */ 2631 /* 2632 * General 32-bit instance field put. 2633 * 2634 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2635 */ 2636 /* op vA, vB, field@CCCC */ 2637 mov r0, rINST, lsr #12 @ r0<- B 2638 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2639 FETCH(r1, 1) @ r1<- field ref CCCC 2640 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2641 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2642 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2643 cmp r0, #0 @ is resolved entry null? 2644 bne .LOP_IPUT_CHAR_finish @ no, already resolved 2645 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2646 EXPORT_PC() @ resolve() could throw 2647 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2648 bl dvmResolveInstField @ r0<- resolved InstField ptr 2649 cmp r0, #0 @ success? 2650 bne .LOP_IPUT_CHAR_finish @ yes, finish up 2651 b common_exceptionThrown 2652 2653 2654 /* ------------------------------ */ 2655 .balign 64 2656 .L_OP_IPUT_SHORT: /* 0x5f */ 2657 /* File: armv5te/OP_IPUT_SHORT.S */ 2658 @include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" } 2659 /* File: armv5te/OP_IPUT.S */ 2660 /* 2661 * General 32-bit instance field put. 2662 * 2663 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2664 */ 2665 /* op vA, vB, field@CCCC */ 2666 mov r0, rINST, lsr #12 @ r0<- B 2667 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2668 FETCH(r1, 1) @ r1<- field ref CCCC 2669 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2670 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2671 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2672 cmp r0, #0 @ is resolved entry null? 2673 bne .LOP_IPUT_SHORT_finish @ no, already resolved 2674 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2675 EXPORT_PC() @ resolve() could throw 2676 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2677 bl dvmResolveInstField @ r0<- resolved InstField ptr 2678 cmp r0, #0 @ success? 2679 bne .LOP_IPUT_SHORT_finish @ yes, finish up 2680 b common_exceptionThrown 2681 2682 2683 /* ------------------------------ */ 2684 .balign 64 2685 .L_OP_SGET: /* 0x60 */ 2686 /* File: armv5te/OP_SGET.S */ 2687 /* 2688 * General 32-bit SGET handler. 2689 * 2690 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2691 */ 2692 /* op vAA, field@BBBB */ 2693 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2694 FETCH(r1, 1) @ r1<- field ref BBBB 2695 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2696 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2697 cmp r0, #0 @ is resolved entry null? 2698 beq .LOP_SGET_resolve @ yes, do resolve 2699 .LOP_SGET_finish: @ field ptr in r0 2700 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2701 @ no-op @ acquiring load 2702 mov r2, rINST, lsr #8 @ r2<- AA 2703 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2704 SET_VREG(r1, r2) @ fp[AA]<- r1 2705 GET_INST_OPCODE(ip) @ extract opcode from rINST 2706 GOTO_OPCODE(ip) @ jump to next instruction 2707 2708 /* ------------------------------ */ 2709 .balign 64 2710 .L_OP_SGET_WIDE: /* 0x61 */ 2711 /* File: armv5te/OP_SGET_WIDE.S */ 2712 /* 2713 * 64-bit SGET handler. 2714 */ 2715 /* sget-wide vAA, field@BBBB */ 2716 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2717 FETCH(r1, 1) @ r1<- field ref BBBB 2718 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2719 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2720 cmp r0, #0 @ is resolved entry null? 2721 beq .LOP_SGET_WIDE_resolve @ yes, do resolve 2722 .LOP_SGET_WIDE_finish: 2723 mov r9, rINST, lsr #8 @ r9<- AA 2724 .if 0 2725 add r0, r0, #offStaticField_value @ r0<- pointer to data 2726 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 2727 .else 2728 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 2729 .endif 2730 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2731 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2732 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 2733 GET_INST_OPCODE(ip) @ extract opcode from rINST 2734 GOTO_OPCODE(ip) @ jump to next instruction 2735 2736 /* ------------------------------ */ 2737 .balign 64 2738 .L_OP_SGET_OBJECT: /* 0x62 */ 2739 /* File: armv5te/OP_SGET_OBJECT.S */ 2740 /* File: armv5te/OP_SGET.S */ 2741 /* 2742 * General 32-bit SGET handler. 2743 * 2744 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2745 */ 2746 /* op vAA, field@BBBB */ 2747 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2748 FETCH(r1, 1) @ r1<- field ref BBBB 2749 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2750 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2751 cmp r0, #0 @ is resolved entry null? 2752 beq .LOP_SGET_OBJECT_resolve @ yes, do resolve 2753 .LOP_SGET_OBJECT_finish: @ field ptr in r0 2754 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2755 @ no-op @ acquiring load 2756 mov r2, rINST, lsr #8 @ r2<- AA 2757 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2758 SET_VREG(r1, r2) @ fp[AA]<- r1 2759 GET_INST_OPCODE(ip) @ extract opcode from rINST 2760 GOTO_OPCODE(ip) @ jump to next instruction 2761 2762 2763 /* ------------------------------ */ 2764 .balign 64 2765 .L_OP_SGET_BOOLEAN: /* 0x63 */ 2766 /* File: armv5te/OP_SGET_BOOLEAN.S */ 2767 /* File: armv5te/OP_SGET.S */ 2768 /* 2769 * General 32-bit SGET handler. 2770 * 2771 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2772 */ 2773 /* op vAA, field@BBBB */ 2774 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2775 FETCH(r1, 1) @ r1<- field ref BBBB 2776 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2777 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2778 cmp r0, #0 @ is resolved entry null? 2779 beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve 2780 .LOP_SGET_BOOLEAN_finish: @ field ptr in r0 2781 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2782 @ no-op @ acquiring load 2783 mov r2, rINST, lsr #8 @ r2<- AA 2784 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2785 SET_VREG(r1, r2) @ fp[AA]<- r1 2786 GET_INST_OPCODE(ip) @ extract opcode from rINST 2787 GOTO_OPCODE(ip) @ jump to next instruction 2788 2789 2790 /* ------------------------------ */ 2791 .balign 64 2792 .L_OP_SGET_BYTE: /* 0x64 */ 2793 /* File: armv5te/OP_SGET_BYTE.S */ 2794 /* File: armv5te/OP_SGET.S */ 2795 /* 2796 * General 32-bit SGET handler. 2797 * 2798 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2799 */ 2800 /* op vAA, field@BBBB */ 2801 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2802 FETCH(r1, 1) @ r1<- field ref BBBB 2803 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2804 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2805 cmp r0, #0 @ is resolved entry null? 2806 beq .LOP_SGET_BYTE_resolve @ yes, do resolve 2807 .LOP_SGET_BYTE_finish: @ field ptr in r0 2808 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2809 @ no-op @ acquiring load 2810 mov r2, rINST, lsr #8 @ r2<- AA 2811 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2812 SET_VREG(r1, r2) @ fp[AA]<- r1 2813 GET_INST_OPCODE(ip) @ extract opcode from rINST 2814 GOTO_OPCODE(ip) @ jump to next instruction 2815 2816 2817 /* ------------------------------ */ 2818 .balign 64 2819 .L_OP_SGET_CHAR: /* 0x65 */ 2820 /* File: armv5te/OP_SGET_CHAR.S */ 2821 /* File: armv5te/OP_SGET.S */ 2822 /* 2823 * General 32-bit SGET handler. 2824 * 2825 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2826 */ 2827 /* op vAA, field@BBBB */ 2828 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2829 FETCH(r1, 1) @ r1<- field ref BBBB 2830 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2831 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2832 cmp r0, #0 @ is resolved entry null? 2833 beq .LOP_SGET_CHAR_resolve @ yes, do resolve 2834 .LOP_SGET_CHAR_finish: @ field ptr in r0 2835 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2836 @ no-op @ acquiring load 2837 mov r2, rINST, lsr #8 @ r2<- AA 2838 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2839 SET_VREG(r1, r2) @ fp[AA]<- r1 2840 GET_INST_OPCODE(ip) @ extract opcode from rINST 2841 GOTO_OPCODE(ip) @ jump to next instruction 2842 2843 2844 /* ------------------------------ */ 2845 .balign 64 2846 .L_OP_SGET_SHORT: /* 0x66 */ 2847 /* File: armv5te/OP_SGET_SHORT.S */ 2848 /* File: armv5te/OP_SGET.S */ 2849 /* 2850 * General 32-bit SGET handler. 2851 * 2852 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2853 */ 2854 /* op vAA, field@BBBB */ 2855 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2856 FETCH(r1, 1) @ r1<- field ref BBBB 2857 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2858 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2859 cmp r0, #0 @ is resolved entry null? 2860 beq .LOP_SGET_SHORT_resolve @ yes, do resolve 2861 .LOP_SGET_SHORT_finish: @ field ptr in r0 2862 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2863 @ no-op @ acquiring load 2864 mov r2, rINST, lsr #8 @ r2<- AA 2865 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2866 SET_VREG(r1, r2) @ fp[AA]<- r1 2867 GET_INST_OPCODE(ip) @ extract opcode from rINST 2868 GOTO_OPCODE(ip) @ jump to next instruction 2869 2870 2871 /* ------------------------------ */ 2872 .balign 64 2873 .L_OP_SPUT: /* 0x67 */ 2874 /* File: armv5te/OP_SPUT.S */ 2875 /* 2876 * General 32-bit SPUT handler. 2877 * 2878 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2879 */ 2880 /* op vAA, field@BBBB */ 2881 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2882 FETCH(r1, 1) @ r1<- field ref BBBB 2883 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2884 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2885 cmp r0, #0 @ is resolved entry null? 2886 beq .LOP_SPUT_resolve @ yes, do resolve 2887 .LOP_SPUT_finish: @ field ptr in r0 2888 mov r2, rINST, lsr #8 @ r2<- AA 2889 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2890 GET_VREG(r1, r2) @ r1<- fp[AA] 2891 GET_INST_OPCODE(ip) @ extract opcode from rINST 2892 @ no-op @ releasing store 2893 str r1, [r0, #offStaticField_value] @ field<- vAA 2894 @ no-op 2895 GOTO_OPCODE(ip) @ jump to next instruction 2896 2897 /* ------------------------------ */ 2898 .balign 64 2899 .L_OP_SPUT_WIDE: /* 0x68 */ 2900 /* File: armv5te/OP_SPUT_WIDE.S */ 2901 /* 2902 * 64-bit SPUT handler. 2903 */ 2904 /* sput-wide vAA, field@BBBB */ 2905 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- DvmDex 2906 FETCH(r1, 1) @ r1<- field ref BBBB 2907 ldr r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2908 mov r9, rINST, lsr #8 @ r9<- AA 2909 ldr r2, [r10, r1, lsl #2] @ r2<- resolved StaticField ptr 2910 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2911 cmp r2, #0 @ is resolved entry null? 2912 beq .LOP_SPUT_WIDE_resolve @ yes, do resolve 2913 .LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9 2914 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2915 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 2916 GET_INST_OPCODE(r10) @ extract opcode from rINST 2917 .if 0 2918 add r2, r2, #offStaticField_value @ r2<- pointer to data 2919 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 2920 .else 2921 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 2922 .endif 2923 GOTO_OPCODE(r10) @ jump to next instruction 2924 2925 /* ------------------------------ */ 2926 .balign 64 2927 .L_OP_SPUT_OBJECT: /* 0x69 */ 2928 /* File: armv5te/OP_SPUT_OBJECT.S */ 2929 /* 2930 * 32-bit SPUT handler for objects 2931 * 2932 * for: sput-object, sput-object-volatile 2933 */ 2934 /* op vAA, field@BBBB */ 2935 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2936 FETCH(r1, 1) @ r1<- field ref BBBB 2937 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2938 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2939 cmp r0, #0 @ is resolved entry null? 2940 beq .LOP_SPUT_OBJECT_resolve @ yes, do resolve 2941 .LOP_SPUT_OBJECT_finish: @ field ptr in r0 2942 mov r2, rINST, lsr #8 @ r2<- AA 2943 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2944 GET_VREG(r1, r2) @ r1<- fp[AA] 2945 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 2946 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 2947 GET_INST_OPCODE(ip) @ extract opcode from rINST 2948 @ no-op @ releasing store 2949 b .LOP_SPUT_OBJECT_end 2950 2951 /* ------------------------------ */ 2952 .balign 64 2953 .L_OP_SPUT_BOOLEAN: /* 0x6a */ 2954 /* File: armv5te/OP_SPUT_BOOLEAN.S */ 2955 /* File: armv5te/OP_SPUT.S */ 2956 /* 2957 * General 32-bit SPUT handler. 2958 * 2959 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2960 */ 2961 /* op vAA, field@BBBB */ 2962 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2963 FETCH(r1, 1) @ r1<- field ref BBBB 2964 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2965 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2966 cmp r0, #0 @ is resolved entry null? 2967 beq .LOP_SPUT_BOOLEAN_resolve @ yes, do resolve 2968 .LOP_SPUT_BOOLEAN_finish: @ field ptr in r0 2969 mov r2, rINST, lsr #8 @ r2<- AA 2970 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2971 GET_VREG(r1, r2) @ r1<- fp[AA] 2972 GET_INST_OPCODE(ip) @ extract opcode from rINST 2973 @ no-op @ releasing store 2974 str r1, [r0, #offStaticField_value] @ field<- vAA 2975 @ no-op 2976 GOTO_OPCODE(ip) @ jump to next instruction 2977 2978 2979 /* ------------------------------ */ 2980 .balign 64 2981 .L_OP_SPUT_BYTE: /* 0x6b */ 2982 /* File: armv5te/OP_SPUT_BYTE.S */ 2983 /* File: armv5te/OP_SPUT.S */ 2984 /* 2985 * General 32-bit SPUT handler. 2986 * 2987 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2988 */ 2989 /* op vAA, field@BBBB */ 2990 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2991 FETCH(r1, 1) @ r1<- field ref BBBB 2992 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2993 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2994 cmp r0, #0 @ is resolved entry null? 2995 beq .LOP_SPUT_BYTE_resolve @ yes, do resolve 2996 .LOP_SPUT_BYTE_finish: @ field ptr in r0 2997 mov r2, rINST, lsr #8 @ r2<- AA 2998 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2999 GET_VREG(r1, r2) @ r1<- fp[AA] 3000 GET_INST_OPCODE(ip) @ extract opcode from rINST 3001 @ no-op @ releasing store 3002 str r1, [r0, #offStaticField_value] @ field<- vAA 3003 @ no-op 3004 GOTO_OPCODE(ip) @ jump to next instruction 3005 3006 3007 /* ------------------------------ */ 3008 .balign 64 3009 .L_OP_SPUT_CHAR: /* 0x6c */ 3010 /* File: armv5te/OP_SPUT_CHAR.S */ 3011 /* File: armv5te/OP_SPUT.S */ 3012 /* 3013 * General 32-bit SPUT handler. 3014 * 3015 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3016 */ 3017 /* op vAA, field@BBBB */ 3018 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3019 FETCH(r1, 1) @ r1<- field ref BBBB 3020 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 3021 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 3022 cmp r0, #0 @ is resolved entry null? 3023 beq .LOP_SPUT_CHAR_resolve @ yes, do resolve 3024 .LOP_SPUT_CHAR_finish: @ field ptr in r0 3025 mov r2, rINST, lsr #8 @ r2<- AA 3026 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3027 GET_VREG(r1, r2) @ r1<- fp[AA] 3028 GET_INST_OPCODE(ip) @ extract opcode from rINST 3029 @ no-op @ releasing store 3030 str r1, [r0, #offStaticField_value] @ field<- vAA 3031 @ no-op 3032 GOTO_OPCODE(ip) @ jump to next instruction 3033 3034 3035 /* ------------------------------ */ 3036 .balign 64 3037 .L_OP_SPUT_SHORT: /* 0x6d */ 3038 /* File: armv5te/OP_SPUT_SHORT.S */ 3039 /* File: armv5te/OP_SPUT.S */ 3040 /* 3041 * General 32-bit SPUT handler. 3042 * 3043 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3044 */ 3045 /* op vAA, field@BBBB */ 3046 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3047 FETCH(r1, 1) @ r1<- field ref BBBB 3048 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 3049 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 3050 cmp r0, #0 @ is resolved entry null? 3051 beq .LOP_SPUT_SHORT_resolve @ yes, do resolve 3052 .LOP_SPUT_SHORT_finish: @ field ptr in r0 3053 mov r2, rINST, lsr #8 @ r2<- AA 3054 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3055 GET_VREG(r1, r2) @ r1<- fp[AA] 3056 GET_INST_OPCODE(ip) @ extract opcode from rINST 3057 @ no-op @ releasing store 3058 str r1, [r0, #offStaticField_value] @ field<- vAA 3059 @ no-op 3060 GOTO_OPCODE(ip) @ jump to next instruction 3061 3062 3063 /* ------------------------------ */ 3064 .balign 64 3065 .L_OP_INVOKE_VIRTUAL: /* 0x6e */ 3066 /* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3067 /* 3068 * Handle a virtual method call. 3069 * 3070 * for: invoke-virtual, invoke-virtual/range 3071 */ 3072 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3073 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3074 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3075 FETCH(r1, 1) @ r1<- BBBB 3076 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3077 FETCH(r10, 2) @ r10<- GFED or CCCC 3078 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3079 .if (!0) 3080 and r10, r10, #15 @ r10<- D (or stays CCCC) 3081 .endif 3082 cmp r0, #0 @ already resolved? 3083 EXPORT_PC() @ must export for invoke 3084 bne .LOP_INVOKE_VIRTUAL_continue @ yes, continue on 3085 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3086 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3087 mov r2, #METHOD_VIRTUAL @ resolver method type 3088 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3089 cmp r0, #0 @ got null? 3090 bne .LOP_INVOKE_VIRTUAL_continue @ no, continue 3091 b common_exceptionThrown @ yes, handle exception 3092 3093 /* ------------------------------ */ 3094 .balign 64 3095 .L_OP_INVOKE_SUPER: /* 0x6f */ 3096 /* File: armv5te/OP_INVOKE_SUPER.S */ 3097 /* 3098 * Handle a "super" method call. 3099 * 3100 * for: invoke-super, invoke-super/range 3101 */ 3102 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3103 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3104 FETCH(r10, 2) @ r10<- GFED or CCCC 3105 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3106 .if (!0) 3107 and r10, r10, #15 @ r10<- D (or stays CCCC) 3108 .endif 3109 FETCH(r1, 1) @ r1<- BBBB 3110 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3111 GET_VREG(r9, r10) @ r9<- "this" ptr 3112 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3113 cmp r9, #0 @ null "this"? 3114 ldr r10, [rSELF, #offThread_method] @ r10<- current method 3115 beq common_errNullObject @ null "this", throw exception 3116 cmp r0, #0 @ already resolved? 3117 ldr r10, [r10, #offMethod_clazz] @ r10<- method->clazz 3118 EXPORT_PC() @ must export for invoke 3119 bne .LOP_INVOKE_SUPER_continue @ resolved, continue on 3120 b .LOP_INVOKE_SUPER_resolve @ do resolve now 3121 3122 /* ------------------------------ */ 3123 .balign 64 3124 .L_OP_INVOKE_DIRECT: /* 0x70 */ 3125 /* File: armv5te/OP_INVOKE_DIRECT.S */ 3126 /* 3127 * Handle a direct method call. 3128 * 3129 * (We could defer the "is 'this' pointer null" test to the common 3130 * method invocation code, and use a flag to indicate that static 3131 * calls don't count. If we do this as part of copying the arguments 3132 * out we could avoiding loading the first arg twice.) 3133 * 3134 * for: invoke-direct, invoke-direct/range 3135 */ 3136 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3137 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3138 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3139 FETCH(r1, 1) @ r1<- BBBB 3140 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3141 FETCH(r10, 2) @ r10<- GFED or CCCC 3142 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3143 .if (!0) 3144 and r10, r10, #15 @ r10<- D (or stays CCCC) 3145 .endif 3146 cmp r0, #0 @ already resolved? 3147 EXPORT_PC() @ must export for invoke 3148 GET_VREG(r9, r10) @ r9<- "this" ptr 3149 beq .LOP_INVOKE_DIRECT_resolve @ not resolved, do it now 3150 .LOP_INVOKE_DIRECT_finish: 3151 cmp r9, #0 @ null "this" ref? 3152 bne common_invokeMethodNoRange @ r0=method, r9="this" 3153 b common_errNullObject @ yes, throw exception 3154 3155 /* ------------------------------ */ 3156 .balign 64 3157 .L_OP_INVOKE_STATIC: /* 0x71 */ 3158 /* File: armv5te/OP_INVOKE_STATIC.S */ 3159 /* 3160 * Handle a static method call. 3161 * 3162 * for: invoke-static, invoke-static/range 3163 */ 3164 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3165 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3166 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3167 FETCH(r1, 1) @ r1<- BBBB 3168 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3169 mov r9, #0 @ null "this" in delay slot 3170 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3171 #if defined(WITH_JIT) 3172 add r10, r3, r1, lsl #2 @ r10<- &resolved_methodToCall 3173 #endif 3174 cmp r0, #0 @ already resolved? 3175 EXPORT_PC() @ must export for invoke 3176 bne common_invokeMethodNoRange @ yes, continue on 3177 b .LOP_INVOKE_STATIC_resolve 3178 3179 /* ------------------------------ */ 3180 .balign 64 3181 .L_OP_INVOKE_INTERFACE: /* 0x72 */ 3182 /* File: armv5te/OP_INVOKE_INTERFACE.S */ 3183 /* 3184 * Handle an interface method call. 3185 * 3186 * for: invoke-interface, invoke-interface/range 3187 */ 3188 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3189 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3190 FETCH(r2, 2) @ r2<- FEDC or CCCC 3191 FETCH(r1, 1) @ r1<- BBBB 3192 .if (!0) 3193 and r2, r2, #15 @ r2<- C (or stays CCCC) 3194 .endif 3195 EXPORT_PC() @ must export for invoke 3196 GET_VREG(r9, r2) @ r9<- first arg ("this") 3197 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- methodClassDex 3198 cmp r9, #0 @ null obj? 3199 ldr r2, [rSELF, #offThread_method] @ r2<- method 3200 beq common_errNullObject @ yes, fail 3201 ldr r0, [r9, #offObject_clazz] @ r0<- thisPtr->clazz 3202 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3203 cmp r0, #0 @ failed? 3204 beq common_exceptionThrown @ yes, handle exception 3205 b common_invokeMethodNoRange @ (r0=method, r9="this") 3206 3207 /* ------------------------------ */ 3208 .balign 64 3209 .L_OP_UNUSED_73: /* 0x73 */ 3210 /* File: armv5te/OP_UNUSED_73.S */ 3211 /* File: armv5te/unused.S */ 3212 bl common_abort 3213 3214 3215 /* ------------------------------ */ 3216 .balign 64 3217 .L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 3218 /* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */ 3219 /* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3220 /* 3221 * Handle a virtual method call. 3222 * 3223 * for: invoke-virtual, invoke-virtual/range 3224 */ 3225 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3226 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3227 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3228 FETCH(r1, 1) @ r1<- BBBB 3229 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3230 FETCH(r10, 2) @ r10<- GFED or CCCC 3231 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3232 .if (!1) 3233 and r10, r10, #15 @ r10<- D (or stays CCCC) 3234 .endif 3235 cmp r0, #0 @ already resolved? 3236 EXPORT_PC() @ must export for invoke 3237 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ yes, continue on 3238 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3239 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3240 mov r2, #METHOD_VIRTUAL @ resolver method type 3241 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3242 cmp r0, #0 @ got null? 3243 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ no, continue 3244 b common_exceptionThrown @ yes, handle exception 3245 3246 3247 /* ------------------------------ */ 3248 .balign 64 3249 .L_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 3250 /* File: armv5te/OP_INVOKE_SUPER_RANGE.S */ 3251 /* File: armv5te/OP_INVOKE_SUPER.S */ 3252 /* 3253 * Handle a "super" method call. 3254 * 3255 * for: invoke-super, invoke-super/range 3256 */ 3257 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3258 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3259 FETCH(r10, 2) @ r10<- GFED or CCCC 3260 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3261 .if (!1) 3262 and r10, r10, #15 @ r10<- D (or stays CCCC) 3263 .endif 3264 FETCH(r1, 1) @ r1<- BBBB 3265 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3266 GET_VREG(r9, r10) @ r9<- "this" ptr 3267 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3268 cmp r9, #0 @ null "this"? 3269 ldr r10, [rSELF, #offThread_method] @ r10<- current method 3270 beq common_errNullObject @ null "this", throw exception 3271 cmp r0, #0 @ already resolved? 3272 ldr r10, [r10, #offMethod_clazz] @ r10<- method->clazz 3273 EXPORT_PC() @ must export for invoke 3274 bne .LOP_INVOKE_SUPER_RANGE_continue @ resolved, continue on 3275 b .LOP_INVOKE_SUPER_RANGE_resolve @ do resolve now 3276 3277 3278 /* ------------------------------ */ 3279 .balign 64 3280 .L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 3281 /* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */ 3282 /* File: armv5te/OP_INVOKE_DIRECT.S */ 3283 /* 3284 * Handle a direct method call. 3285 * 3286 * (We could defer the "is 'this' pointer null" test to the common 3287 * method invocation code, and use a flag to indicate that static 3288 * calls don't count. If we do this as part of copying the arguments 3289 * out we could avoiding loading the first arg twice.) 3290 * 3291 * for: invoke-direct, invoke-direct/range 3292 */ 3293 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3294 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3295 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3296 FETCH(r1, 1) @ r1<- BBBB 3297 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3298 FETCH(r10, 2) @ r10<- GFED or CCCC 3299 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3300 .if (!1) 3301 and r10, r10, #15 @ r10<- D (or stays CCCC) 3302 .endif 3303 cmp r0, #0 @ already resolved? 3304 EXPORT_PC() @ must export for invoke 3305 GET_VREG(r9, r10) @ r9<- "this" ptr 3306 beq .LOP_INVOKE_DIRECT_RANGE_resolve @ not resolved, do it now 3307 .LOP_INVOKE_DIRECT_RANGE_finish: 3308 cmp r9, #0 @ null "this" ref? 3309 bne common_invokeMethodRange @ r0=method, r9="this" 3310 b common_errNullObject @ yes, throw exception 3311 3312 3313 /* ------------------------------ */ 3314 .balign 64 3315 .L_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 3316 /* File: armv5te/OP_INVOKE_STATIC_RANGE.S */ 3317 /* File: armv5te/OP_INVOKE_STATIC.S */ 3318 /* 3319 * Handle a static method call. 3320 * 3321 * for: invoke-static, invoke-static/range 3322 */ 3323 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3324 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3325 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3326 FETCH(r1, 1) @ r1<- BBBB 3327 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3328 mov r9, #0 @ null "this" in delay slot 3329 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3330 #if defined(WITH_JIT) 3331 add r10, r3, r1, lsl #2 @ r10<- &resolved_methodToCall 3332 #endif 3333 cmp r0, #0 @ already resolved? 3334 EXPORT_PC() @ must export for invoke 3335 bne common_invokeMethodRange @ yes, continue on 3336 b .LOP_INVOKE_STATIC_RANGE_resolve 3337 3338 3339 /* ------------------------------ */ 3340 .balign 64 3341 .L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 3342 /* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */ 3343 /* File: armv5te/OP_INVOKE_INTERFACE.S */ 3344 /* 3345 * Handle an interface method call. 3346 * 3347 * for: invoke-interface, invoke-interface/range 3348 */ 3349 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3350 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3351 FETCH(r2, 2) @ r2<- FEDC or CCCC 3352 FETCH(r1, 1) @ r1<- BBBB 3353 .if (!1) 3354 and r2, r2, #15 @ r2<- C (or stays CCCC) 3355 .endif 3356 EXPORT_PC() @ must export for invoke 3357 GET_VREG(r9, r2) @ r9<- first arg ("this") 3358 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- methodClassDex 3359 cmp r9, #0 @ null obj? 3360 ldr r2, [rSELF, #offThread_method] @ r2<- method 3361 beq common_errNullObject @ yes, fail 3362 ldr r0, [r9, #offObject_clazz] @ r0<- thisPtr->clazz 3363 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3364 cmp r0, #0 @ failed? 3365 beq common_exceptionThrown @ yes, handle exception 3366 b common_invokeMethodRange @ (r0=method, r9="this") 3367 3368 3369 /* ------------------------------ */ 3370 .balign 64 3371 .L_OP_UNUSED_79: /* 0x79 */ 3372 /* File: armv5te/OP_UNUSED_79.S */ 3373 /* File: armv5te/unused.S */ 3374 bl common_abort 3375 3376 3377 /* ------------------------------ */ 3378 .balign 64 3379 .L_OP_UNUSED_7A: /* 0x7a */ 3380 /* File: armv5te/OP_UNUSED_7A.S */ 3381 /* File: armv5te/unused.S */ 3382 bl common_abort 3383 3384 3385 /* ------------------------------ */ 3386 .balign 64 3387 .L_OP_NEG_INT: /* 0x7b */ 3388 /* File: armv6t2/OP_NEG_INT.S */ 3389 /* File: armv6t2/unop.S */ 3390 /* 3391 * Generic 32-bit unary operation. Provide an "instr" line that 3392 * specifies an instruction that performs "result = op r0". 3393 * This could be an ARM instruction or a function call. 3394 * 3395 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3396 * int-to-byte, int-to-char, int-to-short 3397 */ 3398 /* unop vA, vB */ 3399 mov r3, rINST, lsr #12 @ r3<- B 3400 ubfx r9, rINST, #8, #4 @ r9<- A 3401 GET_VREG(r0, r3) @ r0<- vB 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 /* 8-9 instructions */ 3409 3410 3411 /* ------------------------------ */ 3412 .balign 64 3413 .L_OP_NOT_INT: /* 0x7c */ 3414 /* File: armv6t2/OP_NOT_INT.S */ 3415 /* File: armv6t2/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 ubfx r9, rINST, #8, #4 @ r9<- A 3427 GET_VREG(r0, r3) @ r0<- vB 3428 @ optional op; may set condition codes 3429 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3430 mvn r0, r0 @ r0<- op, r0-r3 changed 3431 GET_INST_OPCODE(ip) @ extract opcode from rINST 3432 SET_VREG(r0, r9) @ vAA<- r0 3433 GOTO_OPCODE(ip) @ jump to next instruction 3434 /* 8-9 instructions */ 3435 3436 3437 /* ------------------------------ */ 3438 .balign 64 3439 .L_OP_NEG_LONG: /* 0x7d */ 3440 /* File: armv6t2/OP_NEG_LONG.S */ 3441 /* File: armv6t2/unopWide.S */ 3442 /* 3443 * Generic 64-bit unary operation. Provide an "instr" line that 3444 * specifies an instruction that performs "result = op r0/r1". 3445 * This could be an ARM instruction or a function call. 3446 * 3447 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3448 */ 3449 /* unop vA, vB */ 3450 mov r3, rINST, lsr #12 @ r3<- B 3451 ubfx r9, rINST, #8, #4 @ r9<- A 3452 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3453 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3454 ldmia r3, {r0-r1} @ r0/r1<- vAA 3455 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3456 rsbs r0, r0, #0 @ optional op; may set condition codes 3457 rsc r1, r1, #0 @ r0/r1<- op, r2-r3 changed 3458 GET_INST_OPCODE(ip) @ extract opcode from rINST 3459 stmia r9, {r0-r1} @ vAA<- r0/r1 3460 GOTO_OPCODE(ip) @ jump to next instruction 3461 /* 10-11 instructions */ 3462 3463 3464 /* ------------------------------ */ 3465 .balign 64 3466 .L_OP_NOT_LONG: /* 0x7e */ 3467 /* File: armv6t2/OP_NOT_LONG.S */ 3468 /* File: armv6t2/unopWide.S */ 3469 /* 3470 * Generic 64-bit unary operation. Provide an "instr" line that 3471 * specifies an instruction that performs "result = op r0/r1". 3472 * This could be an ARM instruction or a function call. 3473 * 3474 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3475 */ 3476 /* unop vA, vB */ 3477 mov r3, rINST, lsr #12 @ r3<- B 3478 ubfx r9, rINST, #8, #4 @ r9<- A 3479 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3480 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3481 ldmia r3, {r0-r1} @ r0/r1<- vAA 3482 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3483 mvn r0, r0 @ optional op; may set condition codes 3484 mvn r1, r1 @ r0/r1<- op, r2-r3 changed 3485 GET_INST_OPCODE(ip) @ extract opcode from rINST 3486 stmia r9, {r0-r1} @ vAA<- r0/r1 3487 GOTO_OPCODE(ip) @ jump to next instruction 3488 /* 10-11 instructions */ 3489 3490 3491 /* ------------------------------ */ 3492 .balign 64 3493 .L_OP_NEG_FLOAT: /* 0x7f */ 3494 /* File: armv6t2/OP_NEG_FLOAT.S */ 3495 /* File: armv6t2/unop.S */ 3496 /* 3497 * Generic 32-bit unary operation. Provide an "instr" line that 3498 * specifies an instruction that performs "result = op r0". 3499 * This could be an ARM instruction or a function call. 3500 * 3501 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3502 * int-to-byte, int-to-char, int-to-short 3503 */ 3504 /* unop vA, vB */ 3505 mov r3, rINST, lsr #12 @ r3<- B 3506 ubfx r9, rINST, #8, #4 @ r9<- A 3507 GET_VREG(r0, r3) @ r0<- vB 3508 @ optional op; may set condition codes 3509 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3510 add r0, r0, #0x80000000 @ r0<- op, r0-r3 changed 3511 GET_INST_OPCODE(ip) @ extract opcode from rINST 3512 SET_VREG(r0, r9) @ vAA<- r0 3513 GOTO_OPCODE(ip) @ jump to next instruction 3514 /* 8-9 instructions */ 3515 3516 3517 /* ------------------------------ */ 3518 .balign 64 3519 .L_OP_NEG_DOUBLE: /* 0x80 */ 3520 /* File: armv6t2/OP_NEG_DOUBLE.S */ 3521 /* File: armv6t2/unopWide.S */ 3522 /* 3523 * Generic 64-bit unary operation. Provide an "instr" line that 3524 * specifies an instruction that performs "result = op r0/r1". 3525 * This could be an ARM instruction or a function call. 3526 * 3527 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3528 */ 3529 /* unop vA, vB */ 3530 mov r3, rINST, lsr #12 @ r3<- B 3531 ubfx r9, rINST, #8, #4 @ r9<- A 3532 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3533 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3534 ldmia r3, {r0-r1} @ r0/r1<- vAA 3535 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3536 @ optional op; may set condition codes 3537 add r1, r1, #0x80000000 @ r0/r1<- op, r2-r3 changed 3538 GET_INST_OPCODE(ip) @ extract opcode from rINST 3539 stmia r9, {r0-r1} @ vAA<- r0/r1 3540 GOTO_OPCODE(ip) @ jump to next instruction 3541 /* 10-11 instructions */ 3542 3543 3544 /* ------------------------------ */ 3545 .balign 64 3546 .L_OP_INT_TO_LONG: /* 0x81 */ 3547 /* File: armv6t2/OP_INT_TO_LONG.S */ 3548 /* File: armv6t2/unopWider.S */ 3549 /* 3550 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3551 * that specifies an instruction that performs "result = op r0", where 3552 * "result" is a 64-bit quantity in r0/r1. 3553 * 3554 * For: int-to-long, int-to-double, float-to-long, float-to-double 3555 */ 3556 /* unop vA, vB */ 3557 mov r3, rINST, lsr #12 @ r3<- B 3558 ubfx r9, rINST, #8, #4 @ r9<- A 3559 GET_VREG(r0, r3) @ r0<- vB 3560 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3561 @ optional op; may set condition codes 3562 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3563 mov r1, r0, asr #31 @ r0<- op, r0-r3 changed 3564 GET_INST_OPCODE(ip) @ extract opcode from rINST 3565 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3566 GOTO_OPCODE(ip) @ jump to next instruction 3567 /* 9-10 instructions */ 3568 3569 3570 /* ------------------------------ */ 3571 .balign 64 3572 .L_OP_INT_TO_FLOAT: /* 0x82 */ 3573 /* File: arm-vfp/OP_INT_TO_FLOAT.S */ 3574 /* File: arm-vfp/funop.S */ 3575 /* 3576 * Generic 32-bit unary floating-point operation. Provide an "instr" 3577 * line that specifies an instruction that performs "s1 = op s0". 3578 * 3579 * for: int-to-float, float-to-int 3580 */ 3581 /* unop vA, vB */ 3582 mov r3, rINST, lsr #12 @ r3<- B 3583 mov r9, rINST, lsr #8 @ r9<- A+ 3584 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3585 flds s0, [r3] @ s0<- vB 3586 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3587 and r9, r9, #15 @ r9<- A 3588 fsitos s1, s0 @ s1<- op 3589 GET_INST_OPCODE(ip) @ extract opcode from rINST 3590 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3591 fsts s1, [r9] @ vA<- s1 3592 GOTO_OPCODE(ip) @ jump to next instruction 3593 3594 3595 /* ------------------------------ */ 3596 .balign 64 3597 .L_OP_INT_TO_DOUBLE: /* 0x83 */ 3598 /* File: arm-vfp/OP_INT_TO_DOUBLE.S */ 3599 /* File: arm-vfp/funopWider.S */ 3600 /* 3601 * Generic 32bit-to-64bit floating point unary operation. Provide an 3602 * "instr" line that specifies an instruction that performs "d0 = op s0". 3603 * 3604 * For: int-to-double, float-to-double 3605 */ 3606 /* unop vA, vB */ 3607 mov r3, rINST, lsr #12 @ r3<- B 3608 mov r9, rINST, lsr #8 @ r9<- A+ 3609 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3610 flds s0, [r3] @ s0<- vB 3611 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3612 and r9, r9, #15 @ r9<- A 3613 fsitod d0, s0 @ d0<- op 3614 GET_INST_OPCODE(ip) @ extract opcode from rINST 3615 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3616 fstd d0, [r9] @ vA<- d0 3617 GOTO_OPCODE(ip) @ jump to next instruction 3618 3619 3620 /* ------------------------------ */ 3621 .balign 64 3622 .L_OP_LONG_TO_INT: /* 0x84 */ 3623 /* File: armv5te/OP_LONG_TO_INT.S */ 3624 /* we ignore the high word, making this equivalent to a 32-bit reg move */ 3625 /* File: armv5te/OP_MOVE.S */ 3626 /* for move, move-object, long-to-int */ 3627 /* op vA, vB */ 3628 mov r1, rINST, lsr #12 @ r1<- B from 15:12 3629 mov r0, rINST, lsr #8 @ r0<- A from 11:8 3630 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3631 GET_VREG(r2, r1) @ r2<- fp[B] 3632 and r0, r0, #15 3633 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 3634 SET_VREG(r2, r0) @ fp[A]<- r2 3635 GOTO_OPCODE(ip) @ execute next instruction 3636 3637 3638 /* ------------------------------ */ 3639 .balign 64 3640 .L_OP_LONG_TO_FLOAT: /* 0x85 */ 3641 /* File: armv6t2/OP_LONG_TO_FLOAT.S */ 3642 /* File: armv6t2/unopNarrower.S */ 3643 /* 3644 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 3645 * that specifies an instruction that performs "result = op r0/r1", where 3646 * "result" is a 32-bit quantity in r0. 3647 * 3648 * For: long-to-float, double-to-int, double-to-float 3649 * 3650 * (This would work for long-to-int, but that instruction is actually 3651 * an exact match for OP_MOVE.) 3652 */ 3653 /* unop vA, vB */ 3654 mov r3, rINST, lsr #12 @ r3<- B 3655 ubfx r9, rINST, #8, #4 @ r9<- A 3656 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3657 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 3658 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3659 @ optional op; may set condition codes 3660 bl __aeabi_l2f @ r0<- op, r0-r3 changed 3661 GET_INST_OPCODE(ip) @ extract opcode from rINST 3662 SET_VREG(r0, r9) @ vA<- r0 3663 GOTO_OPCODE(ip) @ jump to next instruction 3664 /* 9-10 instructions */ 3665 3666 3667 /* ------------------------------ */ 3668 .balign 64 3669 .L_OP_LONG_TO_DOUBLE: /* 0x86 */ 3670 /* File: armv6t2/OP_LONG_TO_DOUBLE.S */ 3671 /* File: armv6t2/unopWide.S */ 3672 /* 3673 * Generic 64-bit unary operation. Provide an "instr" line that 3674 * specifies an instruction that performs "result = op r0/r1". 3675 * This could be an ARM instruction or a function call. 3676 * 3677 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3678 */ 3679 /* unop vA, vB */ 3680 mov r3, rINST, lsr #12 @ r3<- B 3681 ubfx r9, rINST, #8, #4 @ r9<- A 3682 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3683 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3684 ldmia r3, {r0-r1} @ r0/r1<- vAA 3685 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3686 @ optional op; may set condition codes 3687 bl __aeabi_l2d @ r0/r1<- op, r2-r3 changed 3688 GET_INST_OPCODE(ip) @ extract opcode from rINST 3689 stmia r9, {r0-r1} @ vAA<- r0/r1 3690 GOTO_OPCODE(ip) @ jump to next instruction 3691 /* 10-11 instructions */ 3692 3693 3694 /* ------------------------------ */ 3695 .balign 64 3696 .L_OP_FLOAT_TO_INT: /* 0x87 */ 3697 /* File: arm-vfp/OP_FLOAT_TO_INT.S */ 3698 /* File: arm-vfp/funop.S */ 3699 /* 3700 * Generic 32-bit unary floating-point operation. Provide an "instr" 3701 * line that specifies an instruction that performs "s1 = op s0". 3702 * 3703 * for: int-to-float, float-to-int 3704 */ 3705 /* unop vA, vB */ 3706 mov r3, rINST, lsr #12 @ r3<- B 3707 mov r9, rINST, lsr #8 @ r9<- A+ 3708 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3709 flds s0, [r3] @ s0<- vB 3710 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3711 and r9, r9, #15 @ r9<- A 3712 ftosizs s1, s0 @ s1<- op 3713 GET_INST_OPCODE(ip) @ extract opcode from rINST 3714 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3715 fsts s1, [r9] @ vA<- s1 3716 GOTO_OPCODE(ip) @ jump to next instruction 3717 3718 3719 /* ------------------------------ */ 3720 .balign 64 3721 .L_OP_FLOAT_TO_LONG: /* 0x88 */ 3722 /* File: armv6t2/OP_FLOAT_TO_LONG.S */ 3723 @include "armv6t2/unopWider.S" {"instr":"bl __aeabi_f2lz"} 3724 /* File: armv6t2/unopWider.S */ 3725 /* 3726 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3727 * that specifies an instruction that performs "result = op r0", where 3728 * "result" is a 64-bit quantity in r0/r1. 3729 * 3730 * For: int-to-long, int-to-double, float-to-long, float-to-double 3731 */ 3732 /* unop vA, vB */ 3733 mov r3, rINST, lsr #12 @ r3<- B 3734 ubfx r9, rINST, #8, #4 @ r9<- A 3735 GET_VREG(r0, r3) @ r0<- vB 3736 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3737 @ optional op; may set condition codes 3738 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3739 bl f2l_doconv @ r0<- op, r0-r3 changed 3740 GET_INST_OPCODE(ip) @ extract opcode from rINST 3741 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3742 GOTO_OPCODE(ip) @ jump to next instruction 3743 /* 9-10 instructions */ 3744 3745 3746 3747 /* ------------------------------ */ 3748 .balign 64 3749 .L_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 3750 /* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */ 3751 /* File: arm-vfp/funopWider.S */ 3752 /* 3753 * Generic 32bit-to-64bit floating point unary operation. Provide an 3754 * "instr" line that specifies an instruction that performs "d0 = op s0". 3755 * 3756 * For: int-to-double, float-to-double 3757 */ 3758 /* unop vA, vB */ 3759 mov r3, rINST, lsr #12 @ r3<- B 3760 mov r9, rINST, lsr #8 @ r9<- A+ 3761 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3762 flds s0, [r3] @ s0<- vB 3763 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3764 and r9, r9, #15 @ r9<- A 3765 fcvtds d0, s0 @ d0<- op 3766 GET_INST_OPCODE(ip) @ extract opcode from rINST 3767 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3768 fstd d0, [r9] @ vA<- d0 3769 GOTO_OPCODE(ip) @ jump to next instruction 3770 3771 3772 /* ------------------------------ */ 3773 .balign 64 3774 .L_OP_DOUBLE_TO_INT: /* 0x8a */ 3775 /* File: arm-vfp/OP_DOUBLE_TO_INT.S */ 3776 /* File: arm-vfp/funopNarrower.S */ 3777 /* 3778 * Generic 64bit-to-32bit unary floating point operation. Provide an 3779 * "instr" line that specifies an instruction that performs "s0 = op d0". 3780 * 3781 * For: double-to-int, double-to-float 3782 */ 3783 /* unop vA, vB */ 3784 mov r3, rINST, lsr #12 @ r3<- B 3785 mov r9, rINST, lsr #8 @ r9<- A+ 3786 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3787 fldd d0, [r3] @ d0<- vB 3788 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3789 and r9, r9, #15 @ r9<- A 3790 ftosizd s0, d0 @ s0<- op 3791 GET_INST_OPCODE(ip) @ extract opcode from rINST 3792 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3793 fsts s0, [r9] @ vA<- s0 3794 GOTO_OPCODE(ip) @ jump to next instruction 3795 3796 3797 /* ------------------------------ */ 3798 .balign 64 3799 .L_OP_DOUBLE_TO_LONG: /* 0x8b */ 3800 /* File: armv6t2/OP_DOUBLE_TO_LONG.S */ 3801 @include "armv6t2/unopWide.S" {"instr":"bl __aeabi_d2lz"} 3802 /* File: armv6t2/unopWide.S */ 3803 /* 3804 * Generic 64-bit unary operation. Provide an "instr" line that 3805 * specifies an instruction that performs "result = op r0/r1". 3806 * This could be an ARM instruction or a function call. 3807 * 3808 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3809 */ 3810 /* unop vA, vB */ 3811 mov r3, rINST, lsr #12 @ r3<- B 3812 ubfx r9, rINST, #8, #4 @ r9<- A 3813 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3814 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3815 ldmia r3, {r0-r1} @ r0/r1<- vAA 3816 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3817 @ optional op; may set condition codes 3818 bl d2l_doconv @ r0/r1<- op, r2-r3 changed 3819 GET_INST_OPCODE(ip) @ extract opcode from rINST 3820 stmia r9, {r0-r1} @ vAA<- r0/r1 3821 GOTO_OPCODE(ip) @ jump to next instruction 3822 /* 10-11 instructions */ 3823 3824 3825 3826 /* ------------------------------ */ 3827 .balign 64 3828 .L_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 3829 /* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */ 3830 /* File: arm-vfp/funopNarrower.S */ 3831 /* 3832 * Generic 64bit-to-32bit unary floating point operation. Provide an 3833 * "instr" line that specifies an instruction that performs "s0 = op d0". 3834 * 3835 * For: double-to-int, double-to-float 3836 */ 3837 /* unop vA, vB */ 3838 mov r3, rINST, lsr #12 @ r3<- B 3839 mov r9, rINST, lsr #8 @ r9<- A+ 3840 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3841 fldd d0, [r3] @ d0<- vB 3842 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3843 and r9, r9, #15 @ r9<- A 3844 fcvtsd s0, d0 @ s0<- op 3845 GET_INST_OPCODE(ip) @ extract opcode from rINST 3846 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3847 fsts s0, [r9] @ vA<- s0 3848 GOTO_OPCODE(ip) @ jump to next instruction 3849 3850 3851 /* ------------------------------ */ 3852 .balign 64 3853 .L_OP_INT_TO_BYTE: /* 0x8d */ 3854 /* File: armv6t2/OP_INT_TO_BYTE.S */ 3855 /* File: armv6t2/unop.S */ 3856 /* 3857 * Generic 32-bit unary operation. Provide an "instr" line that 3858 * specifies an instruction that performs "result = op r0". 3859 * This could be an ARM instruction or a function call. 3860 * 3861 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3862 * int-to-byte, int-to-char, int-to-short 3863 */ 3864 /* unop vA, vB */ 3865 mov r3, rINST, lsr #12 @ r3<- B 3866 ubfx r9, rINST, #8, #4 @ r9<- A 3867 GET_VREG(r0, r3) @ r0<- vB 3868 @ optional op; may set condition codes 3869 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3870 sxtb r0, r0 @ r0<- op, r0-r3 changed 3871 GET_INST_OPCODE(ip) @ extract opcode from rINST 3872 SET_VREG(r0, r9) @ vAA<- r0 3873 GOTO_OPCODE(ip) @ jump to next instruction 3874 /* 8-9 instructions */ 3875 3876 3877 /* ------------------------------ */ 3878 .balign 64 3879 .L_OP_INT_TO_CHAR: /* 0x8e */ 3880 /* File: armv6t2/OP_INT_TO_CHAR.S */ 3881 /* File: armv6t2/unop.S */ 3882 /* 3883 * Generic 32-bit unary operation. Provide an "instr" line that 3884 * specifies an instruction that performs "result = op r0". 3885 * This could be an ARM instruction or a function call. 3886 * 3887 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3888 * int-to-byte, int-to-char, int-to-short 3889 */ 3890 /* unop vA, vB */ 3891 mov r3, rINST, lsr #12 @ r3<- B 3892 ubfx r9, rINST, #8, #4 @ r9<- A 3893 GET_VREG(r0, r3) @ r0<- vB 3894 @ optional op; may set condition codes 3895 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3896 uxth r0, r0 @ r0<- op, r0-r3 changed 3897 GET_INST_OPCODE(ip) @ extract opcode from rINST 3898 SET_VREG(r0, r9) @ vAA<- r0 3899 GOTO_OPCODE(ip) @ jump to next instruction 3900 /* 8-9 instructions */ 3901 3902 3903 /* ------------------------------ */ 3904 .balign 64 3905 .L_OP_INT_TO_SHORT: /* 0x8f */ 3906 /* File: armv6t2/OP_INT_TO_SHORT.S */ 3907 /* File: armv6t2/unop.S */ 3908 /* 3909 * Generic 32-bit unary operation. Provide an "instr" line that 3910 * specifies an instruction that performs "result = op r0". 3911 * This could be an ARM instruction or a function call. 3912 * 3913 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3914 * int-to-byte, int-to-char, int-to-short 3915 */ 3916 /* unop vA, vB */ 3917 mov r3, rINST, lsr #12 @ r3<- B 3918 ubfx r9, rINST, #8, #4 @ r9<- A 3919 GET_VREG(r0, r3) @ r0<- vB 3920 @ optional op; may set condition codes 3921 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3922 sxth r0, r0 @ r0<- op, r0-r3 changed 3923 GET_INST_OPCODE(ip) @ extract opcode from rINST 3924 SET_VREG(r0, r9) @ vAA<- r0 3925 GOTO_OPCODE(ip) @ jump to next instruction 3926 /* 8-9 instructions */ 3927 3928 3929 /* ------------------------------ */ 3930 .balign 64 3931 .L_OP_ADD_INT: /* 0x90 */ 3932 /* File: armv5te/OP_ADD_INT.S */ 3933 /* File: armv5te/binop.S */ 3934 /* 3935 * Generic 32-bit binary operation. Provide an "instr" line that 3936 * specifies an instruction that performs "result = r0 op r1". 3937 * This could be an ARM instruction or a function call. (If the result 3938 * comes back in a register other than r0, you can override "result".) 3939 * 3940 * If "chkzero" is set to 1, we perform a divide-by-zero check on 3941 * vCC (r1). Useful for integer division and modulus. Note that we 3942 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 3943 * handles it correctly. 3944 * 3945 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 3946 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 3947 * mul-float, div-float, rem-float 3948 */ 3949 /* binop vAA, vBB, vCC */ 3950 FETCH(r0, 1) @ r0<- CCBB 3951 mov r9, rINST, lsr #8 @ r9<- AA 3952 mov r3, r0, lsr #8 @ r3<- CC 3953 and r2, r0, #255 @ r2<- BB 3954 GET_VREG(r1, r3) @ r1<- vCC 3955 GET_VREG(r0, r2) @ r0<- vBB 3956 .if 0 3957 cmp r1, #0 @ is second operand zero? 3958 beq common_errDivideByZero 3959 .endif 3960 3961 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3962 @ optional op; may set condition codes 3963 add r0, r0, r1 @ r0<- op, r0-r3 changed 3964 GET_INST_OPCODE(ip) @ extract opcode from rINST 3965 SET_VREG(r0, r9) @ vAA<- r0 3966 GOTO_OPCODE(ip) @ jump to next instruction 3967 /* 11-14 instructions */ 3968 3969 3970 /* ------------------------------ */ 3971 .balign 64 3972 .L_OP_SUB_INT: /* 0x91 */ 3973 /* File: armv5te/OP_SUB_INT.S */ 3974 /* File: armv5te/binop.S */ 3975 /* 3976 * Generic 32-bit binary operation. Provide an "instr" line that 3977 * specifies an instruction that performs "result = r0 op r1". 3978 * This could be an ARM instruction or a function call. (If the result 3979 * comes back in a register other than r0, you can override "result".) 3980 * 3981 * If "chkzero" is set to 1, we perform a divide-by-zero check on 3982 * vCC (r1). Useful for integer division and modulus. Note that we 3983 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 3984 * handles it correctly. 3985 * 3986 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 3987 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 3988 * mul-float, div-float, rem-float 3989 */ 3990 /* binop vAA, vBB, vCC */ 3991 FETCH(r0, 1) @ r0<- CCBB 3992 mov r9, rINST, lsr #8 @ r9<- AA 3993 mov r3, r0, lsr #8 @ r3<- CC 3994 and r2, r0, #255 @ r2<- BB 3995 GET_VREG(r1, r3) @ r1<- vCC 3996 GET_VREG(r0, r2) @ r0<- vBB 3997 .if 0 3998 cmp r1, #0 @ is second operand zero? 3999 beq common_errDivideByZero 4000 .endif 4001 4002 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4003 @ optional op; may set condition codes 4004 sub r0, r0, r1 @ r0<- op, r0-r3 changed 4005 GET_INST_OPCODE(ip) @ extract opcode from rINST 4006 SET_VREG(r0, r9) @ vAA<- r0 4007 GOTO_OPCODE(ip) @ jump to next instruction 4008 /* 11-14 instructions */ 4009 4010 4011 /* ------------------------------ */ 4012 .balign 64 4013 .L_OP_MUL_INT: /* 0x92 */ 4014 /* File: armv5te/OP_MUL_INT.S */ 4015 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 4016 /* File: armv5te/binop.S */ 4017 /* 4018 * Generic 32-bit binary operation. Provide an "instr" line that 4019 * specifies an instruction that performs "result = r0 op r1". 4020 * This could be an ARM instruction or a function call. (If the result 4021 * comes back in a register other than r0, you can override "result".) 4022 * 4023 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4024 * vCC (r1). Useful for integer division and modulus. Note that we 4025 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4026 * handles it correctly. 4027 * 4028 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4029 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4030 * mul-float, div-float, rem-float 4031 */ 4032 /* binop vAA, vBB, vCC */ 4033 FETCH(r0, 1) @ r0<- CCBB 4034 mov r9, rINST, lsr #8 @ r9<- AA 4035 mov r3, r0, lsr #8 @ r3<- CC 4036 and r2, r0, #255 @ r2<- BB 4037 GET_VREG(r1, r3) @ r1<- vCC 4038 GET_VREG(r0, r2) @ r0<- vBB 4039 .if 0 4040 cmp r1, #0 @ is second operand zero? 4041 beq common_errDivideByZero 4042 .endif 4043 4044 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4045 @ optional op; may set condition codes 4046 mul r0, r1, r0 @ r0<- op, r0-r3 changed 4047 GET_INST_OPCODE(ip) @ extract opcode from rINST 4048 SET_VREG(r0, r9) @ vAA<- r0 4049 GOTO_OPCODE(ip) @ jump to next instruction 4050 /* 11-14 instructions */ 4051 4052 4053 /* ------------------------------ */ 4054 .balign 64 4055 .L_OP_DIV_INT: /* 0x93 */ 4056 /* File: armv5te/OP_DIV_INT.S */ 4057 /* File: armv5te/binop.S */ 4058 /* 4059 * Generic 32-bit binary operation. Provide an "instr" line that 4060 * specifies an instruction that performs "result = r0 op r1". 4061 * This could be an ARM instruction or a function call. (If the result 4062 * comes back in a register other than r0, you can override "result".) 4063 * 4064 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4065 * vCC (r1). Useful for integer division and modulus. Note that we 4066 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4067 * handles it correctly. 4068 * 4069 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4070 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4071 * mul-float, div-float, rem-float 4072 */ 4073 /* binop vAA, vBB, vCC */ 4074 FETCH(r0, 1) @ r0<- CCBB 4075 mov r9, rINST, lsr #8 @ r9<- AA 4076 mov r3, r0, lsr #8 @ r3<- CC 4077 and r2, r0, #255 @ r2<- BB 4078 GET_VREG(r1, r3) @ r1<- vCC 4079 GET_VREG(r0, r2) @ r0<- vBB 4080 .if 1 4081 cmp r1, #0 @ is second operand zero? 4082 beq common_errDivideByZero 4083 .endif 4084 4085 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4086 @ optional op; may set condition codes 4087 bl __aeabi_idiv @ r0<- op, r0-r3 changed 4088 GET_INST_OPCODE(ip) @ extract opcode from rINST 4089 SET_VREG(r0, r9) @ vAA<- r0 4090 GOTO_OPCODE(ip) @ jump to next instruction 4091 /* 11-14 instructions */ 4092 4093 4094 /* ------------------------------ */ 4095 .balign 64 4096 .L_OP_REM_INT: /* 0x94 */ 4097 /* File: armv5te/OP_REM_INT.S */ 4098 /* idivmod returns quotient in r0 and remainder in r1 */ 4099 /* File: armv5te/binop.S */ 4100 /* 4101 * Generic 32-bit binary operation. Provide an "instr" line that 4102 * specifies an instruction that performs "result = r0 op r1". 4103 * This could be an ARM instruction or a function call. (If the result 4104 * comes back in a register other than r0, you can override "result".) 4105 * 4106 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4107 * vCC (r1). Useful for integer division and modulus. Note that we 4108 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4109 * handles it correctly. 4110 * 4111 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4112 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4113 * mul-float, div-float, rem-float 4114 */ 4115 /* binop vAA, vBB, vCC */ 4116 FETCH(r0, 1) @ r0<- CCBB 4117 mov r9, rINST, lsr #8 @ r9<- AA 4118 mov r3, r0, lsr #8 @ r3<- CC 4119 and r2, r0, #255 @ r2<- BB 4120 GET_VREG(r1, r3) @ r1<- vCC 4121 GET_VREG(r0, r2) @ r0<- vBB 4122 .if 1 4123 cmp r1, #0 @ is second operand zero? 4124 beq common_errDivideByZero 4125 .endif 4126 4127 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4128 @ optional op; may set condition codes 4129 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 4130 GET_INST_OPCODE(ip) @ extract opcode from rINST 4131 SET_VREG(r1, r9) @ vAA<- r1 4132 GOTO_OPCODE(ip) @ jump to next instruction 4133 /* 11-14 instructions */ 4134 4135 4136 /* ------------------------------ */ 4137 .balign 64 4138 .L_OP_AND_INT: /* 0x95 */ 4139 /* File: armv5te/OP_AND_INT.S */ 4140 /* File: armv5te/binop.S */ 4141 /* 4142 * Generic 32-bit binary operation. Provide an "instr" line that 4143 * specifies an instruction that performs "result = r0 op r1". 4144 * This could be an ARM instruction or a function call. (If the result 4145 * comes back in a register other than r0, you can override "result".) 4146 * 4147 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4148 * vCC (r1). Useful for integer division and modulus. Note that we 4149 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4150 * handles it correctly. 4151 * 4152 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4153 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4154 * mul-float, div-float, rem-float 4155 */ 4156 /* binop vAA, vBB, vCC */ 4157 FETCH(r0, 1) @ r0<- CCBB 4158 mov r9, rINST, lsr #8 @ r9<- AA 4159 mov r3, r0, lsr #8 @ r3<- CC 4160 and r2, r0, #255 @ r2<- BB 4161 GET_VREG(r1, r3) @ r1<- vCC 4162 GET_VREG(r0, r2) @ r0<- vBB 4163 .if 0 4164 cmp r1, #0 @ is second operand zero? 4165 beq common_errDivideByZero 4166 .endif 4167 4168 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4169 @ optional op; may set condition codes 4170 and r0, r0, r1 @ r0<- op, r0-r3 changed 4171 GET_INST_OPCODE(ip) @ extract opcode from rINST 4172 SET_VREG(r0, r9) @ vAA<- r0 4173 GOTO_OPCODE(ip) @ jump to next instruction 4174 /* 11-14 instructions */ 4175 4176 4177 /* ------------------------------ */ 4178 .balign 64 4179 .L_OP_OR_INT: /* 0x96 */ 4180 /* File: armv5te/OP_OR_INT.S */ 4181 /* File: armv5te/binop.S */ 4182 /* 4183 * Generic 32-bit binary operation. Provide an "instr" line that 4184 * specifies an instruction that performs "result = r0 op r1". 4185 * This could be an ARM instruction or a function call. (If the result 4186 * comes back in a register other than r0, you can override "result".) 4187 * 4188 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4189 * vCC (r1). Useful for integer division and modulus. Note that we 4190 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4191 * handles it correctly. 4192 * 4193 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4194 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4195 * mul-float, div-float, rem-float 4196 */ 4197 /* binop vAA, vBB, vCC */ 4198 FETCH(r0, 1) @ r0<- CCBB 4199 mov r9, rINST, lsr #8 @ r9<- AA 4200 mov r3, r0, lsr #8 @ r3<- CC 4201 and r2, r0, #255 @ r2<- BB 4202 GET_VREG(r1, r3) @ r1<- vCC 4203 GET_VREG(r0, r2) @ r0<- vBB 4204 .if 0 4205 cmp r1, #0 @ is second operand zero? 4206 beq common_errDivideByZero 4207 .endif 4208 4209 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4210 @ optional op; may set condition codes 4211 orr r0, r0, r1 @ r0<- op, r0-r3 changed 4212 GET_INST_OPCODE(ip) @ extract opcode from rINST 4213 SET_VREG(r0, r9) @ vAA<- r0 4214 GOTO_OPCODE(ip) @ jump to next instruction 4215 /* 11-14 instructions */ 4216 4217 4218 /* ------------------------------ */ 4219 .balign 64 4220 .L_OP_XOR_INT: /* 0x97 */ 4221 /* File: armv5te/OP_XOR_INT.S */ 4222 /* File: armv5te/binop.S */ 4223 /* 4224 * Generic 32-bit binary operation. Provide an "instr" line that 4225 * specifies an instruction that performs "result = r0 op r1". 4226 * This could be an ARM instruction or a function call. (If the result 4227 * comes back in a register other than r0, you can override "result".) 4228 * 4229 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4230 * vCC (r1). Useful for integer division and modulus. Note that we 4231 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4232 * handles it correctly. 4233 * 4234 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4235 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4236 * mul-float, div-float, rem-float 4237 */ 4238 /* binop vAA, vBB, vCC */ 4239 FETCH(r0, 1) @ r0<- CCBB 4240 mov r9, rINST, lsr #8 @ r9<- AA 4241 mov r3, r0, lsr #8 @ r3<- CC 4242 and r2, r0, #255 @ r2<- BB 4243 GET_VREG(r1, r3) @ r1<- vCC 4244 GET_VREG(r0, r2) @ r0<- vBB 4245 .if 0 4246 cmp r1, #0 @ is second operand zero? 4247 beq common_errDivideByZero 4248 .endif 4249 4250 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4251 @ optional op; may set condition codes 4252 eor r0, r0, r1 @ r0<- op, r0-r3 changed 4253 GET_INST_OPCODE(ip) @ extract opcode from rINST 4254 SET_VREG(r0, r9) @ vAA<- r0 4255 GOTO_OPCODE(ip) @ jump to next instruction 4256 /* 11-14 instructions */ 4257 4258 4259 /* ------------------------------ */ 4260 .balign 64 4261 .L_OP_SHL_INT: /* 0x98 */ 4262 /* File: armv5te/OP_SHL_INT.S */ 4263 /* File: armv5te/binop.S */ 4264 /* 4265 * Generic 32-bit binary operation. Provide an "instr" line that 4266 * specifies an instruction that performs "result = r0 op r1". 4267 * This could be an ARM instruction or a function call. (If the result 4268 * comes back in a register other than r0, you can override "result".) 4269 * 4270 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4271 * vCC (r1). Useful for integer division and modulus. Note that we 4272 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4273 * handles it correctly. 4274 * 4275 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4276 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4277 * mul-float, div-float, rem-float 4278 */ 4279 /* binop vAA, vBB, vCC */ 4280 FETCH(r0, 1) @ r0<- CCBB 4281 mov r9, rINST, lsr #8 @ r9<- AA 4282 mov r3, r0, lsr #8 @ r3<- CC 4283 and r2, r0, #255 @ r2<- BB 4284 GET_VREG(r1, r3) @ r1<- vCC 4285 GET_VREG(r0, r2) @ r0<- vBB 4286 .if 0 4287 cmp r1, #0 @ is second operand zero? 4288 beq common_errDivideByZero 4289 .endif 4290 4291 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4292 and r1, r1, #31 @ optional op; may set condition codes 4293 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 4294 GET_INST_OPCODE(ip) @ extract opcode from rINST 4295 SET_VREG(r0, r9) @ vAA<- r0 4296 GOTO_OPCODE(ip) @ jump to next instruction 4297 /* 11-14 instructions */ 4298 4299 4300 /* ------------------------------ */ 4301 .balign 64 4302 .L_OP_SHR_INT: /* 0x99 */ 4303 /* File: armv5te/OP_SHR_INT.S */ 4304 /* File: armv5te/binop.S */ 4305 /* 4306 * Generic 32-bit binary operation. Provide an "instr" line that 4307 * specifies an instruction that performs "result = r0 op r1". 4308 * This could be an ARM instruction or a function call. (If the result 4309 * comes back in a register other than r0, you can override "result".) 4310 * 4311 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4312 * vCC (r1). Useful for integer division and modulus. Note that we 4313 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4314 * handles it correctly. 4315 * 4316 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4317 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4318 * mul-float, div-float, rem-float 4319 */ 4320 /* binop vAA, vBB, vCC */ 4321 FETCH(r0, 1) @ r0<- CCBB 4322 mov r9, rINST, lsr #8 @ r9<- AA 4323 mov r3, r0, lsr #8 @ r3<- CC 4324 and r2, r0, #255 @ r2<- BB 4325 GET_VREG(r1, r3) @ r1<- vCC 4326 GET_VREG(r0, r2) @ r0<- vBB 4327 .if 0 4328 cmp r1, #0 @ is second operand zero? 4329 beq common_errDivideByZero 4330 .endif 4331 4332 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4333 and r1, r1, #31 @ optional op; may set condition codes 4334 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 4335 GET_INST_OPCODE(ip) @ extract opcode from rINST 4336 SET_VREG(r0, r9) @ vAA<- r0 4337 GOTO_OPCODE(ip) @ jump to next instruction 4338 /* 11-14 instructions */ 4339 4340 4341 /* ------------------------------ */ 4342 .balign 64 4343 .L_OP_USHR_INT: /* 0x9a */ 4344 /* File: armv5te/OP_USHR_INT.S */ 4345 /* File: armv5te/binop.S */ 4346 /* 4347 * Generic 32-bit binary operation. Provide an "instr" line that 4348 * specifies an instruction that performs "result = r0 op r1". 4349 * This could be an ARM instruction or a function call. (If the result 4350 * comes back in a register other than r0, you can override "result".) 4351 * 4352 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4353 * vCC (r1). Useful for integer division and modulus. Note that we 4354 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4355 * handles it correctly. 4356 * 4357 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4358 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4359 * mul-float, div-float, rem-float 4360 */ 4361 /* binop vAA, vBB, vCC */ 4362 FETCH(r0, 1) @ r0<- CCBB 4363 mov r9, rINST, lsr #8 @ r9<- AA 4364 mov r3, r0, lsr #8 @ r3<- CC 4365 and r2, r0, #255 @ r2<- BB 4366 GET_VREG(r1, r3) @ r1<- vCC 4367 GET_VREG(r0, r2) @ r0<- vBB 4368 .if 0 4369 cmp r1, #0 @ is second operand zero? 4370 beq common_errDivideByZero 4371 .endif 4372 4373 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4374 and r1, r1, #31 @ optional op; may set condition codes 4375 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 4376 GET_INST_OPCODE(ip) @ extract opcode from rINST 4377 SET_VREG(r0, r9) @ vAA<- r0 4378 GOTO_OPCODE(ip) @ jump to next instruction 4379 /* 11-14 instructions */ 4380 4381 4382 /* ------------------------------ */ 4383 .balign 64 4384 .L_OP_ADD_LONG: /* 0x9b */ 4385 /* File: armv5te/OP_ADD_LONG.S */ 4386 /* File: armv5te/binopWide.S */ 4387 /* 4388 * Generic 64-bit binary operation. Provide an "instr" line that 4389 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4390 * This could be an ARM instruction or a function call. (If the result 4391 * comes back in a register other than r0, you can override "result".) 4392 * 4393 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4394 * vCC (r1). Useful for integer division and modulus. 4395 * 4396 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4397 * xor-long, add-double, sub-double, mul-double, div-double, 4398 * rem-double 4399 * 4400 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4401 */ 4402 /* binop vAA, vBB, vCC */ 4403 FETCH(r0, 1) @ r0<- CCBB 4404 mov r9, rINST, lsr #8 @ r9<- AA 4405 and r2, r0, #255 @ r2<- BB 4406 mov r3, r0, lsr #8 @ r3<- CC 4407 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4408 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4409 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4410 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4411 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4412 .if 0 4413 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4414 beq common_errDivideByZero 4415 .endif 4416 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4417 4418 adds r0, r0, r2 @ optional op; may set condition codes 4419 adc r1, r1, r3 @ result<- op, r0-r3 changed 4420 GET_INST_OPCODE(ip) @ extract opcode from rINST 4421 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4422 GOTO_OPCODE(ip) @ jump to next instruction 4423 /* 14-17 instructions */ 4424 4425 4426 /* ------------------------------ */ 4427 .balign 64 4428 .L_OP_SUB_LONG: /* 0x9c */ 4429 /* File: armv5te/OP_SUB_LONG.S */ 4430 /* File: armv5te/binopWide.S */ 4431 /* 4432 * Generic 64-bit binary operation. Provide an "instr" line that 4433 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4434 * This could be an ARM instruction or a function call. (If the result 4435 * comes back in a register other than r0, you can override "result".) 4436 * 4437 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4438 * vCC (r1). Useful for integer division and modulus. 4439 * 4440 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4441 * xor-long, add-double, sub-double, mul-double, div-double, 4442 * rem-double 4443 * 4444 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4445 */ 4446 /* binop vAA, vBB, vCC */ 4447 FETCH(r0, 1) @ r0<- CCBB 4448 mov r9, rINST, lsr #8 @ r9<- AA 4449 and r2, r0, #255 @ r2<- BB 4450 mov r3, r0, lsr #8 @ r3<- CC 4451 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4452 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4453 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4454 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4455 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4456 .if 0 4457 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4458 beq common_errDivideByZero 4459 .endif 4460 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4461 4462 subs r0, r0, r2 @ optional op; may set condition codes 4463 sbc r1, r1, r3 @ result<- op, r0-r3 changed 4464 GET_INST_OPCODE(ip) @ extract opcode from rINST 4465 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4466 GOTO_OPCODE(ip) @ jump to next instruction 4467 /* 14-17 instructions */ 4468 4469 4470 /* ------------------------------ */ 4471 .balign 64 4472 .L_OP_MUL_LONG: /* 0x9d */ 4473 /* File: armv5te/OP_MUL_LONG.S */ 4474 /* 4475 * Signed 64-bit integer multiply. 4476 * 4477 * Consider WXxYZ (r1r0 x r3r2) with a long multiply: 4478 * WX 4479 * x YZ 4480 * -------- 4481 * ZW ZX 4482 * YW YX 4483 * 4484 * The low word of the result holds ZX, the high word holds 4485 * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because 4486 * it doesn't fit in the low 64 bits. 4487 * 4488 * Unlike most ARM math operations, multiply instructions have 4489 * restrictions on using the same register more than once (Rd and Rm 4490 * cannot be the same). 4491 */ 4492 /* mul-long vAA, vBB, vCC */ 4493 FETCH(r0, 1) @ r0<- CCBB 4494 and r2, r0, #255 @ r2<- BB 4495 mov r3, r0, lsr #8 @ r3<- CC 4496 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4497 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4498 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4499 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4500 mul ip, r2, r1 @ ip<- ZxW 4501 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 4502 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 4503 mov r0, rINST, lsr #8 @ r0<- AA 4504 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 4505 add r0, rFP, r0, lsl #2 @ r0<- &fp[AA] 4506 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4507 b .LOP_MUL_LONG_finish 4508 4509 /* ------------------------------ */ 4510 .balign 64 4511 .L_OP_DIV_LONG: /* 0x9e */ 4512 /* File: armv5te/OP_DIV_LONG.S */ 4513 /* File: armv5te/binopWide.S */ 4514 /* 4515 * Generic 64-bit binary operation. Provide an "instr" line that 4516 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4517 * This could be an ARM instruction or a function call. (If the result 4518 * comes back in a register other than r0, you can override "result".) 4519 * 4520 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4521 * vCC (r1). Useful for integer division and modulus. 4522 * 4523 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4524 * xor-long, add-double, sub-double, mul-double, div-double, 4525 * rem-double 4526 * 4527 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4528 */ 4529 /* binop vAA, vBB, vCC */ 4530 FETCH(r0, 1) @ r0<- CCBB 4531 mov r9, rINST, lsr #8 @ r9<- AA 4532 and r2, r0, #255 @ r2<- BB 4533 mov r3, r0, lsr #8 @ r3<- CC 4534 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4535 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4536 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4537 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4538 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4539 .if 1 4540 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4541 beq common_errDivideByZero 4542 .endif 4543 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4544 4545 @ optional op; may set condition codes 4546 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4547 GET_INST_OPCODE(ip) @ extract opcode from rINST 4548 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4549 GOTO_OPCODE(ip) @ jump to next instruction 4550 /* 14-17 instructions */ 4551 4552 4553 /* ------------------------------ */ 4554 .balign 64 4555 .L_OP_REM_LONG: /* 0x9f */ 4556 /* File: armv5te/OP_REM_LONG.S */ 4557 /* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 4558 /* File: armv5te/binopWide.S */ 4559 /* 4560 * Generic 64-bit binary operation. Provide an "instr" line that 4561 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4562 * This could be an ARM instruction or a function call. (If the result 4563 * comes back in a register other than r0, you can override "result".) 4564 * 4565 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4566 * vCC (r1). Useful for integer division and modulus. 4567 * 4568 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4569 * xor-long, add-double, sub-double, mul-double, div-double, 4570 * rem-double 4571 * 4572 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4573 */ 4574 /* binop vAA, vBB, vCC */ 4575 FETCH(r0, 1) @ r0<- CCBB 4576 mov r9, rINST, lsr #8 @ r9<- AA 4577 and r2, r0, #255 @ r2<- BB 4578 mov r3, r0, lsr #8 @ r3<- CC 4579 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4580 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4581 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4582 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4583 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4584 .if 1 4585 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4586 beq common_errDivideByZero 4587 .endif 4588 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4589 4590 @ optional op; may set condition codes 4591 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4592 GET_INST_OPCODE(ip) @ extract opcode from rINST 4593 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 4594 GOTO_OPCODE(ip) @ jump to next instruction 4595 /* 14-17 instructions */ 4596 4597 4598 /* ------------------------------ */ 4599 .balign 64 4600 .L_OP_AND_LONG: /* 0xa0 */ 4601 /* File: armv5te/OP_AND_LONG.S */ 4602 /* File: armv5te/binopWide.S */ 4603 /* 4604 * Generic 64-bit binary operation. Provide an "instr" line that 4605 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4606 * This could be an ARM instruction or a function call. (If the result 4607 * comes back in a register other than r0, you can override "result".) 4608 * 4609 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4610 * vCC (r1). Useful for integer division and modulus. 4611 * 4612 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4613 * xor-long, add-double, sub-double, mul-double, div-double, 4614 * rem-double 4615 * 4616 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4617 */ 4618 /* binop vAA, vBB, vCC */ 4619 FETCH(r0, 1) @ r0<- CCBB 4620 mov r9, rINST, lsr #8 @ r9<- AA 4621 and r2, r0, #255 @ r2<- BB 4622 mov r3, r0, lsr #8 @ r3<- CC 4623 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4624 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4625 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4626 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4627 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4628 .if 0 4629 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4630 beq common_errDivideByZero 4631 .endif 4632 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4633 4634 and r0, r0, r2 @ optional op; may set condition codes 4635 and r1, r1, r3 @ result<- op, r0-r3 changed 4636 GET_INST_OPCODE(ip) @ extract opcode from rINST 4637 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4638 GOTO_OPCODE(ip) @ jump to next instruction 4639 /* 14-17 instructions */ 4640 4641 4642 /* ------------------------------ */ 4643 .balign 64 4644 .L_OP_OR_LONG: /* 0xa1 */ 4645 /* File: armv5te/OP_OR_LONG.S */ 4646 /* File: armv5te/binopWide.S */ 4647 /* 4648 * Generic 64-bit binary operation. Provide an "instr" line that 4649 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4650 * This could be an ARM instruction or a function call. (If the result 4651 * comes back in a register other than r0, you can override "result".) 4652 * 4653 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4654 * vCC (r1). Useful for integer division and modulus. 4655 * 4656 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4657 * xor-long, add-double, sub-double, mul-double, div-double, 4658 * rem-double 4659 * 4660 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4661 */ 4662 /* binop vAA, vBB, vCC */ 4663 FETCH(r0, 1) @ r0<- CCBB 4664 mov r9, rINST, lsr #8 @ r9<- AA 4665 and r2, r0, #255 @ r2<- BB 4666 mov r3, r0, lsr #8 @ r3<- CC 4667 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4668 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4669 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4670 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4671 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4672 .if 0 4673 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4674 beq common_errDivideByZero 4675 .endif 4676 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4677 4678 orr r0, r0, r2 @ optional op; may set condition codes 4679 orr r1, r1, r3 @ result<- op, r0-r3 changed 4680 GET_INST_OPCODE(ip) @ extract opcode from rINST 4681 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4682 GOTO_OPCODE(ip) @ jump to next instruction 4683 /* 14-17 instructions */ 4684 4685 4686 /* ------------------------------ */ 4687 .balign 64 4688 .L_OP_XOR_LONG: /* 0xa2 */ 4689 /* File: armv5te/OP_XOR_LONG.S */ 4690 /* File: armv5te/binopWide.S */ 4691 /* 4692 * Generic 64-bit binary operation. Provide an "instr" line that 4693 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4694 * This could be an ARM instruction or a function call. (If the result 4695 * comes back in a register other than r0, you can override "result".) 4696 * 4697 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4698 * vCC (r1). Useful for integer division and modulus. 4699 * 4700 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4701 * xor-long, add-double, sub-double, mul-double, div-double, 4702 * rem-double 4703 * 4704 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4705 */ 4706 /* binop vAA, vBB, vCC */ 4707 FETCH(r0, 1) @ r0<- CCBB 4708 mov r9, rINST, lsr #8 @ r9<- AA 4709 and r2, r0, #255 @ r2<- BB 4710 mov r3, r0, lsr #8 @ r3<- CC 4711 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4712 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4713 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4714 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4715 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4716 .if 0 4717 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4718 beq common_errDivideByZero 4719 .endif 4720 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4721 4722 eor r0, r0, r2 @ optional op; may set condition codes 4723 eor r1, r1, r3 @ result<- op, r0-r3 changed 4724 GET_INST_OPCODE(ip) @ extract opcode from rINST 4725 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4726 GOTO_OPCODE(ip) @ jump to next instruction 4727 /* 14-17 instructions */ 4728 4729 4730 /* ------------------------------ */ 4731 .balign 64 4732 .L_OP_SHL_LONG: /* 0xa3 */ 4733 /* File: armv5te/OP_SHL_LONG.S */ 4734 /* 4735 * Long integer shift. This is different from the generic 32/64-bit 4736 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4737 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4738 * 6 bits of the shift distance. 4739 */ 4740 /* shl-long vAA, vBB, vCC */ 4741 FETCH(r0, 1) @ r0<- CCBB 4742 mov r9, rINST, lsr #8 @ r9<- AA 4743 and r3, r0, #255 @ r3<- BB 4744 mov r0, r0, lsr #8 @ r0<- CC 4745 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4746 GET_VREG(r2, r0) @ r2<- vCC 4747 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4748 and r2, r2, #63 @ r2<- r2 & 0x3f 4749 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4750 4751 mov r1, r1, asl r2 @ r1<- r1 << r2 4752 rsb r3, r2, #32 @ r3<- 32 - r2 4753 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 4754 subs ip, r2, #32 @ ip<- r2 - 32 4755 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 4756 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4757 b .LOP_SHL_LONG_finish 4758 4759 /* ------------------------------ */ 4760 .balign 64 4761 .L_OP_SHR_LONG: /* 0xa4 */ 4762 /* File: armv5te/OP_SHR_LONG.S */ 4763 /* 4764 * Long integer shift. This is different from the generic 32/64-bit 4765 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4766 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4767 * 6 bits of the shift distance. 4768 */ 4769 /* shr-long vAA, vBB, vCC */ 4770 FETCH(r0, 1) @ r0<- CCBB 4771 mov r9, rINST, lsr #8 @ r9<- AA 4772 and r3, r0, #255 @ r3<- BB 4773 mov r0, r0, lsr #8 @ r0<- CC 4774 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4775 GET_VREG(r2, r0) @ r2<- vCC 4776 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4777 and r2, r2, #63 @ r0<- r0 & 0x3f 4778 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4779 4780 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4781 rsb r3, r2, #32 @ r3<- 32 - r2 4782 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4783 subs ip, r2, #32 @ ip<- r2 - 32 4784 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 4785 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4786 b .LOP_SHR_LONG_finish 4787 4788 /* ------------------------------ */ 4789 .balign 64 4790 .L_OP_USHR_LONG: /* 0xa5 */ 4791 /* File: armv5te/OP_USHR_LONG.S */ 4792 /* 4793 * Long integer shift. This is different from the generic 32/64-bit 4794 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4795 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4796 * 6 bits of the shift distance. 4797 */ 4798 /* ushr-long vAA, vBB, vCC */ 4799 FETCH(r0, 1) @ r0<- CCBB 4800 mov r9, rINST, lsr #8 @ r9<- AA 4801 and r3, r0, #255 @ r3<- BB 4802 mov r0, r0, lsr #8 @ r0<- CC 4803 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4804 GET_VREG(r2, r0) @ r2<- vCC 4805 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4806 and r2, r2, #63 @ r0<- r0 & 0x3f 4807 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4808 4809 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4810 rsb r3, r2, #32 @ r3<- 32 - r2 4811 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4812 subs ip, r2, #32 @ ip<- r2 - 32 4813 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 4814 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4815 b .LOP_USHR_LONG_finish 4816 4817 /* ------------------------------ */ 4818 .balign 64 4819 .L_OP_ADD_FLOAT: /* 0xa6 */ 4820 /* File: arm-vfp/OP_ADD_FLOAT.S */ 4821 /* File: arm-vfp/fbinop.S */ 4822 /* 4823 * Generic 32-bit floating-point operation. Provide an "instr" line that 4824 * specifies an instruction that performs "s2 = s0 op s1". Because we 4825 * use the "softfp" ABI, this must be an instruction, not a function call. 4826 * 4827 * For: add-float, sub-float, mul-float, div-float 4828 */ 4829 /* floatop vAA, vBB, vCC */ 4830 FETCH(r0, 1) @ r0<- CCBB 4831 mov r9, rINST, lsr #8 @ r9<- AA 4832 mov r3, r0, lsr #8 @ r3<- CC 4833 and r2, r0, #255 @ r2<- BB 4834 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4835 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4836 flds s1, [r3] @ s1<- vCC 4837 flds s0, [r2] @ s0<- vBB 4838 4839 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4840 fadds s2, s0, s1 @ s2<- op 4841 GET_INST_OPCODE(ip) @ extract opcode from rINST 4842 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4843 fsts s2, [r9] @ vAA<- s2 4844 GOTO_OPCODE(ip) @ jump to next instruction 4845 4846 4847 /* ------------------------------ */ 4848 .balign 64 4849 .L_OP_SUB_FLOAT: /* 0xa7 */ 4850 /* File: arm-vfp/OP_SUB_FLOAT.S */ 4851 /* File: arm-vfp/fbinop.S */ 4852 /* 4853 * Generic 32-bit floating-point operation. Provide an "instr" line that 4854 * specifies an instruction that performs "s2 = s0 op s1". Because we 4855 * use the "softfp" ABI, this must be an instruction, not a function call. 4856 * 4857 * For: add-float, sub-float, mul-float, div-float 4858 */ 4859 /* floatop vAA, vBB, vCC */ 4860 FETCH(r0, 1) @ r0<- CCBB 4861 mov r9, rINST, lsr #8 @ r9<- AA 4862 mov r3, r0, lsr #8 @ r3<- CC 4863 and r2, r0, #255 @ r2<- BB 4864 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4865 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4866 flds s1, [r3] @ s1<- vCC 4867 flds s0, [r2] @ s0<- vBB 4868 4869 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4870 fsubs s2, s0, s1 @ s2<- op 4871 GET_INST_OPCODE(ip) @ extract opcode from rINST 4872 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4873 fsts s2, [r9] @ vAA<- s2 4874 GOTO_OPCODE(ip) @ jump to next instruction 4875 4876 4877 /* ------------------------------ */ 4878 .balign 64 4879 .L_OP_MUL_FLOAT: /* 0xa8 */ 4880 /* File: arm-vfp/OP_MUL_FLOAT.S */ 4881 /* File: arm-vfp/fbinop.S */ 4882 /* 4883 * Generic 32-bit floating-point operation. Provide an "instr" line that 4884 * specifies an instruction that performs "s2 = s0 op s1". Because we 4885 * use the "softfp" ABI, this must be an instruction, not a function call. 4886 * 4887 * For: add-float, sub-float, mul-float, div-float 4888 */ 4889 /* floatop vAA, vBB, vCC */ 4890 FETCH(r0, 1) @ r0<- CCBB 4891 mov r9, rINST, lsr #8 @ r9<- AA 4892 mov r3, r0, lsr #8 @ r3<- CC 4893 and r2, r0, #255 @ r2<- BB 4894 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4895 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4896 flds s1, [r3] @ s1<- vCC 4897 flds s0, [r2] @ s0<- vBB 4898 4899 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4900 fmuls s2, s0, s1 @ s2<- op 4901 GET_INST_OPCODE(ip) @ extract opcode from rINST 4902 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4903 fsts s2, [r9] @ vAA<- s2 4904 GOTO_OPCODE(ip) @ jump to next instruction 4905 4906 4907 /* ------------------------------ */ 4908 .balign 64 4909 .L_OP_DIV_FLOAT: /* 0xa9 */ 4910 /* File: arm-vfp/OP_DIV_FLOAT.S */ 4911 /* File: arm-vfp/fbinop.S */ 4912 /* 4913 * Generic 32-bit floating-point operation. Provide an "instr" line that 4914 * specifies an instruction that performs "s2 = s0 op s1". Because we 4915 * use the "softfp" ABI, this must be an instruction, not a function call. 4916 * 4917 * For: add-float, sub-float, mul-float, div-float 4918 */ 4919 /* floatop vAA, vBB, vCC */ 4920 FETCH(r0, 1) @ r0<- CCBB 4921 mov r9, rINST, lsr #8 @ r9<- AA 4922 mov r3, r0, lsr #8 @ r3<- CC 4923 and r2, r0, #255 @ r2<- BB 4924 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4925 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4926 flds s1, [r3] @ s1<- vCC 4927 flds s0, [r2] @ s0<- vBB 4928 4929 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4930 fdivs s2, s0, s1 @ s2<- op 4931 GET_INST_OPCODE(ip) @ extract opcode from rINST 4932 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4933 fsts s2, [r9] @ vAA<- s2 4934 GOTO_OPCODE(ip) @ jump to next instruction 4935 4936 4937 /* ------------------------------ */ 4938 .balign 64 4939 .L_OP_REM_FLOAT: /* 0xaa */ 4940 /* File: armv5te/OP_REM_FLOAT.S */ 4941 /* EABI doesn't define a float remainder function, but libm does */ 4942 /* File: armv5te/binop.S */ 4943 /* 4944 * Generic 32-bit binary operation. Provide an "instr" line that 4945 * specifies an instruction that performs "result = r0 op r1". 4946 * This could be an ARM instruction or a function call. (If the result 4947 * comes back in a register other than r0, you can override "result".) 4948 * 4949 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4950 * vCC (r1). Useful for integer division and modulus. Note that we 4951 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4952 * handles it correctly. 4953 * 4954 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4955 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4956 * mul-float, div-float, rem-float 4957 */ 4958 /* binop vAA, vBB, vCC */ 4959 FETCH(r0, 1) @ r0<- CCBB 4960 mov r9, rINST, lsr #8 @ r9<- AA 4961 mov r3, r0, lsr #8 @ r3<- CC 4962 and r2, r0, #255 @ r2<- BB 4963 GET_VREG(r1, r3) @ r1<- vCC 4964 GET_VREG(r0, r2) @ r0<- vBB 4965 .if 0 4966 cmp r1, #0 @ is second operand zero? 4967 beq common_errDivideByZero 4968 .endif 4969 4970 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4971 @ optional op; may set condition codes 4972 bl fmodf @ r0<- op, r0-r3 changed 4973 GET_INST_OPCODE(ip) @ extract opcode from rINST 4974 SET_VREG(r0, r9) @ vAA<- r0 4975 GOTO_OPCODE(ip) @ jump to next instruction 4976 /* 11-14 instructions */ 4977 4978 4979 /* ------------------------------ */ 4980 .balign 64 4981 .L_OP_ADD_DOUBLE: /* 0xab */ 4982 /* File: arm-vfp/OP_ADD_DOUBLE.S */ 4983 /* File: arm-vfp/fbinopWide.S */ 4984 /* 4985 * Generic 64-bit double-precision floating point binary operation. 4986 * Provide an "instr" line that specifies an instruction that performs 4987 * "d2 = d0 op d1". 4988 * 4989 * for: add-double, sub-double, mul-double, div-double 4990 */ 4991 /* doubleop vAA, vBB, vCC */ 4992 FETCH(r0, 1) @ r0<- CCBB 4993 mov r9, rINST, lsr #8 @ r9<- AA 4994 mov r3, r0, lsr #8 @ r3<- CC 4995 and r2, r0, #255 @ r2<- BB 4996 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4997 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4998 fldd d1, [r3] @ d1<- vCC 4999 fldd d0, [r2] @ d0<- vBB 5000 5001 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5002 faddd d2, d0, d1 @ s2<- op 5003 GET_INST_OPCODE(ip) @ extract opcode from rINST 5004 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5005 fstd d2, [r9] @ vAA<- d2 5006 GOTO_OPCODE(ip) @ jump to next instruction 5007 5008 5009 /* ------------------------------ */ 5010 .balign 64 5011 .L_OP_SUB_DOUBLE: /* 0xac */ 5012 /* File: arm-vfp/OP_SUB_DOUBLE.S */ 5013 /* File: arm-vfp/fbinopWide.S */ 5014 /* 5015 * Generic 64-bit double-precision floating point binary operation. 5016 * Provide an "instr" line that specifies an instruction that performs 5017 * "d2 = d0 op d1". 5018 * 5019 * for: add-double, sub-double, mul-double, div-double 5020 */ 5021 /* doubleop vAA, vBB, vCC */ 5022 FETCH(r0, 1) @ r0<- CCBB 5023 mov r9, rINST, lsr #8 @ r9<- AA 5024 mov r3, r0, lsr #8 @ r3<- CC 5025 and r2, r0, #255 @ r2<- BB 5026 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5027 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5028 fldd d1, [r3] @ d1<- vCC 5029 fldd d0, [r2] @ d0<- vBB 5030 5031 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5032 fsubd d2, d0, d1 @ s2<- op 5033 GET_INST_OPCODE(ip) @ extract opcode from rINST 5034 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5035 fstd d2, [r9] @ vAA<- d2 5036 GOTO_OPCODE(ip) @ jump to next instruction 5037 5038 5039 /* ------------------------------ */ 5040 .balign 64 5041 .L_OP_MUL_DOUBLE: /* 0xad */ 5042 /* File: arm-vfp/OP_MUL_DOUBLE.S */ 5043 /* File: arm-vfp/fbinopWide.S */ 5044 /* 5045 * Generic 64-bit double-precision floating point binary operation. 5046 * Provide an "instr" line that specifies an instruction that performs 5047 * "d2 = d0 op d1". 5048 * 5049 * for: add-double, sub-double, mul-double, div-double 5050 */ 5051 /* doubleop vAA, vBB, vCC */ 5052 FETCH(r0, 1) @ r0<- CCBB 5053 mov r9, rINST, lsr #8 @ r9<- AA 5054 mov r3, r0, lsr #8 @ r3<- CC 5055 and r2, r0, #255 @ r2<- BB 5056 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5057 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5058 fldd d1, [r3] @ d1<- vCC 5059 fldd d0, [r2] @ d0<- vBB 5060 5061 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5062 fmuld d2, d0, d1 @ s2<- op 5063 GET_INST_OPCODE(ip) @ extract opcode from rINST 5064 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5065 fstd d2, [r9] @ vAA<- d2 5066 GOTO_OPCODE(ip) @ jump to next instruction 5067 5068 5069 /* ------------------------------ */ 5070 .balign 64 5071 .L_OP_DIV_DOUBLE: /* 0xae */ 5072 /* File: arm-vfp/OP_DIV_DOUBLE.S */ 5073 /* File: arm-vfp/fbinopWide.S */ 5074 /* 5075 * Generic 64-bit double-precision floating point binary operation. 5076 * Provide an "instr" line that specifies an instruction that performs 5077 * "d2 = d0 op d1". 5078 * 5079 * for: add-double, sub-double, mul-double, div-double 5080 */ 5081 /* doubleop vAA, vBB, vCC */ 5082 FETCH(r0, 1) @ r0<- CCBB 5083 mov r9, rINST, lsr #8 @ r9<- AA 5084 mov r3, r0, lsr #8 @ r3<- CC 5085 and r2, r0, #255 @ r2<- BB 5086 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5087 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5088 fldd d1, [r3] @ d1<- vCC 5089 fldd d0, [r2] @ d0<- vBB 5090 5091 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5092 fdivd d2, d0, d1 @ s2<- op 5093 GET_INST_OPCODE(ip) @ extract opcode from rINST 5094 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5095 fstd d2, [r9] @ vAA<- d2 5096 GOTO_OPCODE(ip) @ jump to next instruction 5097 5098 5099 /* ------------------------------ */ 5100 .balign 64 5101 .L_OP_REM_DOUBLE: /* 0xaf */ 5102 /* File: armv5te/OP_REM_DOUBLE.S */ 5103 /* EABI doesn't define a double remainder function, but libm does */ 5104 /* File: armv5te/binopWide.S */ 5105 /* 5106 * Generic 64-bit binary operation. Provide an "instr" line that 5107 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5108 * This could be an ARM instruction or a function call. (If the result 5109 * comes back in a register other than r0, you can override "result".) 5110 * 5111 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5112 * vCC (r1). Useful for integer division and modulus. 5113 * 5114 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5115 * xor-long, add-double, sub-double, mul-double, div-double, 5116 * rem-double 5117 * 5118 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5119 */ 5120 /* binop vAA, vBB, vCC */ 5121 FETCH(r0, 1) @ r0<- CCBB 5122 mov r9, rINST, lsr #8 @ r9<- AA 5123 and r2, r0, #255 @ r2<- BB 5124 mov r3, r0, lsr #8 @ r3<- CC 5125 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5126 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5127 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5128 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5129 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5130 .if 0 5131 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5132 beq common_errDivideByZero 5133 .endif 5134 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5135 5136 @ optional op; may set condition codes 5137 bl fmod @ result<- op, r0-r3 changed 5138 GET_INST_OPCODE(ip) @ extract opcode from rINST 5139 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5140 GOTO_OPCODE(ip) @ jump to next instruction 5141 /* 14-17 instructions */ 5142 5143 5144 /* ------------------------------ */ 5145 .balign 64 5146 .L_OP_ADD_INT_2ADDR: /* 0xb0 */ 5147 /* File: armv6t2/OP_ADD_INT_2ADDR.S */ 5148 /* File: armv6t2/binop2addr.S */ 5149 /* 5150 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5151 * that specifies an instruction that performs "result = r0 op r1". 5152 * This could be an ARM instruction or a function call. (If the result 5153 * comes back in a register other than r0, you can override "result".) 5154 * 5155 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5156 * vCC (r1). Useful for integer division and modulus. 5157 * 5158 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5159 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5160 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5161 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5162 */ 5163 /* binop/2addr vA, vB */ 5164 mov r3, rINST, lsr #12 @ r3<- B 5165 ubfx r9, rINST, #8, #4 @ r9<- A 5166 GET_VREG(r1, r3) @ r1<- vB 5167 GET_VREG(r0, r9) @ r0<- vA 5168 .if 0 5169 cmp r1, #0 @ is second operand zero? 5170 beq common_errDivideByZero 5171 .endif 5172 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5173 5174 @ optional op; may set condition codes 5175 add r0, r0, r1 @ r0<- op, r0-r3 changed 5176 GET_INST_OPCODE(ip) @ extract opcode from rINST 5177 SET_VREG(r0, r9) @ vAA<- r0 5178 GOTO_OPCODE(ip) @ jump to next instruction 5179 /* 10-13 instructions */ 5180 5181 5182 /* ------------------------------ */ 5183 .balign 64 5184 .L_OP_SUB_INT_2ADDR: /* 0xb1 */ 5185 /* File: armv6t2/OP_SUB_INT_2ADDR.S */ 5186 /* File: armv6t2/binop2addr.S */ 5187 /* 5188 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5189 * that specifies an instruction that performs "result = r0 op r1". 5190 * This could be an ARM instruction or a function call. (If the result 5191 * comes back in a register other than r0, you can override "result".) 5192 * 5193 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5194 * vCC (r1). Useful for integer division and modulus. 5195 * 5196 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5197 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5198 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5199 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5200 */ 5201 /* binop/2addr vA, vB */ 5202 mov r3, rINST, lsr #12 @ r3<- B 5203 ubfx r9, rINST, #8, #4 @ r9<- A 5204 GET_VREG(r1, r3) @ r1<- vB 5205 GET_VREG(r0, r9) @ r0<- vA 5206 .if 0 5207 cmp r1, #0 @ is second operand zero? 5208 beq common_errDivideByZero 5209 .endif 5210 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5211 5212 @ optional op; may set condition codes 5213 sub r0, r0, r1 @ r0<- op, r0-r3 changed 5214 GET_INST_OPCODE(ip) @ extract opcode from rINST 5215 SET_VREG(r0, r9) @ vAA<- r0 5216 GOTO_OPCODE(ip) @ jump to next instruction 5217 /* 10-13 instructions */ 5218 5219 5220 /* ------------------------------ */ 5221 .balign 64 5222 .L_OP_MUL_INT_2ADDR: /* 0xb2 */ 5223 /* File: armv6t2/OP_MUL_INT_2ADDR.S */ 5224 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 5225 /* File: armv6t2/binop2addr.S */ 5226 /* 5227 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5228 * that specifies an instruction that performs "result = r0 op r1". 5229 * This could be an ARM instruction or a function call. (If the result 5230 * comes back in a register other than r0, you can override "result".) 5231 * 5232 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5233 * vCC (r1). Useful for integer division and modulus. 5234 * 5235 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5236 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5237 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5238 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5239 */ 5240 /* binop/2addr vA, vB */ 5241 mov r3, rINST, lsr #12 @ r3<- B 5242 ubfx r9, rINST, #8, #4 @ r9<- A 5243 GET_VREG(r1, r3) @ r1<- vB 5244 GET_VREG(r0, r9) @ r0<- vA 5245 .if 0 5246 cmp r1, #0 @ is second operand zero? 5247 beq common_errDivideByZero 5248 .endif 5249 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5250 5251 @ optional op; may set condition codes 5252 mul r0, r1, r0 @ r0<- op, r0-r3 changed 5253 GET_INST_OPCODE(ip) @ extract opcode from rINST 5254 SET_VREG(r0, r9) @ vAA<- r0 5255 GOTO_OPCODE(ip) @ jump to next instruction 5256 /* 10-13 instructions */ 5257 5258 5259 /* ------------------------------ */ 5260 .balign 64 5261 .L_OP_DIV_INT_2ADDR: /* 0xb3 */ 5262 /* File: armv6t2/OP_DIV_INT_2ADDR.S */ 5263 /* File: armv6t2/binop2addr.S */ 5264 /* 5265 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5266 * that specifies an instruction that performs "result = r0 op r1". 5267 * This could be an ARM instruction or a function call. (If the result 5268 * comes back in a register other than r0, you can override "result".) 5269 * 5270 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5271 * vCC (r1). Useful for integer division and modulus. 5272 * 5273 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5274 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5275 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5276 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5277 */ 5278 /* binop/2addr vA, vB */ 5279 mov r3, rINST, lsr #12 @ r3<- B 5280 ubfx r9, rINST, #8, #4 @ r9<- A 5281 GET_VREG(r1, r3) @ r1<- vB 5282 GET_VREG(r0, r9) @ r0<- vA 5283 .if 1 5284 cmp r1, #0 @ is second operand zero? 5285 beq common_errDivideByZero 5286 .endif 5287 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5288 5289 @ optional op; may set condition codes 5290 bl __aeabi_idiv @ r0<- op, r0-r3 changed 5291 GET_INST_OPCODE(ip) @ extract opcode from rINST 5292 SET_VREG(r0, r9) @ vAA<- r0 5293 GOTO_OPCODE(ip) @ jump to next instruction 5294 /* 10-13 instructions */ 5295 5296 5297 /* ------------------------------ */ 5298 .balign 64 5299 .L_OP_REM_INT_2ADDR: /* 0xb4 */ 5300 /* File: armv6t2/OP_REM_INT_2ADDR.S */ 5301 /* idivmod returns quotient in r0 and remainder in r1 */ 5302 /* File: armv6t2/binop2addr.S */ 5303 /* 5304 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5305 * that specifies an instruction that performs "result = r0 op r1". 5306 * This could be an ARM instruction or a function call. (If the result 5307 * comes back in a register other than r0, you can override "result".) 5308 * 5309 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5310 * vCC (r1). Useful for integer division and modulus. 5311 * 5312 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5313 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5314 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5315 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5316 */ 5317 /* binop/2addr vA, vB */ 5318 mov r3, rINST, lsr #12 @ r3<- B 5319 ubfx r9, rINST, #8, #4 @ r9<- A 5320 GET_VREG(r1, r3) @ r1<- vB 5321 GET_VREG(r0, r9) @ r0<- vA 5322 .if 1 5323 cmp r1, #0 @ is second operand zero? 5324 beq common_errDivideByZero 5325 .endif 5326 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5327 5328 @ optional op; may set condition codes 5329 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 5330 GET_INST_OPCODE(ip) @ extract opcode from rINST 5331 SET_VREG(r1, r9) @ vAA<- r1 5332 GOTO_OPCODE(ip) @ jump to next instruction 5333 /* 10-13 instructions */ 5334 5335 5336 /* ------------------------------ */ 5337 .balign 64 5338 .L_OP_AND_INT_2ADDR: /* 0xb5 */ 5339 /* File: armv6t2/OP_AND_INT_2ADDR.S */ 5340 /* File: armv6t2/binop2addr.S */ 5341 /* 5342 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5343 * that specifies an instruction that performs "result = r0 op r1". 5344 * This could be an ARM instruction or a function call. (If the result 5345 * comes back in a register other than r0, you can override "result".) 5346 * 5347 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5348 * vCC (r1). Useful for integer division and modulus. 5349 * 5350 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5351 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5352 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5353 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5354 */ 5355 /* binop/2addr vA, vB */ 5356 mov r3, rINST, lsr #12 @ r3<- B 5357 ubfx r9, rINST, #8, #4 @ r9<- A 5358 GET_VREG(r1, r3) @ r1<- vB 5359 GET_VREG(r0, r9) @ r0<- vA 5360 .if 0 5361 cmp r1, #0 @ is second operand zero? 5362 beq common_errDivideByZero 5363 .endif 5364 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5365 5366 @ optional op; may set condition codes 5367 and r0, r0, r1 @ r0<- op, r0-r3 changed 5368 GET_INST_OPCODE(ip) @ extract opcode from rINST 5369 SET_VREG(r0, r9) @ vAA<- r0 5370 GOTO_OPCODE(ip) @ jump to next instruction 5371 /* 10-13 instructions */ 5372 5373 5374 /* ------------------------------ */ 5375 .balign 64 5376 .L_OP_OR_INT_2ADDR: /* 0xb6 */ 5377 /* File: armv6t2/OP_OR_INT_2ADDR.S */ 5378 /* File: armv6t2/binop2addr.S */ 5379 /* 5380 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5381 * that specifies an instruction that performs "result = r0 op r1". 5382 * This could be an ARM instruction or a function call. (If the result 5383 * comes back in a register other than r0, you can override "result".) 5384 * 5385 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5386 * vCC (r1). Useful for integer division and modulus. 5387 * 5388 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5389 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5390 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5391 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5392 */ 5393 /* binop/2addr vA, vB */ 5394 mov r3, rINST, lsr #12 @ r3<- B 5395 ubfx r9, rINST, #8, #4 @ r9<- A 5396 GET_VREG(r1, r3) @ r1<- vB 5397 GET_VREG(r0, r9) @ r0<- vA 5398 .if 0 5399 cmp r1, #0 @ is second operand zero? 5400 beq common_errDivideByZero 5401 .endif 5402 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5403 5404 @ optional op; may set condition codes 5405 orr r0, r0, r1 @ r0<- op, r0-r3 changed 5406 GET_INST_OPCODE(ip) @ extract opcode from rINST 5407 SET_VREG(r0, r9) @ vAA<- r0 5408 GOTO_OPCODE(ip) @ jump to next instruction 5409 /* 10-13 instructions */ 5410 5411 5412 /* ------------------------------ */ 5413 .balign 64 5414 .L_OP_XOR_INT_2ADDR: /* 0xb7 */ 5415 /* File: armv6t2/OP_XOR_INT_2ADDR.S */ 5416 /* File: armv6t2/binop2addr.S */ 5417 /* 5418 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5419 * that specifies an instruction that performs "result = r0 op r1". 5420 * This could be an ARM instruction or a function call. (If the result 5421 * comes back in a register other than r0, you can override "result".) 5422 * 5423 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5424 * vCC (r1). Useful for integer division and modulus. 5425 * 5426 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5427 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5428 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5429 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5430 */ 5431 /* binop/2addr vA, vB */ 5432 mov r3, rINST, lsr #12 @ r3<- B 5433 ubfx r9, rINST, #8, #4 @ r9<- A 5434 GET_VREG(r1, r3) @ r1<- vB 5435 GET_VREG(r0, r9) @ r0<- vA 5436 .if 0 5437 cmp r1, #0 @ is second operand zero? 5438 beq common_errDivideByZero 5439 .endif 5440 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5441 5442 @ optional op; may set condition codes 5443 eor r0, r0, r1 @ r0<- op, r0-r3 changed 5444 GET_INST_OPCODE(ip) @ extract opcode from rINST 5445 SET_VREG(r0, r9) @ vAA<- r0 5446 GOTO_OPCODE(ip) @ jump to next instruction 5447 /* 10-13 instructions */ 5448 5449 5450 /* ------------------------------ */ 5451 .balign 64 5452 .L_OP_SHL_INT_2ADDR: /* 0xb8 */ 5453 /* File: armv6t2/OP_SHL_INT_2ADDR.S */ 5454 /* File: armv6t2/binop2addr.S */ 5455 /* 5456 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5457 * that specifies an instruction that performs "result = r0 op r1". 5458 * This could be an ARM instruction or a function call. (If the result 5459 * comes back in a register other than r0, you can override "result".) 5460 * 5461 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5462 * vCC (r1). Useful for integer division and modulus. 5463 * 5464 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5465 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5466 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5467 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5468 */ 5469 /* binop/2addr vA, vB */ 5470 mov r3, rINST, lsr #12 @ r3<- B 5471 ubfx r9, rINST, #8, #4 @ r9<- A 5472 GET_VREG(r1, r3) @ r1<- vB 5473 GET_VREG(r0, r9) @ r0<- vA 5474 .if 0 5475 cmp r1, #0 @ is second operand zero? 5476 beq common_errDivideByZero 5477 .endif 5478 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5479 5480 and r1, r1, #31 @ optional op; may set condition codes 5481 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 5482 GET_INST_OPCODE(ip) @ extract opcode from rINST 5483 SET_VREG(r0, r9) @ vAA<- r0 5484 GOTO_OPCODE(ip) @ jump to next instruction 5485 /* 10-13 instructions */ 5486 5487 5488 /* ------------------------------ */ 5489 .balign 64 5490 .L_OP_SHR_INT_2ADDR: /* 0xb9 */ 5491 /* File: armv6t2/OP_SHR_INT_2ADDR.S */ 5492 /* File: armv6t2/binop2addr.S */ 5493 /* 5494 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5495 * that specifies an instruction that performs "result = r0 op r1". 5496 * This could be an ARM instruction or a function call. (If the result 5497 * comes back in a register other than r0, you can override "result".) 5498 * 5499 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5500 * vCC (r1). Useful for integer division and modulus. 5501 * 5502 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5503 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5504 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5505 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5506 */ 5507 /* binop/2addr vA, vB */ 5508 mov r3, rINST, lsr #12 @ r3<- B 5509 ubfx r9, rINST, #8, #4 @ r9<- A 5510 GET_VREG(r1, r3) @ r1<- vB 5511 GET_VREG(r0, r9) @ r0<- vA 5512 .if 0 5513 cmp r1, #0 @ is second operand zero? 5514 beq common_errDivideByZero 5515 .endif 5516 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5517 5518 and r1, r1, #31 @ optional op; may set condition codes 5519 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 5520 GET_INST_OPCODE(ip) @ extract opcode from rINST 5521 SET_VREG(r0, r9) @ vAA<- r0 5522 GOTO_OPCODE(ip) @ jump to next instruction 5523 /* 10-13 instructions */ 5524 5525 5526 /* ------------------------------ */ 5527 .balign 64 5528 .L_OP_USHR_INT_2ADDR: /* 0xba */ 5529 /* File: armv6t2/OP_USHR_INT_2ADDR.S */ 5530 /* File: armv6t2/binop2addr.S */ 5531 /* 5532 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5533 * that specifies an instruction that performs "result = r0 op r1". 5534 * This could be an ARM instruction or a function call. (If the result 5535 * comes back in a register other than r0, you can override "result".) 5536 * 5537 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5538 * vCC (r1). Useful for integer division and modulus. 5539 * 5540 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5541 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5542 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5543 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5544 */ 5545 /* binop/2addr vA, vB */ 5546 mov r3, rINST, lsr #12 @ r3<- B 5547 ubfx r9, rINST, #8, #4 @ r9<- A 5548 GET_VREG(r1, r3) @ r1<- vB 5549 GET_VREG(r0, r9) @ r0<- vA 5550 .if 0 5551 cmp r1, #0 @ is second operand zero? 5552 beq common_errDivideByZero 5553 .endif 5554 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5555 5556 and r1, r1, #31 @ optional op; may set condition codes 5557 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 5558 GET_INST_OPCODE(ip) @ extract opcode from rINST 5559 SET_VREG(r0, r9) @ vAA<- r0 5560 GOTO_OPCODE(ip) @ jump to next instruction 5561 /* 10-13 instructions */ 5562 5563 5564 /* ------------------------------ */ 5565 .balign 64 5566 .L_OP_ADD_LONG_2ADDR: /* 0xbb */ 5567 /* File: armv6t2/OP_ADD_LONG_2ADDR.S */ 5568 /* File: armv6t2/binopWide2addr.S */ 5569 /* 5570 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5571 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5572 * This could be an ARM instruction or a function call. (If the result 5573 * comes back in a register other than r0, you can override "result".) 5574 * 5575 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5576 * vCC (r1). Useful for integer division and modulus. 5577 * 5578 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5579 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5580 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5581 * rem-double/2addr 5582 */ 5583 /* binop/2addr vA, vB */ 5584 mov r1, rINST, lsr #12 @ r1<- B 5585 ubfx r9, rINST, #8, #4 @ r9<- A 5586 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5587 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5588 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5589 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5590 .if 0 5591 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5592 beq common_errDivideByZero 5593 .endif 5594 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5595 5596 adds r0, r0, r2 @ optional op; may set condition codes 5597 adc r1, r1, r3 @ result<- op, r0-r3 changed 5598 GET_INST_OPCODE(ip) @ extract opcode from rINST 5599 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5600 GOTO_OPCODE(ip) @ jump to next instruction 5601 /* 12-15 instructions */ 5602 5603 5604 /* ------------------------------ */ 5605 .balign 64 5606 .L_OP_SUB_LONG_2ADDR: /* 0xbc */ 5607 /* File: armv6t2/OP_SUB_LONG_2ADDR.S */ 5608 /* File: armv6t2/binopWide2addr.S */ 5609 /* 5610 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5611 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5612 * This could be an ARM instruction or a function call. (If the result 5613 * comes back in a register other than r0, you can override "result".) 5614 * 5615 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5616 * vCC (r1). Useful for integer division and modulus. 5617 * 5618 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5619 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5620 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5621 * rem-double/2addr 5622 */ 5623 /* binop/2addr vA, vB */ 5624 mov r1, rINST, lsr #12 @ r1<- B 5625 ubfx r9, rINST, #8, #4 @ r9<- A 5626 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5627 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5628 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5629 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5630 .if 0 5631 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5632 beq common_errDivideByZero 5633 .endif 5634 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5635 5636 subs r0, r0, r2 @ optional op; may set condition codes 5637 sbc r1, r1, r3 @ result<- op, r0-r3 changed 5638 GET_INST_OPCODE(ip) @ extract opcode from rINST 5639 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5640 GOTO_OPCODE(ip) @ jump to next instruction 5641 /* 12-15 instructions */ 5642 5643 5644 /* ------------------------------ */ 5645 .balign 64 5646 .L_OP_MUL_LONG_2ADDR: /* 0xbd */ 5647 /* File: armv6t2/OP_MUL_LONG_2ADDR.S */ 5648 /* 5649 * Signed 64-bit integer multiply, "/2addr" version. 5650 * 5651 * See OP_MUL_LONG for an explanation. 5652 * 5653 * We get a little tight on registers, so to avoid looking up &fp[A] 5654 * again we stuff it into rINST. 5655 */ 5656 /* mul-long/2addr vA, vB */ 5657 mov r1, rINST, lsr #12 @ r1<- B 5658 ubfx r9, rINST, #8, #4 @ r9<- A 5659 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5660 add rINST, rFP, r9, lsl #2 @ rINST<- &fp[A] 5661 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5662 ldmia rINST, {r0-r1} @ r0/r1<- vAA/vAA+1 5663 mul ip, r2, r1 @ ip<- ZxW 5664 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 5665 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 5666 mov r0, rINST @ r0<- &fp[A] (free up rINST) 5667 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5668 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 5669 GET_INST_OPCODE(ip) @ extract opcode from rINST 5670 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 5671 GOTO_OPCODE(ip) @ jump to next instruction 5672 5673 /* ------------------------------ */ 5674 .balign 64 5675 .L_OP_DIV_LONG_2ADDR: /* 0xbe */ 5676 /* File: armv6t2/OP_DIV_LONG_2ADDR.S */ 5677 /* File: armv6t2/binopWide2addr.S */ 5678 /* 5679 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5680 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5681 * This could be an ARM instruction or a function call. (If the result 5682 * comes back in a register other than r0, you can override "result".) 5683 * 5684 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5685 * vCC (r1). Useful for integer division and modulus. 5686 * 5687 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5688 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5689 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5690 * rem-double/2addr 5691 */ 5692 /* binop/2addr vA, vB */ 5693 mov r1, rINST, lsr #12 @ r1<- B 5694 ubfx r9, rINST, #8, #4 @ r9<- A 5695 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5696 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5697 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5698 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5699 .if 1 5700 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5701 beq common_errDivideByZero 5702 .endif 5703 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5704 5705 @ optional op; may set condition codes 5706 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5707 GET_INST_OPCODE(ip) @ extract opcode from rINST 5708 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5709 GOTO_OPCODE(ip) @ jump to next instruction 5710 /* 12-15 instructions */ 5711 5712 5713 /* ------------------------------ */ 5714 .balign 64 5715 .L_OP_REM_LONG_2ADDR: /* 0xbf */ 5716 /* File: armv6t2/OP_REM_LONG_2ADDR.S */ 5717 /* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 5718 /* File: armv6t2/binopWide2addr.S */ 5719 /* 5720 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5721 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5722 * This could be an ARM instruction or a function call. (If the result 5723 * comes back in a register other than r0, you can override "result".) 5724 * 5725 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5726 * vCC (r1). Useful for integer division and modulus. 5727 * 5728 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5729 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5730 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5731 * rem-double/2addr 5732 */ 5733 /* binop/2addr vA, vB */ 5734 mov r1, rINST, lsr #12 @ r1<- B 5735 ubfx r9, rINST, #8, #4 @ r9<- A 5736 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5737 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5738 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5739 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5740 .if 1 5741 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5742 beq common_errDivideByZero 5743 .endif 5744 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5745 5746 @ optional op; may set condition codes 5747 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5748 GET_INST_OPCODE(ip) @ extract opcode from rINST 5749 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 5750 GOTO_OPCODE(ip) @ jump to next instruction 5751 /* 12-15 instructions */ 5752 5753 5754 /* ------------------------------ */ 5755 .balign 64 5756 .L_OP_AND_LONG_2ADDR: /* 0xc0 */ 5757 /* File: armv6t2/OP_AND_LONG_2ADDR.S */ 5758 /* File: armv6t2/binopWide2addr.S */ 5759 /* 5760 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5761 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5762 * This could be an ARM instruction or a function call. (If the result 5763 * comes back in a register other than r0, you can override "result".) 5764 * 5765 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5766 * vCC (r1). Useful for integer division and modulus. 5767 * 5768 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5769 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5770 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5771 * rem-double/2addr 5772 */ 5773 /* binop/2addr vA, vB */ 5774 mov r1, rINST, lsr #12 @ r1<- B 5775 ubfx r9, rINST, #8, #4 @ r9<- A 5776 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5777 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5778 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5779 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5780 .if 0 5781 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5782 beq common_errDivideByZero 5783 .endif 5784 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5785 5786 and r0, r0, r2 @ optional op; may set condition codes 5787 and r1, r1, r3 @ result<- op, r0-r3 changed 5788 GET_INST_OPCODE(ip) @ extract opcode from rINST 5789 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5790 GOTO_OPCODE(ip) @ jump to next instruction 5791 /* 12-15 instructions */ 5792 5793 5794 /* ------------------------------ */ 5795 .balign 64 5796 .L_OP_OR_LONG_2ADDR: /* 0xc1 */ 5797 /* File: armv6t2/OP_OR_LONG_2ADDR.S */ 5798 /* File: armv6t2/binopWide2addr.S */ 5799 /* 5800 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5801 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5802 * This could be an ARM instruction or a function call. (If the result 5803 * comes back in a register other than r0, you can override "result".) 5804 * 5805 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5806 * vCC (r1). Useful for integer division and modulus. 5807 * 5808 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5809 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5810 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5811 * rem-double/2addr 5812 */ 5813 /* binop/2addr vA, vB */ 5814 mov r1, rINST, lsr #12 @ r1<- B 5815 ubfx r9, rINST, #8, #4 @ r9<- A 5816 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5817 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5818 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5819 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5820 .if 0 5821 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5822 beq common_errDivideByZero 5823 .endif 5824 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5825 5826 orr r0, r0, r2 @ optional op; may set condition codes 5827 orr r1, r1, r3 @ result<- op, r0-r3 changed 5828 GET_INST_OPCODE(ip) @ extract opcode from rINST 5829 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5830 GOTO_OPCODE(ip) @ jump to next instruction 5831 /* 12-15 instructions */ 5832 5833 5834 /* ------------------------------ */ 5835 .balign 64 5836 .L_OP_XOR_LONG_2ADDR: /* 0xc2 */ 5837 /* File: armv6t2/OP_XOR_LONG_2ADDR.S */ 5838 /* File: armv6t2/binopWide2addr.S */ 5839 /* 5840 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5841 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5842 * This could be an ARM instruction or a function call. (If the result 5843 * comes back in a register other than r0, you can override "result".) 5844 * 5845 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5846 * vCC (r1). Useful for integer division and modulus. 5847 * 5848 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5849 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5850 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5851 * rem-double/2addr 5852 */ 5853 /* binop/2addr vA, vB */ 5854 mov r1, rINST, lsr #12 @ r1<- B 5855 ubfx r9, rINST, #8, #4 @ r9<- A 5856 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5857 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5858 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5859 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5860 .if 0 5861 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5862 beq common_errDivideByZero 5863 .endif 5864 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5865 5866 eor r0, r0, r2 @ optional op; may set condition codes 5867 eor r1, r1, r3 @ result<- op, r0-r3 changed 5868 GET_INST_OPCODE(ip) @ extract opcode from rINST 5869 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5870 GOTO_OPCODE(ip) @ jump to next instruction 5871 /* 12-15 instructions */ 5872 5873 5874 /* ------------------------------ */ 5875 .balign 64 5876 .L_OP_SHL_LONG_2ADDR: /* 0xc3 */ 5877 /* File: armv6t2/OP_SHL_LONG_2ADDR.S */ 5878 /* 5879 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5880 * 32-bit shift distance. 5881 */ 5882 /* shl-long/2addr vA, vB */ 5883 mov r3, rINST, lsr #12 @ r3<- B 5884 ubfx r9, rINST, #8, #4 @ r9<- A 5885 GET_VREG(r2, r3) @ r2<- vB 5886 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5887 and r2, r2, #63 @ r2<- r2 & 0x3f 5888 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5889 5890 mov r1, r1, asl r2 @ r1<- r1 << r2 5891 rsb r3, r2, #32 @ r3<- 32 - r2 5892 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 5893 subs ip, r2, #32 @ ip<- r2 - 32 5894 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5895 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 5896 mov r0, r0, asl r2 @ r0<- r0 << r2 5897 b .LOP_SHL_LONG_2ADDR_finish 5898 5899 /* ------------------------------ */ 5900 .balign 64 5901 .L_OP_SHR_LONG_2ADDR: /* 0xc4 */ 5902 /* File: armv6t2/OP_SHR_LONG_2ADDR.S */ 5903 /* 5904 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5905 * 32-bit shift distance. 5906 */ 5907 /* shr-long/2addr vA, vB */ 5908 mov r3, rINST, lsr #12 @ r3<- B 5909 ubfx r9, rINST, #8, #4 @ r9<- A 5910 GET_VREG(r2, r3) @ r2<- vB 5911 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5912 and r2, r2, #63 @ r2<- r2 & 0x3f 5913 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5914 5915 mov r0, r0, lsr r2 @ r0<- r2 >> r2 5916 rsb r3, r2, #32 @ r3<- 32 - r2 5917 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 5918 subs ip, r2, #32 @ ip<- r2 - 32 5919 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5920 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 5921 mov r1, r1, asr r2 @ r1<- r1 >> r2 5922 b .LOP_SHR_LONG_2ADDR_finish 5923 5924 /* ------------------------------ */ 5925 .balign 64 5926 .L_OP_USHR_LONG_2ADDR: /* 0xc5 */ 5927 /* File: armv6t2/OP_USHR_LONG_2ADDR.S */ 5928 /* 5929 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5930 * 32-bit shift distance. 5931 */ 5932 /* ushr-long/2addr vA, vB */ 5933 mov r3, rINST, lsr #12 @ r3<- B 5934 ubfx r9, rINST, #8, #4 @ r9<- A 5935 GET_VREG(r2, r3) @ r2<- vB 5936 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5937 and r2, r2, #63 @ r2<- r2 & 0x3f 5938 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5939 5940 mov r0, r0, lsr r2 @ r0<- r2 >> r2 5941 rsb r3, r2, #32 @ r3<- 32 - r2 5942 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 5943 subs ip, r2, #32 @ ip<- r2 - 32 5944 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5945 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 5946 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 5947 b .LOP_USHR_LONG_2ADDR_finish 5948 5949 /* ------------------------------ */ 5950 .balign 64 5951 .L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 5952 /* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */ 5953 /* File: arm-vfp/fbinop2addr.S */ 5954 /* 5955 * Generic 32-bit floating point "/2addr" binary operation. Provide 5956 * an "instr" line that specifies an instruction that performs 5957 * "s2 = s0 op s1". 5958 * 5959 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 5960 */ 5961 /* binop/2addr vA, vB */ 5962 mov r3, rINST, lsr #12 @ r3<- B 5963 mov r9, rINST, lsr #8 @ r9<- A+ 5964 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 5965 and r9, r9, #15 @ r9<- A 5966 flds s1, [r3] @ s1<- vB 5967 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 5968 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5969 flds s0, [r9] @ s0<- vA 5970 5971 fadds s2, s0, s1 @ s2<- op 5972 GET_INST_OPCODE(ip) @ extract opcode from rINST 5973 fsts s2, [r9] @ vAA<- s2 5974 GOTO_OPCODE(ip) @ jump to next instruction 5975 5976 5977 /* ------------------------------ */ 5978 .balign 64 5979 .L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 5980 /* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */ 5981 /* File: arm-vfp/fbinop2addr.S */ 5982 /* 5983 * Generic 32-bit floating point "/2addr" binary operation. Provide 5984 * an "instr" line that specifies an instruction that performs 5985 * "s2 = s0 op s1". 5986 * 5987 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 5988 */ 5989 /* binop/2addr vA, vB */ 5990 mov r3, rINST, lsr #12 @ r3<- B 5991 mov r9, rINST, lsr #8 @ r9<- A+ 5992 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 5993 and r9, r9, #15 @ r9<- A 5994 flds s1, [r3] @ s1<- vB 5995 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 5996 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5997 flds s0, [r9] @ s0<- vA 5998 5999 fsubs s2, s0, s1 @ s2<- op 6000 GET_INST_OPCODE(ip) @ extract opcode from rINST 6001 fsts s2, [r9] @ vAA<- s2 6002 GOTO_OPCODE(ip) @ jump to next instruction 6003 6004 6005 /* ------------------------------ */ 6006 .balign 64 6007 .L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 6008 /* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */ 6009 /* File: arm-vfp/fbinop2addr.S */ 6010 /* 6011 * Generic 32-bit floating point "/2addr" binary operation. Provide 6012 * an "instr" line that specifies an instruction that performs 6013 * "s2 = s0 op s1". 6014 * 6015 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6016 */ 6017 /* binop/2addr vA, vB */ 6018 mov r3, rINST, lsr #12 @ r3<- B 6019 mov r9, rINST, lsr #8 @ r9<- A+ 6020 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6021 and r9, r9, #15 @ r9<- A 6022 flds s1, [r3] @ s1<- vB 6023 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6024 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6025 flds s0, [r9] @ s0<- vA 6026 6027 fmuls s2, s0, s1 @ s2<- op 6028 GET_INST_OPCODE(ip) @ extract opcode from rINST 6029 fsts s2, [r9] @ vAA<- s2 6030 GOTO_OPCODE(ip) @ jump to next instruction 6031 6032 6033 /* ------------------------------ */ 6034 .balign 64 6035 .L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 6036 /* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */ 6037 /* File: arm-vfp/fbinop2addr.S */ 6038 /* 6039 * Generic 32-bit floating point "/2addr" binary operation. Provide 6040 * an "instr" line that specifies an instruction that performs 6041 * "s2 = s0 op s1". 6042 * 6043 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6044 */ 6045 /* binop/2addr vA, vB */ 6046 mov r3, rINST, lsr #12 @ r3<- B 6047 mov r9, rINST, lsr #8 @ r9<- A+ 6048 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6049 and r9, r9, #15 @ r9<- A 6050 flds s1, [r3] @ s1<- vB 6051 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6052 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6053 flds s0, [r9] @ s0<- vA 6054 6055 fdivs s2, s0, s1 @ s2<- op 6056 GET_INST_OPCODE(ip) @ extract opcode from rINST 6057 fsts s2, [r9] @ vAA<- s2 6058 GOTO_OPCODE(ip) @ jump to next instruction 6059 6060 6061 /* ------------------------------ */ 6062 .balign 64 6063 .L_OP_REM_FLOAT_2ADDR: /* 0xca */ 6064 /* File: armv6t2/OP_REM_FLOAT_2ADDR.S */ 6065 /* EABI doesn't define a float remainder function, but libm does */ 6066 /* File: armv6t2/binop2addr.S */ 6067 /* 6068 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6069 * that specifies an instruction that performs "result = r0 op r1". 6070 * This could be an ARM instruction or a function call. (If the result 6071 * comes back in a register other than r0, you can override "result".) 6072 * 6073 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6074 * vCC (r1). Useful for integer division and modulus. 6075 * 6076 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6077 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6078 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6079 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6080 */ 6081 /* binop/2addr vA, vB */ 6082 mov r3, rINST, lsr #12 @ r3<- B 6083 ubfx r9, rINST, #8, #4 @ r9<- A 6084 GET_VREG(r1, r3) @ r1<- vB 6085 GET_VREG(r0, r9) @ r0<- vA 6086 .if 0 6087 cmp r1, #0 @ is second operand zero? 6088 beq common_errDivideByZero 6089 .endif 6090 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6091 6092 @ optional op; may set condition codes 6093 bl fmodf @ r0<- op, r0-r3 changed 6094 GET_INST_OPCODE(ip) @ extract opcode from rINST 6095 SET_VREG(r0, r9) @ vAA<- r0 6096 GOTO_OPCODE(ip) @ jump to next instruction 6097 /* 10-13 instructions */ 6098 6099 6100 /* ------------------------------ */ 6101 .balign 64 6102 .L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 6103 /* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */ 6104 /* File: arm-vfp/fbinopWide2addr.S */ 6105 /* 6106 * Generic 64-bit floating point "/2addr" binary operation. Provide 6107 * an "instr" line that specifies an instruction that performs 6108 * "d2 = d0 op d1". 6109 * 6110 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6111 * div-double/2addr 6112 */ 6113 /* binop/2addr vA, vB */ 6114 mov r3, rINST, lsr #12 @ r3<- B 6115 mov r9, rINST, lsr #8 @ r9<- A+ 6116 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6117 and r9, r9, #15 @ r9<- A 6118 fldd d1, [r3] @ d1<- vB 6119 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6120 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6121 fldd d0, [r9] @ d0<- vA 6122 6123 faddd d2, d0, d1 @ d2<- op 6124 GET_INST_OPCODE(ip) @ extract opcode from rINST 6125 fstd d2, [r9] @ vAA<- d2 6126 GOTO_OPCODE(ip) @ jump to next instruction 6127 6128 6129 /* ------------------------------ */ 6130 .balign 64 6131 .L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 6132 /* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */ 6133 /* File: arm-vfp/fbinopWide2addr.S */ 6134 /* 6135 * Generic 64-bit floating point "/2addr" binary operation. Provide 6136 * an "instr" line that specifies an instruction that performs 6137 * "d2 = d0 op d1". 6138 * 6139 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6140 * div-double/2addr 6141 */ 6142 /* binop/2addr vA, vB */ 6143 mov r3, rINST, lsr #12 @ r3<- B 6144 mov r9, rINST, lsr #8 @ r9<- A+ 6145 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6146 and r9, r9, #15 @ r9<- A 6147 fldd d1, [r3] @ d1<- vB 6148 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6149 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6150 fldd d0, [r9] @ d0<- vA 6151 6152 fsubd d2, d0, d1 @ d2<- op 6153 GET_INST_OPCODE(ip) @ extract opcode from rINST 6154 fstd d2, [r9] @ vAA<- d2 6155 GOTO_OPCODE(ip) @ jump to next instruction 6156 6157 6158 /* ------------------------------ */ 6159 .balign 64 6160 .L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 6161 /* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */ 6162 /* File: arm-vfp/fbinopWide2addr.S */ 6163 /* 6164 * Generic 64-bit floating point "/2addr" binary operation. Provide 6165 * an "instr" line that specifies an instruction that performs 6166 * "d2 = d0 op d1". 6167 * 6168 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6169 * div-double/2addr 6170 */ 6171 /* binop/2addr vA, vB */ 6172 mov r3, rINST, lsr #12 @ r3<- B 6173 mov r9, rINST, lsr #8 @ r9<- A+ 6174 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6175 and r9, r9, #15 @ r9<- A 6176 fldd d1, [r3] @ d1<- vB 6177 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6178 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6179 fldd d0, [r9] @ d0<- vA 6180 6181 fmuld d2, d0, d1 @ d2<- op 6182 GET_INST_OPCODE(ip) @ extract opcode from rINST 6183 fstd d2, [r9] @ vAA<- d2 6184 GOTO_OPCODE(ip) @ jump to next instruction 6185 6186 6187 /* ------------------------------ */ 6188 .balign 64 6189 .L_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 6190 /* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */ 6191 /* File: arm-vfp/fbinopWide2addr.S */ 6192 /* 6193 * Generic 64-bit floating point "/2addr" binary operation. Provide 6194 * an "instr" line that specifies an instruction that performs 6195 * "d2 = d0 op d1". 6196 * 6197 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6198 * div-double/2addr 6199 */ 6200 /* binop/2addr vA, vB */ 6201 mov r3, rINST, lsr #12 @ r3<- B 6202 mov r9, rINST, lsr #8 @ r9<- A+ 6203 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6204 and r9, r9, #15 @ r9<- A 6205 fldd d1, [r3] @ d1<- vB 6206 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6207 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6208 fldd d0, [r9] @ d0<- vA 6209 6210 fdivd d2, d0, d1 @ d2<- op 6211 GET_INST_OPCODE(ip) @ extract opcode from rINST 6212 fstd d2, [r9] @ vAA<- d2 6213 GOTO_OPCODE(ip) @ jump to next instruction 6214 6215 6216 /* ------------------------------ */ 6217 .balign 64 6218 .L_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 6219 /* File: armv6t2/OP_REM_DOUBLE_2ADDR.S */ 6220 /* EABI doesn't define a double remainder function, but libm does */ 6221 /* File: armv6t2/binopWide2addr.S */ 6222 /* 6223 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6224 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6225 * This could be an ARM instruction or a function call. (If the result 6226 * comes back in a register other than r0, you can override "result".) 6227 * 6228 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6229 * vCC (r1). Useful for integer division and modulus. 6230 * 6231 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6232 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6233 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6234 * rem-double/2addr 6235 */ 6236 /* binop/2addr vA, vB */ 6237 mov r1, rINST, lsr #12 @ r1<- B 6238 ubfx r9, rINST, #8, #4 @ r9<- A 6239 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6240 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6241 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6242 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6243 .if 0 6244 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6245 beq common_errDivideByZero 6246 .endif 6247 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6248 6249 @ optional op; may set condition codes 6250 bl fmod @ result<- op, r0-r3 changed 6251 GET_INST_OPCODE(ip) @ extract opcode from rINST 6252 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6253 GOTO_OPCODE(ip) @ jump to next instruction 6254 /* 12-15 instructions */ 6255 6256 6257 /* ------------------------------ */ 6258 .balign 64 6259 .L_OP_ADD_INT_LIT16: /* 0xd0 */ 6260 /* File: armv6t2/OP_ADD_INT_LIT16.S */ 6261 /* File: armv6t2/binopLit16.S */ 6262 /* 6263 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6264 * that specifies an instruction that performs "result = r0 op r1". 6265 * This could be an ARM instruction or a function call. (If the result 6266 * comes back in a register other than r0, you can override "result".) 6267 * 6268 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6269 * vCC (r1). Useful for integer division and modulus. 6270 * 6271 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6272 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6273 */ 6274 /* binop/lit16 vA, vB, #+CCCC */ 6275 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6276 mov r2, rINST, lsr #12 @ r2<- B 6277 ubfx r9, rINST, #8, #4 @ r9<- A 6278 GET_VREG(r0, r2) @ r0<- vB 6279 .if 0 6280 cmp r1, #0 @ is second operand zero? 6281 beq common_errDivideByZero 6282 .endif 6283 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6284 6285 add r0, r0, r1 @ r0<- op, r0-r3 changed 6286 GET_INST_OPCODE(ip) @ extract opcode from rINST 6287 SET_VREG(r0, r9) @ vAA<- r0 6288 GOTO_OPCODE(ip) @ jump to next instruction 6289 /* 10-13 instructions */ 6290 6291 6292 /* ------------------------------ */ 6293 .balign 64 6294 .L_OP_RSUB_INT: /* 0xd1 */ 6295 /* File: armv6t2/OP_RSUB_INT.S */ 6296 /* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */ 6297 /* File: armv6t2/binopLit16.S */ 6298 /* 6299 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6300 * that specifies an instruction that performs "result = r0 op r1". 6301 * This could be an ARM instruction or a function call. (If the result 6302 * comes back in a register other than r0, you can override "result".) 6303 * 6304 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6305 * vCC (r1). Useful for integer division and modulus. 6306 * 6307 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6308 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6309 */ 6310 /* binop/lit16 vA, vB, #+CCCC */ 6311 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6312 mov r2, rINST, lsr #12 @ r2<- B 6313 ubfx r9, rINST, #8, #4 @ r9<- A 6314 GET_VREG(r0, r2) @ r0<- vB 6315 .if 0 6316 cmp r1, #0 @ is second operand zero? 6317 beq common_errDivideByZero 6318 .endif 6319 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6320 6321 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6322 GET_INST_OPCODE(ip) @ extract opcode from rINST 6323 SET_VREG(r0, r9) @ vAA<- r0 6324 GOTO_OPCODE(ip) @ jump to next instruction 6325 /* 10-13 instructions */ 6326 6327 6328 /* ------------------------------ */ 6329 .balign 64 6330 .L_OP_MUL_INT_LIT16: /* 0xd2 */ 6331 /* File: armv6t2/OP_MUL_INT_LIT16.S */ 6332 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6333 /* File: armv6t2/binopLit16.S */ 6334 /* 6335 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6336 * that specifies an instruction that performs "result = r0 op r1". 6337 * This could be an ARM instruction or a function call. (If the result 6338 * comes back in a register other than r0, you can override "result".) 6339 * 6340 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6341 * vCC (r1). Useful for integer division and modulus. 6342 * 6343 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6344 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6345 */ 6346 /* binop/lit16 vA, vB, #+CCCC */ 6347 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6348 mov r2, rINST, lsr #12 @ r2<- B 6349 ubfx r9, rINST, #8, #4 @ r9<- A 6350 GET_VREG(r0, r2) @ r0<- vB 6351 .if 0 6352 cmp r1, #0 @ is second operand zero? 6353 beq common_errDivideByZero 6354 .endif 6355 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6356 6357 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6358 GET_INST_OPCODE(ip) @ extract opcode from rINST 6359 SET_VREG(r0, r9) @ vAA<- r0 6360 GOTO_OPCODE(ip) @ jump to next instruction 6361 /* 10-13 instructions */ 6362 6363 6364 /* ------------------------------ */ 6365 .balign 64 6366 .L_OP_DIV_INT_LIT16: /* 0xd3 */ 6367 /* File: armv6t2/OP_DIV_INT_LIT16.S */ 6368 /* File: armv6t2/binopLit16.S */ 6369 /* 6370 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6371 * that specifies an instruction that performs "result = r0 op r1". 6372 * This could be an ARM instruction or a function call. (If the result 6373 * comes back in a register other than r0, you can override "result".) 6374 * 6375 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6376 * vCC (r1). Useful for integer division and modulus. 6377 * 6378 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6379 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6380 */ 6381 /* binop/lit16 vA, vB, #+CCCC */ 6382 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6383 mov r2, rINST, lsr #12 @ r2<- B 6384 ubfx r9, rINST, #8, #4 @ r9<- A 6385 GET_VREG(r0, r2) @ r0<- vB 6386 .if 1 6387 cmp r1, #0 @ is second operand zero? 6388 beq common_errDivideByZero 6389 .endif 6390 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6391 6392 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6393 GET_INST_OPCODE(ip) @ extract opcode from rINST 6394 SET_VREG(r0, r9) @ vAA<- r0 6395 GOTO_OPCODE(ip) @ jump to next instruction 6396 /* 10-13 instructions */ 6397 6398 6399 /* ------------------------------ */ 6400 .balign 64 6401 .L_OP_REM_INT_LIT16: /* 0xd4 */ 6402 /* File: armv6t2/OP_REM_INT_LIT16.S */ 6403 /* idivmod returns quotient in r0 and remainder in r1 */ 6404 /* File: armv6t2/binopLit16.S */ 6405 /* 6406 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6407 * that specifies an instruction that performs "result = r0 op r1". 6408 * This could be an ARM instruction or a function call. (If the result 6409 * comes back in a register other than r0, you can override "result".) 6410 * 6411 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6412 * vCC (r1). Useful for integer division and modulus. 6413 * 6414 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6415 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6416 */ 6417 /* binop/lit16 vA, vB, #+CCCC */ 6418 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6419 mov r2, rINST, lsr #12 @ r2<- B 6420 ubfx r9, rINST, #8, #4 @ r9<- A 6421 GET_VREG(r0, r2) @ r0<- vB 6422 .if 1 6423 cmp r1, #0 @ is second operand zero? 6424 beq common_errDivideByZero 6425 .endif 6426 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6427 6428 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6429 GET_INST_OPCODE(ip) @ extract opcode from rINST 6430 SET_VREG(r1, r9) @ vAA<- r1 6431 GOTO_OPCODE(ip) @ jump to next instruction 6432 /* 10-13 instructions */ 6433 6434 6435 /* ------------------------------ */ 6436 .balign 64 6437 .L_OP_AND_INT_LIT16: /* 0xd5 */ 6438 /* File: armv6t2/OP_AND_INT_LIT16.S */ 6439 /* File: armv6t2/binopLit16.S */ 6440 /* 6441 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6442 * that specifies an instruction that performs "result = r0 op r1". 6443 * This could be an ARM instruction or a function call. (If the result 6444 * comes back in a register other than r0, you can override "result".) 6445 * 6446 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6447 * vCC (r1). Useful for integer division and modulus. 6448 * 6449 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6450 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6451 */ 6452 /* binop/lit16 vA, vB, #+CCCC */ 6453 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6454 mov r2, rINST, lsr #12 @ r2<- B 6455 ubfx r9, rINST, #8, #4 @ r9<- A 6456 GET_VREG(r0, r2) @ r0<- vB 6457 .if 0 6458 cmp r1, #0 @ is second operand zero? 6459 beq common_errDivideByZero 6460 .endif 6461 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6462 6463 and r0, r0, r1 @ r0<- op, r0-r3 changed 6464 GET_INST_OPCODE(ip) @ extract opcode from rINST 6465 SET_VREG(r0, r9) @ vAA<- r0 6466 GOTO_OPCODE(ip) @ jump to next instruction 6467 /* 10-13 instructions */ 6468 6469 6470 /* ------------------------------ */ 6471 .balign 64 6472 .L_OP_OR_INT_LIT16: /* 0xd6 */ 6473 /* File: armv6t2/OP_OR_INT_LIT16.S */ 6474 /* File: armv6t2/binopLit16.S */ 6475 /* 6476 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6477 * that specifies an instruction that performs "result = r0 op r1". 6478 * This could be an ARM instruction or a function call. (If the result 6479 * comes back in a register other than r0, you can override "result".) 6480 * 6481 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6482 * vCC (r1). Useful for integer division and modulus. 6483 * 6484 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6485 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6486 */ 6487 /* binop/lit16 vA, vB, #+CCCC */ 6488 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6489 mov r2, rINST, lsr #12 @ r2<- B 6490 ubfx r9, rINST, #8, #4 @ r9<- A 6491 GET_VREG(r0, r2) @ r0<- vB 6492 .if 0 6493 cmp r1, #0 @ is second operand zero? 6494 beq common_errDivideByZero 6495 .endif 6496 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6497 6498 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6499 GET_INST_OPCODE(ip) @ extract opcode from rINST 6500 SET_VREG(r0, r9) @ vAA<- r0 6501 GOTO_OPCODE(ip) @ jump to next instruction 6502 /* 10-13 instructions */ 6503 6504 6505 /* ------------------------------ */ 6506 .balign 64 6507 .L_OP_XOR_INT_LIT16: /* 0xd7 */ 6508 /* File: armv6t2/OP_XOR_INT_LIT16.S */ 6509 /* File: armv6t2/binopLit16.S */ 6510 /* 6511 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6512 * that specifies an instruction that performs "result = r0 op r1". 6513 * This could be an ARM instruction or a function call. (If the result 6514 * comes back in a register other than r0, you can override "result".) 6515 * 6516 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6517 * vCC (r1). Useful for integer division and modulus. 6518 * 6519 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6520 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6521 */ 6522 /* binop/lit16 vA, vB, #+CCCC */ 6523 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6524 mov r2, rINST, lsr #12 @ r2<- B 6525 ubfx r9, rINST, #8, #4 @ r9<- A 6526 GET_VREG(r0, r2) @ r0<- vB 6527 .if 0 6528 cmp r1, #0 @ is second operand zero? 6529 beq common_errDivideByZero 6530 .endif 6531 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6532 6533 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6534 GET_INST_OPCODE(ip) @ extract opcode from rINST 6535 SET_VREG(r0, r9) @ vAA<- r0 6536 GOTO_OPCODE(ip) @ jump to next instruction 6537 /* 10-13 instructions */ 6538 6539 6540 /* ------------------------------ */ 6541 .balign 64 6542 .L_OP_ADD_INT_LIT8: /* 0xd8 */ 6543 /* File: armv5te/OP_ADD_INT_LIT8.S */ 6544 /* File: armv5te/binopLit8.S */ 6545 /* 6546 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6547 * that specifies an instruction that performs "result = r0 op r1". 6548 * This could be an ARM instruction or a function call. (If the result 6549 * comes back in a register other than r0, you can override "result".) 6550 * 6551 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6552 * vCC (r1). Useful for integer division and modulus. 6553 * 6554 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6555 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6556 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6557 */ 6558 /* binop/lit8 vAA, vBB, #+CC */ 6559 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6560 mov r9, rINST, lsr #8 @ r9<- AA 6561 and r2, r3, #255 @ r2<- BB 6562 GET_VREG(r0, r2) @ r0<- vBB 6563 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6564 .if 0 6565 @cmp r1, #0 @ is second operand zero? 6566 beq common_errDivideByZero 6567 .endif 6568 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6569 6570 @ optional op; may set condition codes 6571 add r0, r0, r1 @ r0<- op, r0-r3 changed 6572 GET_INST_OPCODE(ip) @ extract opcode from rINST 6573 SET_VREG(r0, r9) @ vAA<- r0 6574 GOTO_OPCODE(ip) @ jump to next instruction 6575 /* 10-12 instructions */ 6576 6577 6578 /* ------------------------------ */ 6579 .balign 64 6580 .L_OP_RSUB_INT_LIT8: /* 0xd9 */ 6581 /* File: armv5te/OP_RSUB_INT_LIT8.S */ 6582 /* File: armv5te/binopLit8.S */ 6583 /* 6584 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6585 * that specifies an instruction that performs "result = r0 op r1". 6586 * This could be an ARM instruction or a function call. (If the result 6587 * comes back in a register other than r0, you can override "result".) 6588 * 6589 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6590 * vCC (r1). Useful for integer division and modulus. 6591 * 6592 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6593 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6594 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6595 */ 6596 /* binop/lit8 vAA, vBB, #+CC */ 6597 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6598 mov r9, rINST, lsr #8 @ r9<- AA 6599 and r2, r3, #255 @ r2<- BB 6600 GET_VREG(r0, r2) @ r0<- vBB 6601 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6602 .if 0 6603 @cmp r1, #0 @ is second operand zero? 6604 beq common_errDivideByZero 6605 .endif 6606 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6607 6608 @ optional op; may set condition codes 6609 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6610 GET_INST_OPCODE(ip) @ extract opcode from rINST 6611 SET_VREG(r0, r9) @ vAA<- r0 6612 GOTO_OPCODE(ip) @ jump to next instruction 6613 /* 10-12 instructions */ 6614 6615 6616 /* ------------------------------ */ 6617 .balign 64 6618 .L_OP_MUL_INT_LIT8: /* 0xda */ 6619 /* File: armv5te/OP_MUL_INT_LIT8.S */ 6620 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6621 /* File: armv5te/binopLit8.S */ 6622 /* 6623 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6624 * that specifies an instruction that performs "result = r0 op r1". 6625 * This could be an ARM instruction or a function call. (If the result 6626 * comes back in a register other than r0, you can override "result".) 6627 * 6628 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6629 * vCC (r1). Useful for integer division and modulus. 6630 * 6631 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6632 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6633 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6634 */ 6635 /* binop/lit8 vAA, vBB, #+CC */ 6636 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6637 mov r9, rINST, lsr #8 @ r9<- AA 6638 and r2, r3, #255 @ r2<- BB 6639 GET_VREG(r0, r2) @ r0<- vBB 6640 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6641 .if 0 6642 @cmp r1, #0 @ is second operand zero? 6643 beq common_errDivideByZero 6644 .endif 6645 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6646 6647 @ optional op; may set condition codes 6648 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6649 GET_INST_OPCODE(ip) @ extract opcode from rINST 6650 SET_VREG(r0, r9) @ vAA<- r0 6651 GOTO_OPCODE(ip) @ jump to next instruction 6652 /* 10-12 instructions */ 6653 6654 6655 /* ------------------------------ */ 6656 .balign 64 6657 .L_OP_DIV_INT_LIT8: /* 0xdb */ 6658 /* File: armv5te/OP_DIV_INT_LIT8.S */ 6659 /* File: armv5te/binopLit8.S */ 6660 /* 6661 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6662 * that specifies an instruction that performs "result = r0 op r1". 6663 * This could be an ARM instruction or a function call. (If the result 6664 * comes back in a register other than r0, you can override "result".) 6665 * 6666 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6667 * vCC (r1). Useful for integer division and modulus. 6668 * 6669 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6670 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6671 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6672 */ 6673 /* binop/lit8 vAA, vBB, #+CC */ 6674 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6675 mov r9, rINST, lsr #8 @ r9<- AA 6676 and r2, r3, #255 @ r2<- BB 6677 GET_VREG(r0, r2) @ r0<- vBB 6678 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6679 .if 1 6680 @cmp r1, #0 @ is second operand zero? 6681 beq common_errDivideByZero 6682 .endif 6683 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6684 6685 @ optional op; may set condition codes 6686 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6687 GET_INST_OPCODE(ip) @ extract opcode from rINST 6688 SET_VREG(r0, r9) @ vAA<- r0 6689 GOTO_OPCODE(ip) @ jump to next instruction 6690 /* 10-12 instructions */ 6691 6692 6693 /* ------------------------------ */ 6694 .balign 64 6695 .L_OP_REM_INT_LIT8: /* 0xdc */ 6696 /* File: armv5te/OP_REM_INT_LIT8.S */ 6697 /* idivmod returns quotient in r0 and remainder in r1 */ 6698 /* File: armv5te/binopLit8.S */ 6699 /* 6700 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6701 * that specifies an instruction that performs "result = r0 op r1". 6702 * This could be an ARM instruction or a function call. (If the result 6703 * comes back in a register other than r0, you can override "result".) 6704 * 6705 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6706 * vCC (r1). Useful for integer division and modulus. 6707 * 6708 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6709 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6710 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6711 */ 6712 /* binop/lit8 vAA, vBB, #+CC */ 6713 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6714 mov r9, rINST, lsr #8 @ r9<- AA 6715 and r2, r3, #255 @ r2<- BB 6716 GET_VREG(r0, r2) @ r0<- vBB 6717 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6718 .if 1 6719 @cmp r1, #0 @ is second operand zero? 6720 beq common_errDivideByZero 6721 .endif 6722 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6723 6724 @ optional op; may set condition codes 6725 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6726 GET_INST_OPCODE(ip) @ extract opcode from rINST 6727 SET_VREG(r1, r9) @ vAA<- r1 6728 GOTO_OPCODE(ip) @ jump to next instruction 6729 /* 10-12 instructions */ 6730 6731 6732 /* ------------------------------ */ 6733 .balign 64 6734 .L_OP_AND_INT_LIT8: /* 0xdd */ 6735 /* File: armv5te/OP_AND_INT_LIT8.S */ 6736 /* File: armv5te/binopLit8.S */ 6737 /* 6738 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6739 * that specifies an instruction that performs "result = r0 op r1". 6740 * This could be an ARM instruction or a function call. (If the result 6741 * comes back in a register other than r0, you can override "result".) 6742 * 6743 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6744 * vCC (r1). Useful for integer division and modulus. 6745 * 6746 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6747 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6748 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6749 */ 6750 /* binop/lit8 vAA, vBB, #+CC */ 6751 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6752 mov r9, rINST, lsr #8 @ r9<- AA 6753 and r2, r3, #255 @ r2<- BB 6754 GET_VREG(r0, r2) @ r0<- vBB 6755 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6756 .if 0 6757 @cmp r1, #0 @ is second operand zero? 6758 beq common_errDivideByZero 6759 .endif 6760 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6761 6762 @ optional op; may set condition codes 6763 and r0, r0, r1 @ r0<- op, r0-r3 changed 6764 GET_INST_OPCODE(ip) @ extract opcode from rINST 6765 SET_VREG(r0, r9) @ vAA<- r0 6766 GOTO_OPCODE(ip) @ jump to next instruction 6767 /* 10-12 instructions */ 6768 6769 6770 /* ------------------------------ */ 6771 .balign 64 6772 .L_OP_OR_INT_LIT8: /* 0xde */ 6773 /* File: armv5te/OP_OR_INT_LIT8.S */ 6774 /* File: armv5te/binopLit8.S */ 6775 /* 6776 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6777 * that specifies an instruction that performs "result = r0 op r1". 6778 * This could be an ARM instruction or a function call. (If the result 6779 * comes back in a register other than r0, you can override "result".) 6780 * 6781 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6782 * vCC (r1). Useful for integer division and modulus. 6783 * 6784 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6785 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6786 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6787 */ 6788 /* binop/lit8 vAA, vBB, #+CC */ 6789 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6790 mov r9, rINST, lsr #8 @ r9<- AA 6791 and r2, r3, #255 @ r2<- BB 6792 GET_VREG(r0, r2) @ r0<- vBB 6793 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6794 .if 0 6795 @cmp r1, #0 @ is second operand zero? 6796 beq common_errDivideByZero 6797 .endif 6798 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6799 6800 @ optional op; may set condition codes 6801 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6802 GET_INST_OPCODE(ip) @ extract opcode from rINST 6803 SET_VREG(r0, r9) @ vAA<- r0 6804 GOTO_OPCODE(ip) @ jump to next instruction 6805 /* 10-12 instructions */ 6806 6807 6808 /* ------------------------------ */ 6809 .balign 64 6810 .L_OP_XOR_INT_LIT8: /* 0xdf */ 6811 /* File: armv5te/OP_XOR_INT_LIT8.S */ 6812 /* File: armv5te/binopLit8.S */ 6813 /* 6814 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6815 * that specifies an instruction that performs "result = r0 op r1". 6816 * This could be an ARM instruction or a function call. (If the result 6817 * comes back in a register other than r0, you can override "result".) 6818 * 6819 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6820 * vCC (r1). Useful for integer division and modulus. 6821 * 6822 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6823 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6824 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6825 */ 6826 /* binop/lit8 vAA, vBB, #+CC */ 6827 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6828 mov r9, rINST, lsr #8 @ r9<- AA 6829 and r2, r3, #255 @ r2<- BB 6830 GET_VREG(r0, r2) @ r0<- vBB 6831 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6832 .if 0 6833 @cmp r1, #0 @ is second operand zero? 6834 beq common_errDivideByZero 6835 .endif 6836 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6837 6838 @ optional op; may set condition codes 6839 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6840 GET_INST_OPCODE(ip) @ extract opcode from rINST 6841 SET_VREG(r0, r9) @ vAA<- r0 6842 GOTO_OPCODE(ip) @ jump to next instruction 6843 /* 10-12 instructions */ 6844 6845 6846 /* ------------------------------ */ 6847 .balign 64 6848 .L_OP_SHL_INT_LIT8: /* 0xe0 */ 6849 /* File: armv5te/OP_SHL_INT_LIT8.S */ 6850 /* File: armv5te/binopLit8.S */ 6851 /* 6852 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6853 * that specifies an instruction that performs "result = r0 op r1". 6854 * This could be an ARM instruction or a function call. (If the result 6855 * comes back in a register other than r0, you can override "result".) 6856 * 6857 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6858 * vCC (r1). Useful for integer division and modulus. 6859 * 6860 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6861 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6862 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6863 */ 6864 /* binop/lit8 vAA, vBB, #+CC */ 6865 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6866 mov r9, rINST, lsr #8 @ r9<- AA 6867 and r2, r3, #255 @ r2<- BB 6868 GET_VREG(r0, r2) @ r0<- vBB 6869 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6870 .if 0 6871 @cmp r1, #0 @ is second operand zero? 6872 beq common_errDivideByZero 6873 .endif 6874 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6875 6876 and r1, r1, #31 @ optional op; may set condition codes 6877 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 6878 GET_INST_OPCODE(ip) @ extract opcode from rINST 6879 SET_VREG(r0, r9) @ vAA<- r0 6880 GOTO_OPCODE(ip) @ jump to next instruction 6881 /* 10-12 instructions */ 6882 6883 6884 /* ------------------------------ */ 6885 .balign 64 6886 .L_OP_SHR_INT_LIT8: /* 0xe1 */ 6887 /* File: armv5te/OP_SHR_INT_LIT8.S */ 6888 /* File: armv5te/binopLit8.S */ 6889 /* 6890 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6891 * that specifies an instruction that performs "result = r0 op r1". 6892 * This could be an ARM instruction or a function call. (If the result 6893 * comes back in a register other than r0, you can override "result".) 6894 * 6895 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6896 * vCC (r1). Useful for integer division and modulus. 6897 * 6898 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6899 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6900 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6901 */ 6902 /* binop/lit8 vAA, vBB, #+CC */ 6903 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6904 mov r9, rINST, lsr #8 @ r9<- AA 6905 and r2, r3, #255 @ r2<- BB 6906 GET_VREG(r0, r2) @ r0<- vBB 6907 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6908 .if 0 6909 @cmp r1, #0 @ is second operand zero? 6910 beq common_errDivideByZero 6911 .endif 6912 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6913 6914 and r1, r1, #31 @ optional op; may set condition codes 6915 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 6916 GET_INST_OPCODE(ip) @ extract opcode from rINST 6917 SET_VREG(r0, r9) @ vAA<- r0 6918 GOTO_OPCODE(ip) @ jump to next instruction 6919 /* 10-12 instructions */ 6920 6921 6922 /* ------------------------------ */ 6923 .balign 64 6924 .L_OP_USHR_INT_LIT8: /* 0xe2 */ 6925 /* File: armv5te/OP_USHR_INT_LIT8.S */ 6926 /* File: armv5te/binopLit8.S */ 6927 /* 6928 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6929 * that specifies an instruction that performs "result = r0 op r1". 6930 * This could be an ARM instruction or a function call. (If the result 6931 * comes back in a register other than r0, you can override "result".) 6932 * 6933 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6934 * vCC (r1). Useful for integer division and modulus. 6935 * 6936 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6937 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6938 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6939 */ 6940 /* binop/lit8 vAA, vBB, #+CC */ 6941 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6942 mov r9, rINST, lsr #8 @ r9<- AA 6943 and r2, r3, #255 @ r2<- BB 6944 GET_VREG(r0, r2) @ r0<- vBB 6945 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6946 .if 0 6947 @cmp r1, #0 @ is second operand zero? 6948 beq common_errDivideByZero 6949 .endif 6950 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6951 6952 and r1, r1, #31 @ optional op; may set condition codes 6953 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 6954 GET_INST_OPCODE(ip) @ extract opcode from rINST 6955 SET_VREG(r0, r9) @ vAA<- r0 6956 GOTO_OPCODE(ip) @ jump to next instruction 6957 /* 10-12 instructions */ 6958 6959 6960 /* ------------------------------ */ 6961 .balign 64 6962 .L_OP_IGET_VOLATILE: /* 0xe3 */ 6963 /* File: armv5te/OP_IGET_VOLATILE.S */ 6964 /* File: armv5te/OP_IGET.S */ 6965 /* 6966 * General 32-bit instance field get. 6967 * 6968 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 6969 */ 6970 /* op vA, vB, field@CCCC */ 6971 mov r0, rINST, lsr #12 @ r0<- B 6972 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 6973 FETCH(r1, 1) @ r1<- field ref CCCC 6974 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 6975 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 6976 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 6977 cmp r0, #0 @ is resolved entry null? 6978 bne .LOP_IGET_VOLATILE_finish @ no, already resolved 6979 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 6980 EXPORT_PC() @ resolve() could throw 6981 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 6982 bl dvmResolveInstField @ r0<- resolved InstField ptr 6983 cmp r0, #0 6984 bne .LOP_IGET_VOLATILE_finish 6985 b common_exceptionThrown 6986 6987 6988 /* ------------------------------ */ 6989 .balign 64 6990 .L_OP_IPUT_VOLATILE: /* 0xe4 */ 6991 /* File: armv5te/OP_IPUT_VOLATILE.S */ 6992 /* File: armv5te/OP_IPUT.S */ 6993 /* 6994 * General 32-bit instance field put. 6995 * 6996 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 6997 */ 6998 /* op vA, vB, field@CCCC */ 6999 mov r0, rINST, lsr #12 @ r0<- B 7000 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7001 FETCH(r1, 1) @ r1<- field ref CCCC 7002 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7003 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7004 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7005 cmp r0, #0 @ is resolved entry null? 7006 bne .LOP_IPUT_VOLATILE_finish @ no, already resolved 7007 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7008 EXPORT_PC() @ resolve() could throw 7009 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7010 bl dvmResolveInstField @ r0<- resolved InstField ptr 7011 cmp r0, #0 @ success? 7012 bne .LOP_IPUT_VOLATILE_finish @ yes, finish up 7013 b common_exceptionThrown 7014 7015 7016 /* ------------------------------ */ 7017 .balign 64 7018 .L_OP_SGET_VOLATILE: /* 0xe5 */ 7019 /* File: armv5te/OP_SGET_VOLATILE.S */ 7020 /* File: armv5te/OP_SGET.S */ 7021 /* 7022 * General 32-bit SGET handler. 7023 * 7024 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7025 */ 7026 /* op vAA, field@BBBB */ 7027 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7028 FETCH(r1, 1) @ r1<- field ref BBBB 7029 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7030 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7031 cmp r0, #0 @ is resolved entry null? 7032 beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve 7033 .LOP_SGET_VOLATILE_finish: @ field ptr in r0 7034 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7035 SMP_DMB @ acquiring load 7036 mov r2, rINST, lsr #8 @ r2<- AA 7037 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7038 SET_VREG(r1, r2) @ fp[AA]<- r1 7039 GET_INST_OPCODE(ip) @ extract opcode from rINST 7040 GOTO_OPCODE(ip) @ jump to next instruction 7041 7042 7043 /* ------------------------------ */ 7044 .balign 64 7045 .L_OP_SPUT_VOLATILE: /* 0xe6 */ 7046 /* File: armv5te/OP_SPUT_VOLATILE.S */ 7047 /* File: armv5te/OP_SPUT.S */ 7048 /* 7049 * General 32-bit SPUT handler. 7050 * 7051 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 7052 */ 7053 /* op vAA, field@BBBB */ 7054 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7055 FETCH(r1, 1) @ r1<- field ref BBBB 7056 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7057 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7058 cmp r0, #0 @ is resolved entry null? 7059 beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve 7060 .LOP_SPUT_VOLATILE_finish: @ field ptr in r0 7061 mov r2, rINST, lsr #8 @ r2<- AA 7062 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7063 GET_VREG(r1, r2) @ r1<- fp[AA] 7064 GET_INST_OPCODE(ip) @ extract opcode from rINST 7065 SMP_DMB_ST @ releasing store 7066 str r1, [r0, #offStaticField_value] @ field<- vAA 7067 SMP_DMB 7068 GOTO_OPCODE(ip) @ jump to next instruction 7069 7070 7071 /* ------------------------------ */ 7072 .balign 64 7073 .L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 7074 /* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */ 7075 /* File: armv5te/OP_IGET.S */ 7076 /* 7077 * General 32-bit instance field get. 7078 * 7079 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7080 */ 7081 /* op vA, vB, field@CCCC */ 7082 mov r0, rINST, lsr #12 @ r0<- B 7083 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7084 FETCH(r1, 1) @ r1<- field ref CCCC 7085 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7086 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7087 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7088 cmp r0, #0 @ is resolved entry null? 7089 bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved 7090 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7091 EXPORT_PC() @ resolve() could throw 7092 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7093 bl dvmResolveInstField @ r0<- resolved InstField ptr 7094 cmp r0, #0 7095 bne .LOP_IGET_OBJECT_VOLATILE_finish 7096 b common_exceptionThrown 7097 7098 7099 /* ------------------------------ */ 7100 .balign 64 7101 .L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 7102 /* File: armv5te/OP_IGET_WIDE_VOLATILE.S */ 7103 /* File: armv5te/OP_IGET_WIDE.S */ 7104 /* 7105 * Wide 32-bit instance field get. 7106 */ 7107 /* iget-wide vA, vB, field@CCCC */ 7108 mov r0, rINST, lsr #12 @ r0<- B 7109 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7110 FETCH(r1, 1) @ r1<- field ref CCCC 7111 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7112 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7113 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7114 cmp r0, #0 @ is resolved entry null? 7115 bne .LOP_IGET_WIDE_VOLATILE_finish @ no, already resolved 7116 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7117 EXPORT_PC() @ resolve() could throw 7118 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7119 bl dvmResolveInstField @ r0<- resolved InstField ptr 7120 cmp r0, #0 7121 bne .LOP_IGET_WIDE_VOLATILE_finish 7122 b common_exceptionThrown 7123 7124 7125 /* ------------------------------ */ 7126 .balign 64 7127 .L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 7128 /* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */ 7129 /* File: armv5te/OP_IPUT_WIDE.S */ 7130 /* iput-wide vA, vB, field@CCCC */ 7131 mov r0, rINST, lsr #12 @ r0<- B 7132 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7133 FETCH(r1, 1) @ r1<- field ref CCCC 7134 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7135 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7136 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7137 cmp r0, #0 @ is resolved entry null? 7138 bne .LOP_IPUT_WIDE_VOLATILE_finish @ no, already resolved 7139 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7140 EXPORT_PC() @ resolve() could throw 7141 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7142 bl dvmResolveInstField @ r0<- resolved InstField ptr 7143 cmp r0, #0 @ success? 7144 bne .LOP_IPUT_WIDE_VOLATILE_finish @ yes, finish up 7145 b common_exceptionThrown 7146 7147 7148 /* ------------------------------ */ 7149 .balign 64 7150 .L_OP_SGET_WIDE_VOLATILE: /* 0xea */ 7151 /* File: armv5te/OP_SGET_WIDE_VOLATILE.S */ 7152 /* File: armv5te/OP_SGET_WIDE.S */ 7153 /* 7154 * 64-bit SGET handler. 7155 */ 7156 /* sget-wide vAA, field@BBBB */ 7157 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7158 FETCH(r1, 1) @ r1<- field ref BBBB 7159 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7160 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7161 cmp r0, #0 @ is resolved entry null? 7162 beq .LOP_SGET_WIDE_VOLATILE_resolve @ yes, do resolve 7163 .LOP_SGET_WIDE_VOLATILE_finish: 7164 mov r9, rINST, lsr #8 @ r9<- AA 7165 .if 1 7166 add r0, r0, #offStaticField_value @ r0<- pointer to data 7167 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 7168 .else 7169 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 7170 .endif 7171 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7172 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7173 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 7174 GET_INST_OPCODE(ip) @ extract opcode from rINST 7175 GOTO_OPCODE(ip) @ jump to next instruction 7176 7177 7178 /* ------------------------------ */ 7179 .balign 64 7180 .L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 7181 /* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */ 7182 /* File: armv5te/OP_SPUT_WIDE.S */ 7183 /* 7184 * 64-bit SPUT handler. 7185 */ 7186 /* sput-wide vAA, field@BBBB */ 7187 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- DvmDex 7188 FETCH(r1, 1) @ r1<- field ref BBBB 7189 ldr r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7190 mov r9, rINST, lsr #8 @ r9<- AA 7191 ldr r2, [r10, r1, lsl #2] @ r2<- resolved StaticField ptr 7192 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7193 cmp r2, #0 @ is resolved entry null? 7194 beq .LOP_SPUT_WIDE_VOLATILE_resolve @ yes, do resolve 7195 .LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9 7196 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7197 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 7198 GET_INST_OPCODE(r10) @ extract opcode from rINST 7199 .if 1 7200 add r2, r2, #offStaticField_value @ r2<- pointer to data 7201 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 7202 .else 7203 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 7204 .endif 7205 GOTO_OPCODE(r10) @ jump to next instruction 7206 7207 7208 /* ------------------------------ */ 7209 .balign 64 7210 .L_OP_BREAKPOINT: /* 0xec */ 7211 /* File: armv5te/OP_BREAKPOINT.S */ 7212 /* 7213 * Breakpoint handler. 7214 * 7215 * Restart this instruction with the original opcode. By 7216 * the time we get here, the breakpoint will have already been 7217 * handled. 7218 */ 7219 mov r0, rPC 7220 bl dvmGetOriginalOpcode @ (rPC) 7221 FETCH(rINST, 0) @ reload OP_BREAKPOINT + rest of inst 7222 ldr r1, [rSELF, #offThread_mainHandlerTable] 7223 and rINST, #0xff00 7224 orr rINST, rINST, r0 7225 GOTO_OPCODE_BASE(r1, r0) 7226 7227 /* ------------------------------ */ 7228 .balign 64 7229 .L_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 7230 /* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */ 7231 /* 7232 * Handle a throw-verification-error instruction. This throws an 7233 * exception for an error discovered during verification. The 7234 * exception is indicated by AA, with some detail provided by BBBB. 7235 */ 7236 /* op AA, ref@BBBB */ 7237 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7238 FETCH(r2, 1) @ r2<- BBBB 7239 EXPORT_PC() @ export the PC 7240 mov r1, rINST, lsr #8 @ r1<- AA 7241 bl dvmThrowVerificationError @ always throws 7242 b common_exceptionThrown @ handle exception 7243 7244 /* ------------------------------ */ 7245 .balign 64 7246 .L_OP_EXECUTE_INLINE: /* 0xee */ 7247 /* File: armv5te/OP_EXECUTE_INLINE.S */ 7248 /* 7249 * Execute a "native inline" instruction. 7250 * 7251 * We need to call an InlineOp4Func: 7252 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7253 * 7254 * The first four args are in r0-r3, pointer to return value storage 7255 * is on the stack. The function's return value is a flag that tells 7256 * us if an exception was thrown. 7257 * 7258 * TUNING: could maintain two tables, pointer in Thread and 7259 * swap if profiler/debuggger active. 7260 */ 7261 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 7262 ldrh r2, [rSELF, #offThread_subMode] 7263 FETCH(r10, 1) @ r10<- BBBB 7264 EXPORT_PC() @ can throw 7265 ands r2, #kSubModeDebugProfile @ Any going on? 7266 bne .LOP_EXECUTE_INLINE_debugmode @ yes - take slow path 7267 .LOP_EXECUTE_INLINE_resume: 7268 add r1, rSELF, #offThread_retval @ r1<- &self->retval 7269 sub sp, sp, #8 @ make room for arg, +64 bit align 7270 mov r0, rINST, lsr #12 @ r0<- B 7271 str r1, [sp] @ push &self->retval 7272 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 7273 add sp, sp, #8 @ pop stack 7274 cmp r0, #0 @ test boolean result of inline 7275 beq common_exceptionThrown @ returned false, handle exception 7276 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7277 GET_INST_OPCODE(ip) @ extract opcode from rINST 7278 GOTO_OPCODE(ip) @ jump to next instruction 7279 7280 /* ------------------------------ */ 7281 .balign 64 7282 .L_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 7283 /* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */ 7284 /* 7285 * Execute a "native inline" instruction, using "/range" semantics. 7286 * Same idea as execute-inline, but we get the args differently. 7287 * 7288 * We need to call an InlineOp4Func: 7289 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7290 * 7291 * The first four args are in r0-r3, pointer to return value storage 7292 * is on the stack. The function's return value is a flag that tells 7293 * us if an exception was thrown. 7294 */ 7295 /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */ 7296 ldrh r2, [rSELF, #offThread_subMode] 7297 FETCH(r10, 1) @ r10<- BBBB 7298 EXPORT_PC() @ can throw 7299 ands r2, #kSubModeDebugProfile @ Any going on? 7300 bne .LOP_EXECUTE_INLINE_RANGE_debugmode @ yes - take slow path 7301 .LOP_EXECUTE_INLINE_RANGE_resume: 7302 add r1, rSELF, #offThread_retval @ r1<- &self->retval 7303 sub sp, sp, #8 @ make room for arg, +64 bit align 7304 mov r0, rINST, lsr #8 @ r0<- AA 7305 str r1, [sp] @ push &self->retval 7306 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 7307 add sp, sp, #8 @ pop stack 7308 cmp r0, #0 @ test boolean result of inline 7309 beq common_exceptionThrown @ returned false, handle exception 7310 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7311 GET_INST_OPCODE(ip) @ extract opcode from rINST 7312 GOTO_OPCODE(ip) @ jump to next instruction 7313 7314 /* ------------------------------ */ 7315 .balign 64 7316 .L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */ 7317 /* File: armv5te/OP_INVOKE_OBJECT_INIT_RANGE.S */ 7318 /* 7319 * Invoke Object.<init> on an object. In practice we know that 7320 * Object's nullary constructor doesn't do anything, so we just 7321 * skip it unless a debugger is active. 7322 */ 7323 FETCH(r1, 2) @ r1<- CCCC 7324 GET_VREG(r0, r1) @ r0<- "this" ptr 7325 cmp r0, #0 @ check for NULL 7326 beq common_errNullObject @ export PC and throw NPE 7327 ldr r1, [r0, #offObject_clazz] @ r1<- obj->clazz 7328 ldr r2, [r1, #offClassObject_accessFlags] @ r2<- clazz->accessFlags 7329 tst r2, #CLASS_ISFINALIZABLE @ is this class finalizable? 7330 bne .LOP_INVOKE_OBJECT_INIT_RANGE_setFinal @ yes, go 7331 .LOP_INVOKE_OBJECT_INIT_RANGE_finish: 7332 ldrh r1, [rSELF, #offThread_subMode] 7333 ands r1, #kSubModeDebuggerActive @ debugger active? 7334 bne .LOP_INVOKE_OBJECT_INIT_RANGE_debugger @ Yes - skip optimization 7335 FETCH_ADVANCE_INST(2+1) @ advance to next instr, load rINST 7336 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 7337 GOTO_OPCODE(ip) @ execute it 7338 7339 /* ------------------------------ */ 7340 .balign 64 7341 .L_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 7342 /* File: armv5te/OP_RETURN_VOID_BARRIER.S */ 7343 SMP_DMB_ST 7344 b common_returnFromMethod 7345 7346 /* ------------------------------ */ 7347 .balign 64 7348 .L_OP_IGET_QUICK: /* 0xf2 */ 7349 /* File: armv6t2/OP_IGET_QUICK.S */ 7350 /* For: iget-quick, iget-object-quick */ 7351 /* op vA, vB, offset@CCCC */ 7352 mov r2, rINST, lsr #12 @ r2<- B 7353 FETCH(r1, 1) @ r1<- field byte offset 7354 GET_VREG(r3, r2) @ r3<- object we're operating on 7355 ubfx r2, rINST, #8, #4 @ r2<- A 7356 cmp r3, #0 @ check object for null 7357 beq common_errNullObject @ object was null 7358 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7359 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7360 SET_VREG(r0, r2) @ fp[A]<- r0 7361 GET_INST_OPCODE(ip) @ extract opcode from rINST 7362 GOTO_OPCODE(ip) @ jump to next instruction 7363 7364 /* ------------------------------ */ 7365 .balign 64 7366 .L_OP_IGET_WIDE_QUICK: /* 0xf3 */ 7367 /* File: armv6t2/OP_IGET_WIDE_QUICK.S */ 7368 /* iget-wide-quick vA, vB, offset@CCCC */ 7369 mov r2, rINST, lsr #12 @ r2<- B 7370 FETCH(ip, 1) @ ip<- field byte offset 7371 GET_VREG(r3, r2) @ r3<- object we're operating on 7372 ubfx r2, rINST, #8, #4 @ r2<- A 7373 cmp r3, #0 @ check object for null 7374 beq common_errNullObject @ object was null 7375 ldrd r0, [r3, ip] @ r0<- obj.field (64 bits, aligned) 7376 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7377 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 7378 GET_INST_OPCODE(ip) @ extract opcode from rINST 7379 stmia r3, {r0-r1} @ fp[A]<- r0/r1 7380 GOTO_OPCODE(ip) @ jump to next instruction 7381 7382 /* ------------------------------ */ 7383 .balign 64 7384 .L_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 7385 /* File: armv5te/OP_IGET_OBJECT_QUICK.S */ 7386 /* File: armv5te/OP_IGET_QUICK.S */ 7387 /* For: iget-quick, iget-object-quick */ 7388 /* op vA, vB, offset@CCCC */ 7389 mov r2, rINST, lsr #12 @ r2<- B 7390 GET_VREG(r3, r2) @ r3<- object we're operating on 7391 FETCH(r1, 1) @ r1<- field byte offset 7392 cmp r3, #0 @ check object for null 7393 mov r2, rINST, lsr #8 @ r2<- A(+) 7394 beq common_errNullObject @ object was null 7395 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7396 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7397 and r2, r2, #15 7398 GET_INST_OPCODE(ip) @ extract opcode from rINST 7399 SET_VREG(r0, r2) @ fp[A]<- r0 7400 GOTO_OPCODE(ip) @ jump to next instruction 7401 7402 7403 /* ------------------------------ */ 7404 .balign 64 7405 .L_OP_IPUT_QUICK: /* 0xf5 */ 7406 /* File: armv6t2/OP_IPUT_QUICK.S */ 7407 /* For: iput-quick, iput-object-quick */ 7408 /* op vA, vB, offset@CCCC */ 7409 mov r2, rINST, lsr #12 @ r2<- B 7410 FETCH(r1, 1) @ r1<- field byte offset 7411 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7412 ubfx r2, rINST, #8, #4 @ r2<- A 7413 cmp r3, #0 @ check object for null 7414 beq common_errNullObject @ object was null 7415 GET_VREG(r0, r2) @ r0<- fp[A] 7416 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7417 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7418 GET_INST_OPCODE(ip) @ extract opcode from rINST 7419 GOTO_OPCODE(ip) @ jump to next instruction 7420 7421 /* ------------------------------ */ 7422 .balign 64 7423 .L_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 7424 /* File: armv6t2/OP_IPUT_WIDE_QUICK.S */ 7425 /* iput-wide-quick vA, vB, offset@CCCC */ 7426 mov r1, rINST, lsr #12 @ r1<- B 7427 ubfx r0, rINST, #8, #4 @ r0<- A 7428 GET_VREG(r2, r1) @ r2<- fp[B], the object pointer 7429 add r3, rFP, r0, lsl #2 @ r3<- &fp[A] 7430 cmp r2, #0 @ check object for null 7431 ldmia r3, {r0-r1} @ r0/r1<- fp[A] 7432 beq common_errNullObject @ object was null 7433 FETCH(r3, 1) @ r3<- field byte offset 7434 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7435 strd r0, [r2, r3] @ obj.field (64 bits, aligned)<- r0/r1 7436 GET_INST_OPCODE(ip) @ extract opcode from rINST 7437 GOTO_OPCODE(ip) @ jump to next instruction 7438 7439 /* ------------------------------ */ 7440 .balign 64 7441 .L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 7442 /* File: armv5te/OP_IPUT_OBJECT_QUICK.S */ 7443 /* For: iput-object-quick */ 7444 /* op vA, vB, offset@CCCC */ 7445 mov r2, rINST, lsr #12 @ r2<- B 7446 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7447 FETCH(r1, 1) @ r1<- field byte offset 7448 cmp r3, #0 @ check object for null 7449 mov r2, rINST, lsr #8 @ r2<- A(+) 7450 beq common_errNullObject @ object was null 7451 and r2, r2, #15 7452 GET_VREG(r0, r2) @ r0<- fp[A] 7453 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 7454 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7455 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7456 cmp r0, #0 7457 strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head 7458 GET_INST_OPCODE(ip) @ extract opcode from rINST 7459 GOTO_OPCODE(ip) @ jump to next instruction 7460 7461 /* ------------------------------ */ 7462 .balign 64 7463 .L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 7464 /* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7465 /* 7466 * Handle an optimized virtual method call. 7467 * 7468 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7469 */ 7470 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7471 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7472 FETCH(r3, 2) @ r3<- FEDC or CCCC 7473 FETCH(r1, 1) @ r1<- BBBB 7474 .if (!0) 7475 and r3, r3, #15 @ r3<- C (or stays CCCC) 7476 .endif 7477 GET_VREG(r9, r3) @ r9<- vC ("this" ptr) 7478 cmp r9, #0 @ is "this" null? 7479 beq common_errNullObject @ null "this", throw exception 7480 ldr r2, [r9, #offObject_clazz] @ r2<- thisPtr->clazz 7481 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7482 EXPORT_PC() @ invoke must export 7483 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7484 bl common_invokeMethodNoRange @ (r0=method, r9="this") 7485 7486 /* ------------------------------ */ 7487 .balign 64 7488 .L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 7489 /* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */ 7490 /* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7491 /* 7492 * Handle an optimized virtual method call. 7493 * 7494 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7495 */ 7496 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7497 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7498 FETCH(r3, 2) @ r3<- FEDC or CCCC 7499 FETCH(r1, 1) @ r1<- BBBB 7500 .if (!1) 7501 and r3, r3, #15 @ r3<- C (or stays CCCC) 7502 .endif 7503 GET_VREG(r9, r3) @ r9<- vC ("this" ptr) 7504 cmp r9, #0 @ is "this" null? 7505 beq common_errNullObject @ null "this", throw exception 7506 ldr r2, [r9, #offObject_clazz] @ r2<- thisPtr->clazz 7507 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7508 EXPORT_PC() @ invoke must export 7509 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7510 bl common_invokeMethodRange @ (r0=method, r9="this") 7511 7512 7513 /* ------------------------------ */ 7514 .balign 64 7515 .L_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 7516 /* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7517 /* 7518 * Handle an optimized "super" method call. 7519 * 7520 * for: [opt] invoke-super-quick, invoke-super-quick/range 7521 */ 7522 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7523 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7524 FETCH(r10, 2) @ r10<- GFED or CCCC 7525 ldr r2, [rSELF, #offThread_method] @ r2<- current method 7526 .if (!0) 7527 and r10, r10, #15 @ r10<- D (or stays CCCC) 7528 .endif 7529 FETCH(r1, 1) @ r1<- BBBB 7530 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7531 EXPORT_PC() @ must export for invoke 7532 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7533 GET_VREG(r9, r10) @ r9<- "this" 7534 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7535 cmp r9, #0 @ null "this" ref? 7536 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7537 beq common_errNullObject @ "this" is null, throw exception 7538 bl common_invokeMethodNoRange @ (r0=method, r9="this") 7539 7540 /* ------------------------------ */ 7541 .balign 64 7542 .L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 7543 /* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */ 7544 /* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7545 /* 7546 * Handle an optimized "super" method call. 7547 * 7548 * for: [opt] invoke-super-quick, invoke-super-quick/range 7549 */ 7550 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7551 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7552 FETCH(r10, 2) @ r10<- GFED or CCCC 7553 ldr r2, [rSELF, #offThread_method] @ r2<- current method 7554 .if (!1) 7555 and r10, r10, #15 @ r10<- D (or stays CCCC) 7556 .endif 7557 FETCH(r1, 1) @ r1<- BBBB 7558 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7559 EXPORT_PC() @ must export for invoke 7560 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7561 GET_VREG(r9, r10) @ r9<- "this" 7562 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7563 cmp r9, #0 @ null "this" ref? 7564 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7565 beq common_errNullObject @ "this" is null, throw exception 7566 bl common_invokeMethodRange @ (r0=method, r9="this") 7567 7568 7569 /* ------------------------------ */ 7570 .balign 64 7571 .L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 7572 /* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */ 7573 /* File: armv5te/OP_IPUT_OBJECT.S */ 7574 /* 7575 * 32-bit instance field put. 7576 * 7577 * for: iput-object, iput-object-volatile 7578 */ 7579 /* op vA, vB, field@CCCC */ 7580 mov r0, rINST, lsr #12 @ r0<- B 7581 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7582 FETCH(r1, 1) @ r1<- field ref CCCC 7583 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7584 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7585 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7586 cmp r0, #0 @ is resolved entry null? 7587 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved 7588 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7589 EXPORT_PC() @ resolve() could throw 7590 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7591 bl dvmResolveInstField @ r0<- resolved InstField ptr 7592 cmp r0, #0 @ success? 7593 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up 7594 b common_exceptionThrown 7595 7596 7597 /* ------------------------------ */ 7598 .balign 64 7599 .L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 7600 /* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */ 7601 /* File: armv5te/OP_SGET.S */ 7602 /* 7603 * General 32-bit SGET handler. 7604 * 7605 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7606 */ 7607 /* op vAA, field@BBBB */ 7608 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7609 FETCH(r1, 1) @ r1<- field ref BBBB 7610 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7611 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7612 cmp r0, #0 @ is resolved entry null? 7613 beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve 7614 .LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0 7615 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7616 SMP_DMB @ acquiring load 7617 mov r2, rINST, lsr #8 @ r2<- AA 7618 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7619 SET_VREG(r1, r2) @ fp[AA]<- r1 7620 GET_INST_OPCODE(ip) @ extract opcode from rINST 7621 GOTO_OPCODE(ip) @ jump to next instruction 7622 7623 7624 /* ------------------------------ */ 7625 .balign 64 7626 .L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 7627 /* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */ 7628 /* File: armv5te/OP_SPUT_OBJECT.S */ 7629 /* 7630 * 32-bit SPUT handler for objects 7631 * 7632 * for: sput-object, sput-object-volatile 7633 */ 7634 /* op vAA, field@BBBB */ 7635 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7636 FETCH(r1, 1) @ r1<- field ref BBBB 7637 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7638 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7639 cmp r0, #0 @ is resolved entry null? 7640 beq .LOP_SPUT_OBJECT_VOLATILE_resolve @ yes, do resolve 7641 .LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0 7642 mov r2, rINST, lsr #8 @ r2<- AA 7643 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7644 GET_VREG(r1, r2) @ r1<- fp[AA] 7645 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 7646 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 7647 GET_INST_OPCODE(ip) @ extract opcode from rINST 7648 SMP_DMB_ST @ releasing store 7649 b .LOP_SPUT_OBJECT_VOLATILE_end 7650 7651 7652 /* ------------------------------ */ 7653 .balign 64 7654 .L_OP_UNUSED_FF: /* 0xff */ 7655 /* File: armv5te/OP_UNUSED_FF.S */ 7656 /* File: armv5te/unused.S */ 7657 bl common_abort 7658 7659 7660 .balign 64 7661 .size dvmAsmInstructionStart, .-dvmAsmInstructionStart 7662 .global dvmAsmInstructionEnd 7663 dvmAsmInstructionEnd: 7664 7665 /* 7666 * =========================================================================== 7667 * Sister implementations 7668 * =========================================================================== 7669 */ 7670 .global dvmAsmSisterStart 7671 .type dvmAsmSisterStart, %function 7672 .text 7673 .balign 4 7674 dvmAsmSisterStart: 7675 7676 /* continuation for OP_CONST_STRING */ 7677 7678 /* 7679 * Continuation if the String has not yet been resolved. 7680 * r1: BBBB (String ref) 7681 * r9: target register 7682 */ 7683 .LOP_CONST_STRING_resolve: 7684 EXPORT_PC() 7685 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7686 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7687 bl dvmResolveString @ r0<- String reference 7688 cmp r0, #0 @ failed? 7689 beq common_exceptionThrown @ yup, handle the exception 7690 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7691 SET_VREG(r0, r9) @ vAA<- r0 7692 GET_INST_OPCODE(ip) @ extract opcode from rINST 7693 GOTO_OPCODE(ip) @ jump to next instruction 7694 7695 /* continuation for OP_CONST_STRING_JUMBO */ 7696 7697 /* 7698 * Continuation if the String has not yet been resolved. 7699 * r1: BBBBBBBB (String ref) 7700 * r9: target register 7701 */ 7702 .LOP_CONST_STRING_JUMBO_resolve: 7703 EXPORT_PC() 7704 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7705 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7706 bl dvmResolveString @ r0<- String reference 7707 cmp r0, #0 @ failed? 7708 beq common_exceptionThrown @ yup, handle the exception 7709 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7710 SET_VREG(r0, r9) @ vAA<- r0 7711 GET_INST_OPCODE(ip) @ extract opcode from rINST 7712 GOTO_OPCODE(ip) @ jump to next instruction 7713 7714 /* continuation for OP_CONST_CLASS */ 7715 7716 /* 7717 * Continuation if the Class has not yet been resolved. 7718 * r1: BBBB (Class ref) 7719 * r9: target register 7720 */ 7721 .LOP_CONST_CLASS_resolve: 7722 EXPORT_PC() 7723 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7724 mov r2, #1 @ r2<- true 7725 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7726 bl dvmResolveClass @ r0<- Class reference 7727 cmp r0, #0 @ failed? 7728 beq common_exceptionThrown @ yup, handle the exception 7729 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7730 SET_VREG(r0, r9) @ vAA<- r0 7731 GET_INST_OPCODE(ip) @ extract opcode from rINST 7732 GOTO_OPCODE(ip) @ jump to next instruction 7733 7734 /* continuation for OP_CHECK_CAST */ 7735 7736 /* 7737 * Trivial test failed, need to perform full check. This is common. 7738 * r0 holds obj->clazz 7739 * r1 holds desired class resolved from BBBB 7740 * r9 holds object 7741 */ 7742 .LOP_CHECK_CAST_fullcheck: 7743 mov r10, r1 @ avoid ClassObject getting clobbered 7744 bl dvmInstanceofNonTrivial @ r0<- boolean result 7745 cmp r0, #0 @ failed? 7746 bne .LOP_CHECK_CAST_okay @ no, success 7747 7748 @ A cast has failed. We need to throw a ClassCastException. 7749 EXPORT_PC() @ about to throw 7750 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 7751 mov r1, r10 @ r1<- desired class 7752 bl dvmThrowClassCastException 7753 b common_exceptionThrown 7754 7755 /* 7756 * Resolution required. This is the least-likely path. 7757 * 7758 * r2 holds BBBB 7759 * r9 holds object 7760 */ 7761 .LOP_CHECK_CAST_resolve: 7762 EXPORT_PC() @ resolve() could throw 7763 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 7764 mov r1, r2 @ r1<- BBBB 7765 mov r2, #0 @ r2<- false 7766 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7767 bl dvmResolveClass @ r0<- resolved ClassObject ptr 7768 cmp r0, #0 @ got null? 7769 beq common_exceptionThrown @ yes, handle exception 7770 mov r1, r0 @ r1<- class resolved from BBB 7771 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 7772 b .LOP_CHECK_CAST_resolved @ pick up where we left off 7773 7774 /* continuation for OP_INSTANCE_OF */ 7775 7776 /* 7777 * Trivial test failed, need to perform full check. This is common. 7778 * r0 holds obj->clazz 7779 * r1 holds class resolved from BBBB 7780 * r9 holds A 7781 */ 7782 .LOP_INSTANCE_OF_fullcheck: 7783 bl dvmInstanceofNonTrivial @ r0<- boolean result 7784 @ fall through to OP_INSTANCE_OF_store 7785 7786 /* 7787 * r0 holds boolean result 7788 * r9 holds A 7789 */ 7790 .LOP_INSTANCE_OF_store: 7791 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7792 SET_VREG(r0, r9) @ vA<- r0 7793 GET_INST_OPCODE(ip) @ extract opcode from rINST 7794 GOTO_OPCODE(ip) @ jump to next instruction 7795 7796 /* 7797 * Trivial test succeeded, save and bail. 7798 * r9 holds A 7799 */ 7800 .LOP_INSTANCE_OF_trivial: 7801 mov r0, #1 @ indicate success 7802 @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper 7803 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7804 SET_VREG(r0, r9) @ vA<- r0 7805 GET_INST_OPCODE(ip) @ extract opcode from rINST 7806 GOTO_OPCODE(ip) @ jump to next instruction 7807 7808 /* 7809 * Resolution required. This is the least-likely path. 7810 * 7811 * r3 holds BBBB 7812 * r9 holds A 7813 */ 7814 .LOP_INSTANCE_OF_resolve: 7815 EXPORT_PC() @ resolve() could throw 7816 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7817 mov r1, r3 @ r1<- BBBB 7818 mov r2, #1 @ r2<- true 7819 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7820 bl dvmResolveClass @ r0<- resolved ClassObject ptr 7821 cmp r0, #0 @ got null? 7822 beq common_exceptionThrown @ yes, handle exception 7823 mov r1, r0 @ r1<- class resolved from BBB 7824 mov r3, rINST, lsr #12 @ r3<- B 7825 GET_VREG(r0, r3) @ r0<- vB (object) 7826 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 7827 b .LOP_INSTANCE_OF_resolved @ pick up where we left off 7828 7829 /* continuation for OP_NEW_INSTANCE */ 7830 7831 .balign 32 @ minimize cache lines 7832 .LOP_NEW_INSTANCE_finish: @ r0=new object 7833 mov r3, rINST, lsr #8 @ r3<- AA 7834 cmp r0, #0 @ failed? 7835 #if defined(WITH_JIT) 7836 /* 7837 * The JIT needs the class to be fully resolved before it can 7838 * include this instruction in a trace. 7839 */ 7840 ldrh r1, [rSELF, #offThread_subMode] 7841 beq common_exceptionThrown @ yes, handle the exception 7842 ands r1, #kSubModeJitTraceBuild @ under construction? 7843 bne .LOP_NEW_INSTANCE_jitCheck 7844 #else 7845 beq common_exceptionThrown @ yes, handle the exception 7846 #endif 7847 .LOP_NEW_INSTANCE_end: 7848 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7849 SET_VREG(r0, r3) @ vAA<- r0 7850 GET_INST_OPCODE(ip) @ extract opcode from rINST 7851 GOTO_OPCODE(ip) @ jump to next instruction 7852 7853 #if defined(WITH_JIT) 7854 /* 7855 * Check to see if we need to stop the trace building early. 7856 * r0: new object 7857 * r3: vAA 7858 */ 7859 .LOP_NEW_INSTANCE_jitCheck: 7860 ldr r1, [r10] @ reload resolved class 7861 cmp r1, #0 @ okay? 7862 bne .LOP_NEW_INSTANCE_end @ yes, finish 7863 mov r9, r0 @ preserve new object 7864 mov r10, r3 @ preserve vAA 7865 mov r0, rSELF 7866 mov r1, rPC 7867 bl dvmJitEndTraceSelect @ (self, pc) 7868 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7869 SET_VREG(r9, r10) @ vAA<- new object 7870 GET_INST_OPCODE(ip) @ extract opcode from rINST 7871 GOTO_OPCODE(ip) @ jump to next instruction 7872 #endif 7873 7874 /* 7875 * Class initialization required. 7876 * 7877 * r0 holds class object 7878 */ 7879 .LOP_NEW_INSTANCE_needinit: 7880 mov r9, r0 @ save r0 7881 bl dvmInitClass @ initialize class 7882 cmp r0, #0 @ check boolean result 7883 mov r0, r9 @ restore r0 7884 bne .LOP_NEW_INSTANCE_initialized @ success, continue 7885 b common_exceptionThrown @ failed, deal with init exception 7886 7887 /* 7888 * Resolution required. This is the least-likely path. 7889 * 7890 * r1 holds BBBB 7891 */ 7892 .LOP_NEW_INSTANCE_resolve: 7893 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 7894 mov r2, #0 @ r2<- false 7895 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7896 bl dvmResolveClass @ r0<- resolved ClassObject ptr 7897 cmp r0, #0 @ got null? 7898 bne .LOP_NEW_INSTANCE_resolved @ no, continue 7899 b common_exceptionThrown @ yes, handle exception 7900 7901 /* continuation for OP_NEW_ARRAY */ 7902 7903 7904 /* 7905 * Resolve class. (This is an uncommon case.) 7906 * 7907 * r1 holds array length 7908 * r2 holds class ref CCCC 7909 */ 7910 .LOP_NEW_ARRAY_resolve: 7911 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 7912 mov r9, r1 @ r9<- length (save) 7913 mov r1, r2 @ r1<- CCCC 7914 mov r2, #0 @ r2<- false 7915 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7916 bl dvmResolveClass @ r0<- call(clazz, ref) 7917 cmp r0, #0 @ got null? 7918 mov r1, r9 @ r1<- length (restore) 7919 beq common_exceptionThrown @ yes, handle exception 7920 @ fall through to OP_NEW_ARRAY_finish 7921 7922 /* 7923 * Finish allocation. 7924 * 7925 * r0 holds class 7926 * r1 holds array length 7927 */ 7928 .LOP_NEW_ARRAY_finish: 7929 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 7930 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 7931 cmp r0, #0 @ failed? 7932 mov r2, rINST, lsr #8 @ r2<- A+ 7933 beq common_exceptionThrown @ yes, handle the exception 7934 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7935 and r2, r2, #15 @ r2<- A 7936 GET_INST_OPCODE(ip) @ extract opcode from rINST 7937 SET_VREG(r0, r2) @ vA<- r0 7938 GOTO_OPCODE(ip) @ jump to next instruction 7939 7940 /* continuation for OP_FILLED_NEW_ARRAY */ 7941 7942 /* 7943 * On entry: 7944 * r0 holds array class 7945 * r10 holds AA or BA 7946 */ 7947 .LOP_FILLED_NEW_ARRAY_continue: 7948 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 7949 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 7950 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 7951 .if 0 7952 mov r1, r10 @ r1<- AA (length) 7953 .else 7954 mov r1, r10, lsr #4 @ r1<- B (length) 7955 .endif 7956 cmp rINST, #'I' @ array of ints? 7957 cmpne rINST, #'L' @ array of objects? 7958 cmpne rINST, #'[' @ array of arrays? 7959 mov r9, r1 @ save length in r9 7960 bne .LOP_FILLED_NEW_ARRAY_notimpl @ no, not handled yet 7961 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 7962 cmp r0, #0 @ null return? 7963 beq common_exceptionThrown @ alloc failed, handle exception 7964 7965 FETCH(r1, 2) @ r1<- FEDC or CCCC 7966 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 7967 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 7968 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 7969 subs r9, r9, #1 @ length--, check for neg 7970 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 7971 bmi 2f @ was zero, bail 7972 7973 @ copy values from registers into the array 7974 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 7975 .if 0 7976 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 7977 1: ldr r3, [r2], #4 @ r3<- *r2++ 7978 subs r9, r9, #1 @ count-- 7979 str r3, [r0], #4 @ *contents++ = vX 7980 bpl 1b 7981 @ continue at 2 7982 .else 7983 cmp r9, #4 @ length was initially 5? 7984 and r2, r10, #15 @ r2<- A 7985 bne 1f @ <= 4 args, branch 7986 GET_VREG(r3, r2) @ r3<- vA 7987 sub r9, r9, #1 @ count-- 7988 str r3, [r0, #16] @ contents[4] = vA 7989 1: and r2, r1, #15 @ r2<- F/E/D/C 7990 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 7991 mov r1, r1, lsr #4 @ r1<- next reg in low 4 7992 subs r9, r9, #1 @ count-- 7993 str r3, [r0], #4 @ *contents++ = vX 7994 bpl 1b 7995 @ continue at 2 7996 .endif 7997 7998 2: 7999 ldr r0, [rSELF, #offThread_retval] @ r0<- object 8000 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 8001 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8002 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 8003 cmp r1, #'I' @ Is int array? 8004 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 8005 GOTO_OPCODE(ip) @ execute it 8006 8007 /* 8008 * Throw an exception indicating that we have not implemented this 8009 * mode of filled-new-array. 8010 */ 8011 .LOP_FILLED_NEW_ARRAY_notimpl: 8012 ldr r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY 8013 3: add r0, pc 8014 bl dvmThrowInternalError 8015 b common_exceptionThrown 8016 8017 /* 8018 * Ideally we'd only define this once, but depending on layout we can 8019 * exceed the range of the load above. 8020 */ 8021 8022 .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY: 8023 .word PCREL_REF(.LstrFilledNewArrayNotImpl,3b) 8024 8025 /* continuation for OP_FILLED_NEW_ARRAY_RANGE */ 8026 8027 /* 8028 * On entry: 8029 * r0 holds array class 8030 * r10 holds AA or BA 8031 */ 8032 .LOP_FILLED_NEW_ARRAY_RANGE_continue: 8033 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 8034 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 8035 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 8036 .if 1 8037 mov r1, r10 @ r1<- AA (length) 8038 .else 8039 mov r1, r10, lsr #4 @ r1<- B (length) 8040 .endif 8041 cmp rINST, #'I' @ array of ints? 8042 cmpne rINST, #'L' @ array of objects? 8043 cmpne rINST, #'[' @ array of arrays? 8044 mov r9, r1 @ save length in r9 8045 bne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl @ no, not handled yet 8046 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 8047 cmp r0, #0 @ null return? 8048 beq common_exceptionThrown @ alloc failed, handle exception 8049 8050 FETCH(r1, 2) @ r1<- FEDC or CCCC 8051 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 8052 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 8053 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 8054 subs r9, r9, #1 @ length--, check for neg 8055 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 8056 bmi 2f @ was zero, bail 8057 8058 @ copy values from registers into the array 8059 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 8060 .if 1 8061 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 8062 1: ldr r3, [r2], #4 @ r3<- *r2++ 8063 subs r9, r9, #1 @ count-- 8064 str r3, [r0], #4 @ *contents++ = vX 8065 bpl 1b 8066 @ continue at 2 8067 .else 8068 cmp r9, #4 @ length was initially 5? 8069 and r2, r10, #15 @ r2<- A 8070 bne 1f @ <= 4 args, branch 8071 GET_VREG(r3, r2) @ r3<- vA 8072 sub r9, r9, #1 @ count-- 8073 str r3, [r0, #16] @ contents[4] = vA 8074 1: and r2, r1, #15 @ r2<- F/E/D/C 8075 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 8076 mov r1, r1, lsr #4 @ r1<- next reg in low 4 8077 subs r9, r9, #1 @ count-- 8078 str r3, [r0], #4 @ *contents++ = vX 8079 bpl 1b 8080 @ continue at 2 8081 .endif 8082 8083 2: 8084 ldr r0, [rSELF, #offThread_retval] @ r0<- object 8085 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 8086 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8087 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 8088 cmp r1, #'I' @ Is int array? 8089 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 8090 GOTO_OPCODE(ip) @ execute it 8091 8092 /* 8093 * Throw an exception indicating that we have not implemented this 8094 * mode of filled-new-array. 8095 */ 8096 .LOP_FILLED_NEW_ARRAY_RANGE_notimpl: 8097 ldr r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE 8098 3: add r0, pc 8099 bl dvmThrowInternalError 8100 b common_exceptionThrown 8101 8102 /* 8103 * Ideally we'd only define this once, but depending on layout we can 8104 * exceed the range of the load above. 8105 */ 8106 8107 .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE: 8108 .word PCREL_REF(.LstrFilledNewArrayNotImpl,3b) 8109 8110 /* continuation for OP_CMPL_FLOAT */ 8111 .LOP_CMPL_FLOAT_finish: 8112 SET_VREG(r0, r9) @ vAA<- r0 8113 GOTO_OPCODE(ip) @ jump to next instruction 8114 8115 /* continuation for OP_CMPG_FLOAT */ 8116 .LOP_CMPG_FLOAT_finish: 8117 SET_VREG(r0, r9) @ vAA<- r0 8118 GOTO_OPCODE(ip) @ jump to next instruction 8119 8120 /* continuation for OP_CMPL_DOUBLE */ 8121 .LOP_CMPL_DOUBLE_finish: 8122 SET_VREG(r0, r9) @ vAA<- r0 8123 GOTO_OPCODE(ip) @ jump to next instruction 8124 8125 /* continuation for OP_CMPG_DOUBLE */ 8126 .LOP_CMPG_DOUBLE_finish: 8127 SET_VREG(r0, r9) @ vAA<- r0 8128 GOTO_OPCODE(ip) @ jump to next instruction 8129 8130 /* continuation for OP_CMP_LONG */ 8131 8132 .LOP_CMP_LONG_less: 8133 mvn r1, #0 @ r1<- -1 8134 @ Want to cond code the next mov so we can avoid branch, but don't see it; 8135 @ instead, we just replicate the tail end. 8136 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8137 SET_VREG(r1, r9) @ vAA<- r1 8138 GET_INST_OPCODE(ip) @ extract opcode from rINST 8139 GOTO_OPCODE(ip) @ jump to next instruction 8140 8141 .LOP_CMP_LONG_greater: 8142 mov r1, #1 @ r1<- 1 8143 @ fall through to _finish 8144 8145 .LOP_CMP_LONG_finish: 8146 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8147 SET_VREG(r1, r9) @ vAA<- r1 8148 GET_INST_OPCODE(ip) @ extract opcode from rINST 8149 GOTO_OPCODE(ip) @ jump to next instruction 8150 8151 /* continuation for OP_AGET_WIDE */ 8152 8153 .LOP_AGET_WIDE_finish: 8154 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8155 ldrd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 8156 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 8157 GET_INST_OPCODE(ip) @ extract opcode from rINST 8158 stmia r9, {r2-r3} @ vAA/vAA+1<- r2/r3 8159 GOTO_OPCODE(ip) @ jump to next instruction 8160 8161 /* continuation for OP_APUT_WIDE */ 8162 8163 .LOP_APUT_WIDE_finish: 8164 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8165 ldmia r9, {r2-r3} @ r2/r3<- vAA/vAA+1 8166 GET_INST_OPCODE(ip) @ extract opcode from rINST 8167 strd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 8168 GOTO_OPCODE(ip) @ jump to next instruction 8169 8170 /* continuation for OP_APUT_OBJECT */ 8171 /* 8172 * On entry: 8173 * rINST = vBB (arrayObj) 8174 * r9 = vAA (obj) 8175 * r10 = offset into array (vBB + vCC * width) 8176 */ 8177 .LOP_APUT_OBJECT_finish: 8178 cmp r9, #0 @ storing null reference? 8179 beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks 8180 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 8181 ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz 8182 bl dvmCanPutArrayElement @ test object type vs. array type 8183 cmp r0, #0 @ okay? 8184 beq .LOP_APUT_OBJECT_throw @ no 8185 mov r1, rINST @ r1<- arrayObj 8186 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8187 ldr r2, [rSELF, #offThread_cardTable] @ get biased CT base 8188 add r10, #offArrayObject_contents @ r0<- pointer to slot 8189 GET_INST_OPCODE(ip) @ extract opcode from rINST 8190 str r9, [r10] @ vBB[vCC]<- vAA 8191 strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head 8192 GOTO_OPCODE(ip) @ jump to next instruction 8193 .LOP_APUT_OBJECT_skip_check: 8194 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8195 str r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA 8196 GET_INST_OPCODE(ip) @ extract opcode from rINST 8197 GOTO_OPCODE(ip) @ jump to next instruction 8198 .LOP_APUT_OBJECT_throw: 8199 @ The types don't match. We need to throw an ArrayStoreException. 8200 ldr r0, [r9, #offObject_clazz] 8201 ldr r1, [rINST, #offObject_clazz] 8202 EXPORT_PC() 8203 bl dvmThrowArrayStoreExceptionIncompatibleElement 8204 b common_exceptionThrown 8205 8206 /* continuation for OP_IGET */ 8207 8208 /* 8209 * Currently: 8210 * r0 holds resolved field 8211 * r9 holds object 8212 */ 8213 .LOP_IGET_finish: 8214 @bl common_squeak0 8215 cmp r9, #0 @ check object for null 8216 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8217 beq common_errNullObject @ object was null 8218 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8219 ubfx r2, rINST, #8, #4 @ r2<- A 8220 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8221 SET_VREG(r0, r2) @ fp[A]<- r0 8222 GET_INST_OPCODE(ip) @ extract opcode from rINST 8223 GOTO_OPCODE(ip) @ jump to next instruction 8224 8225 /* continuation for OP_IGET_WIDE */ 8226 8227 /* 8228 * Currently: 8229 * r0 holds resolved field 8230 * r9 holds object 8231 */ 8232 .LOP_IGET_WIDE_finish: 8233 cmp r9, #0 @ check object for null 8234 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8235 beq common_errNullObject @ object was null 8236 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 8237 ubfx r2, rINST, #8, #4 @ r2<- A 8238 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8239 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 8240 GET_INST_OPCODE(ip) @ extract opcode from rINST 8241 stmia r3, {r0-r1} @ fp[A]<- r0/r1 8242 GOTO_OPCODE(ip) @ jump to next instruction 8243 8244 /* continuation for OP_IGET_OBJECT */ 8245 8246 /* 8247 * Currently: 8248 * r0 holds resolved field 8249 * r9 holds object 8250 */ 8251 .LOP_IGET_OBJECT_finish: 8252 @bl common_squeak0 8253 cmp r9, #0 @ check object for null 8254 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8255 beq common_errNullObject @ object was null 8256 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8257 @ no-op @ acquiring load 8258 mov r2, rINST, lsr #8 @ r2<- A+ 8259 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8260 and r2, r2, #15 @ r2<- A 8261 GET_INST_OPCODE(ip) @ extract opcode from rINST 8262 SET_VREG(r0, r2) @ fp[A]<- r0 8263 GOTO_OPCODE(ip) @ jump to next instruction 8264 8265 /* continuation for OP_IGET_BOOLEAN */ 8266 8267 /* 8268 * Currently: 8269 * r0 holds resolved field 8270 * r9 holds object 8271 */ 8272 .LOP_IGET_BOOLEAN_finish: 8273 @bl common_squeak1 8274 cmp r9, #0 @ check object for null 8275 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8276 beq common_errNullObject @ object was null 8277 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8278 @ no-op @ acquiring load 8279 mov r2, rINST, lsr #8 @ r2<- A+ 8280 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8281 and r2, r2, #15 @ r2<- A 8282 GET_INST_OPCODE(ip) @ extract opcode from rINST 8283 SET_VREG(r0, r2) @ fp[A]<- r0 8284 GOTO_OPCODE(ip) @ jump to next instruction 8285 8286 /* continuation for OP_IGET_BYTE */ 8287 8288 /* 8289 * Currently: 8290 * r0 holds resolved field 8291 * r9 holds object 8292 */ 8293 .LOP_IGET_BYTE_finish: 8294 @bl common_squeak2 8295 cmp r9, #0 @ check object for null 8296 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8297 beq common_errNullObject @ object was null 8298 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8299 @ no-op @ acquiring load 8300 mov r2, rINST, lsr #8 @ r2<- A+ 8301 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8302 and r2, r2, #15 @ r2<- A 8303 GET_INST_OPCODE(ip) @ extract opcode from rINST 8304 SET_VREG(r0, r2) @ fp[A]<- r0 8305 GOTO_OPCODE(ip) @ jump to next instruction 8306 8307 /* continuation for OP_IGET_CHAR */ 8308 8309 /* 8310 * Currently: 8311 * r0 holds resolved field 8312 * r9 holds object 8313 */ 8314 .LOP_IGET_CHAR_finish: 8315 @bl common_squeak3 8316 cmp r9, #0 @ check object for null 8317 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8318 beq common_errNullObject @ object was null 8319 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8320 @ no-op @ acquiring load 8321 mov r2, rINST, lsr #8 @ r2<- A+ 8322 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8323 and r2, r2, #15 @ r2<- A 8324 GET_INST_OPCODE(ip) @ extract opcode from rINST 8325 SET_VREG(r0, r2) @ fp[A]<- r0 8326 GOTO_OPCODE(ip) @ jump to next instruction 8327 8328 /* continuation for OP_IGET_SHORT */ 8329 8330 /* 8331 * Currently: 8332 * r0 holds resolved field 8333 * r9 holds object 8334 */ 8335 .LOP_IGET_SHORT_finish: 8336 @bl common_squeak4 8337 cmp r9, #0 @ check object for null 8338 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8339 beq common_errNullObject @ object was null 8340 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8341 @ no-op @ acquiring load 8342 mov r2, rINST, lsr #8 @ r2<- A+ 8343 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8344 and r2, r2, #15 @ r2<- A 8345 GET_INST_OPCODE(ip) @ extract opcode from rINST 8346 SET_VREG(r0, r2) @ fp[A]<- r0 8347 GOTO_OPCODE(ip) @ jump to next instruction 8348 8349 /* continuation for OP_IPUT */ 8350 8351 /* 8352 * Currently: 8353 * r0 holds resolved field 8354 * r9 holds object 8355 */ 8356 .LOP_IPUT_finish: 8357 @bl common_squeak0 8358 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8359 ubfx r1, rINST, #8, #4 @ r1<- A 8360 cmp r9, #0 @ check object for null 8361 GET_VREG(r0, r1) @ r0<- fp[A] 8362 beq common_errNullObject @ object was null 8363 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8364 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8365 GET_INST_OPCODE(ip) @ extract opcode from rINST 8366 GOTO_OPCODE(ip) @ jump to next instruction 8367 8368 /* continuation for OP_IPUT_WIDE */ 8369 8370 /* 8371 * Currently: 8372 * r0 holds resolved field 8373 * r9 holds object 8374 */ 8375 .LOP_IPUT_WIDE_finish: 8376 ubfx r2, rINST, #8, #4 @ r2<- A 8377 cmp r9, #0 @ check object for null 8378 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8379 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 8380 beq common_errNullObject @ object was null 8381 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8382 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 8383 GET_INST_OPCODE(ip) @ extract opcode from rINST 8384 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0 8385 GOTO_OPCODE(ip) @ jump to next instruction 8386 8387 /* continuation for OP_IPUT_OBJECT */ 8388 8389 /* 8390 * Currently: 8391 * r0 holds resolved field 8392 * r9 holds object 8393 */ 8394 .LOP_IPUT_OBJECT_finish: 8395 @bl common_squeak0 8396 mov r1, rINST, lsr #8 @ r1<- A+ 8397 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8398 and r1, r1, #15 @ r1<- A 8399 cmp r9, #0 @ check object for null 8400 GET_VREG(r0, r1) @ r0<- fp[A] 8401 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8402 beq common_errNullObject @ object was null 8403 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8404 @ no-op @ releasing store 8405 str r0, [r9, r3] @ obj.field (32 bits)<- r0 8406 @ no-op 8407 GET_INST_OPCODE(ip) @ extract opcode from rINST 8408 cmp r0, #0 @ stored a null reference? 8409 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 8410 GOTO_OPCODE(ip) @ jump to next instruction 8411 8412 /* continuation for OP_IPUT_BOOLEAN */ 8413 8414 /* 8415 * Currently: 8416 * r0 holds resolved field 8417 * r9 holds object 8418 */ 8419 .LOP_IPUT_BOOLEAN_finish: 8420 @bl common_squeak1 8421 mov r1, rINST, lsr #8 @ r1<- A+ 8422 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8423 and r1, r1, #15 @ r1<- A 8424 cmp r9, #0 @ check object for null 8425 GET_VREG(r0, r1) @ r0<- fp[A] 8426 beq common_errNullObject @ object was null 8427 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8428 @ no-op @ releasing store 8429 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8430 @ no-op 8431 GET_INST_OPCODE(ip) @ extract opcode from rINST 8432 GOTO_OPCODE(ip) @ jump to next instruction 8433 8434 /* continuation for OP_IPUT_BYTE */ 8435 8436 /* 8437 * Currently: 8438 * r0 holds resolved field 8439 * r9 holds object 8440 */ 8441 .LOP_IPUT_BYTE_finish: 8442 @bl common_squeak2 8443 mov r1, rINST, lsr #8 @ r1<- A+ 8444 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8445 and r1, r1, #15 @ r1<- A 8446 cmp r9, #0 @ check object for null 8447 GET_VREG(r0, r1) @ r0<- fp[A] 8448 beq common_errNullObject @ object was null 8449 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8450 @ no-op @ releasing store 8451 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8452 @ no-op 8453 GET_INST_OPCODE(ip) @ extract opcode from rINST 8454 GOTO_OPCODE(ip) @ jump to next instruction 8455 8456 /* continuation for OP_IPUT_CHAR */ 8457 8458 /* 8459 * Currently: 8460 * r0 holds resolved field 8461 * r9 holds object 8462 */ 8463 .LOP_IPUT_CHAR_finish: 8464 @bl common_squeak3 8465 mov r1, rINST, lsr #8 @ r1<- A+ 8466 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8467 and r1, r1, #15 @ r1<- A 8468 cmp r9, #0 @ check object for null 8469 GET_VREG(r0, r1) @ r0<- fp[A] 8470 beq common_errNullObject @ object was null 8471 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8472 @ no-op @ releasing store 8473 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8474 @ no-op 8475 GET_INST_OPCODE(ip) @ extract opcode from rINST 8476 GOTO_OPCODE(ip) @ jump to next instruction 8477 8478 /* continuation for OP_IPUT_SHORT */ 8479 8480 /* 8481 * Currently: 8482 * r0 holds resolved field 8483 * r9 holds object 8484 */ 8485 .LOP_IPUT_SHORT_finish: 8486 @bl common_squeak4 8487 mov r1, rINST, lsr #8 @ r1<- A+ 8488 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8489 and r1, r1, #15 @ r1<- A 8490 cmp r9, #0 @ check object for null 8491 GET_VREG(r0, r1) @ r0<- fp[A] 8492 beq common_errNullObject @ object was null 8493 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8494 @ no-op @ releasing store 8495 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8496 @ no-op 8497 GET_INST_OPCODE(ip) @ extract opcode from rINST 8498 GOTO_OPCODE(ip) @ jump to next instruction 8499 8500 /* continuation for OP_SGET */ 8501 8502 /* 8503 * Continuation if the field has not yet been resolved. 8504 * r1: BBBB field ref 8505 * r10: dvmDex->pResFields 8506 */ 8507 .LOP_SGET_resolve: 8508 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8509 #if defined(WITH_JIT) 8510 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8511 #endif 8512 EXPORT_PC() @ resolve() could throw, so export now 8513 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8514 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8515 cmp r0, #0 @ success? 8516 beq common_exceptionThrown @ no, handle exception 8517 #if defined(WITH_JIT) 8518 /* 8519 * If the JIT is actively building a trace we need to make sure 8520 * that the field is fully resolved before including this instruction. 8521 */ 8522 bl common_verifyField 8523 #endif 8524 b .LOP_SGET_finish 8525 8526 /* continuation for OP_SGET_WIDE */ 8527 8528 /* 8529 * Continuation if the field has not yet been resolved. 8530 * r1: BBBB field ref 8531 * r10: dvmDex->pResFields 8532 * 8533 * Returns StaticField pointer in r0. 8534 */ 8535 .LOP_SGET_WIDE_resolve: 8536 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8537 #if defined(WITH_JIT) 8538 add r10, r10, r1, lsl #2 @ r1<- &dvmDex->pResFields[field] 8539 #endif 8540 EXPORT_PC() @ resolve() could throw, so export now 8541 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8542 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8543 cmp r0, #0 @ success? 8544 beq common_exceptionThrown @ no, handle exception 8545 #if defined(WITH_JIT) 8546 /* 8547 * If the JIT is actively building a trace we need to make sure 8548 * that the field is fully resolved before including this instruction. 8549 */ 8550 bl common_verifyField 8551 #endif 8552 b .LOP_SGET_WIDE_finish @ resume 8553 8554 /* continuation for OP_SGET_OBJECT */ 8555 8556 /* 8557 * Continuation if the field has not yet been resolved. 8558 * r1: BBBB field ref 8559 * r10: dvmDex->pResFields 8560 */ 8561 .LOP_SGET_OBJECT_resolve: 8562 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8563 #if defined(WITH_JIT) 8564 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8565 #endif 8566 EXPORT_PC() @ resolve() could throw, so export now 8567 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8568 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8569 cmp r0, #0 @ success? 8570 beq common_exceptionThrown @ no, handle exception 8571 #if defined(WITH_JIT) 8572 /* 8573 * If the JIT is actively building a trace we need to make sure 8574 * that the field is fully resolved before including this instruction. 8575 */ 8576 bl common_verifyField 8577 #endif 8578 b .LOP_SGET_OBJECT_finish 8579 8580 /* continuation for OP_SGET_BOOLEAN */ 8581 8582 /* 8583 * Continuation if the field has not yet been resolved. 8584 * r1: BBBB field ref 8585 * r10: dvmDex->pResFields 8586 */ 8587 .LOP_SGET_BOOLEAN_resolve: 8588 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8589 #if defined(WITH_JIT) 8590 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8591 #endif 8592 EXPORT_PC() @ resolve() could throw, so export now 8593 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8594 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8595 cmp r0, #0 @ success? 8596 beq common_exceptionThrown @ no, handle exception 8597 #if defined(WITH_JIT) 8598 /* 8599 * If the JIT is actively building a trace we need to make sure 8600 * that the field is fully resolved before including this instruction. 8601 */ 8602 bl common_verifyField 8603 #endif 8604 b .LOP_SGET_BOOLEAN_finish 8605 8606 /* continuation for OP_SGET_BYTE */ 8607 8608 /* 8609 * Continuation if the field has not yet been resolved. 8610 * r1: BBBB field ref 8611 * r10: dvmDex->pResFields 8612 */ 8613 .LOP_SGET_BYTE_resolve: 8614 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8615 #if defined(WITH_JIT) 8616 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8617 #endif 8618 EXPORT_PC() @ resolve() could throw, so export now 8619 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8620 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8621 cmp r0, #0 @ success? 8622 beq common_exceptionThrown @ no, handle exception 8623 #if defined(WITH_JIT) 8624 /* 8625 * If the JIT is actively building a trace we need to make sure 8626 * that the field is fully resolved before including this instruction. 8627 */ 8628 bl common_verifyField 8629 #endif 8630 b .LOP_SGET_BYTE_finish 8631 8632 /* continuation for OP_SGET_CHAR */ 8633 8634 /* 8635 * Continuation if the field has not yet been resolved. 8636 * r1: BBBB field ref 8637 * r10: dvmDex->pResFields 8638 */ 8639 .LOP_SGET_CHAR_resolve: 8640 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8641 #if defined(WITH_JIT) 8642 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8643 #endif 8644 EXPORT_PC() @ resolve() could throw, so export now 8645 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8646 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8647 cmp r0, #0 @ success? 8648 beq common_exceptionThrown @ no, handle exception 8649 #if defined(WITH_JIT) 8650 /* 8651 * If the JIT is actively building a trace we need to make sure 8652 * that the field is fully resolved before including this instruction. 8653 */ 8654 bl common_verifyField 8655 #endif 8656 b .LOP_SGET_CHAR_finish 8657 8658 /* continuation for OP_SGET_SHORT */ 8659 8660 /* 8661 * Continuation if the field has not yet been resolved. 8662 * r1: BBBB field ref 8663 * r10: dvmDex->pResFields 8664 */ 8665 .LOP_SGET_SHORT_resolve: 8666 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8667 #if defined(WITH_JIT) 8668 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8669 #endif 8670 EXPORT_PC() @ resolve() could throw, so export now 8671 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8672 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8673 cmp r0, #0 @ success? 8674 beq common_exceptionThrown @ no, handle exception 8675 #if defined(WITH_JIT) 8676 /* 8677 * If the JIT is actively building a trace we need to make sure 8678 * that the field is fully resolved before including this instruction. 8679 */ 8680 bl common_verifyField 8681 #endif 8682 b .LOP_SGET_SHORT_finish 8683 8684 /* continuation for OP_SPUT */ 8685 8686 /* 8687 * Continuation if the field has not yet been resolved. 8688 * r1: BBBB field ref 8689 * r10: dvmDex->pResFields 8690 */ 8691 .LOP_SPUT_resolve: 8692 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8693 #if defined(WITH_JIT) 8694 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8695 #endif 8696 EXPORT_PC() @ resolve() could throw, so export now 8697 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8698 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8699 cmp r0, #0 @ success? 8700 beq common_exceptionThrown @ no, handle exception 8701 #if defined(WITH_JIT) 8702 /* 8703 * If the JIT is actively building a trace we need to make sure 8704 * that the field is fully resolved before including this instruction. 8705 */ 8706 bl common_verifyField 8707 #endif 8708 b .LOP_SPUT_finish @ resume 8709 8710 /* continuation for OP_SPUT_WIDE */ 8711 8712 /* 8713 * Continuation if the field has not yet been resolved. 8714 * r1: BBBB field ref 8715 * r9: &fp[AA] 8716 * r10: dvmDex->pResFields 8717 * 8718 * Returns StaticField pointer in r2. 8719 */ 8720 .LOP_SPUT_WIDE_resolve: 8721 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8722 #if defined(WITH_JIT) 8723 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8724 #endif 8725 EXPORT_PC() @ resolve() could throw, so export now 8726 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8727 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8728 cmp r0, #0 @ success? 8729 mov r2, r0 @ copy to r2 8730 beq common_exceptionThrown @ no, handle exception 8731 #if defined(WITH_JIT) 8732 /* 8733 * If the JIT is actively building a trace we need to make sure 8734 * that the field is fully resolved before including this instruction. 8735 */ 8736 bl common_verifyField 8737 #endif 8738 b .LOP_SPUT_WIDE_finish @ resume 8739 8740 /* continuation for OP_SPUT_OBJECT */ 8741 8742 8743 .LOP_SPUT_OBJECT_end: 8744 str r1, [r0, #offStaticField_value] @ field<- vAA 8745 @ no-op 8746 cmp r1, #0 @ stored a null object? 8747 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 8748 GOTO_OPCODE(ip) @ jump to next instruction 8749 8750 /* Continuation if the field has not yet been resolved. 8751 * r1: BBBB field ref 8752 * r10: dvmDex->pResFields 8753 */ 8754 .LOP_SPUT_OBJECT_resolve: 8755 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8756 #if defined(WITH_JIT) 8757 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8758 #endif 8759 EXPORT_PC() @ resolve() could throw, so export now 8760 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8761 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8762 cmp r0, #0 @ success? 8763 beq common_exceptionThrown @ no, handle exception 8764 #if defined(WITH_JIT) 8765 /* 8766 * If the JIT is actively building a trace we need to make sure 8767 * that the field is fully resolved before including this instruction. 8768 */ 8769 bl common_verifyField 8770 #endif 8771 b .LOP_SPUT_OBJECT_finish @ resume 8772 8773 8774 /* continuation for OP_SPUT_BOOLEAN */ 8775 8776 /* 8777 * Continuation if the field has not yet been resolved. 8778 * r1: BBBB field ref 8779 * r10: dvmDex->pResFields 8780 */ 8781 .LOP_SPUT_BOOLEAN_resolve: 8782 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8783 #if defined(WITH_JIT) 8784 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8785 #endif 8786 EXPORT_PC() @ resolve() could throw, so export now 8787 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8788 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8789 cmp r0, #0 @ success? 8790 beq common_exceptionThrown @ no, handle exception 8791 #if defined(WITH_JIT) 8792 /* 8793 * If the JIT is actively building a trace we need to make sure 8794 * that the field is fully resolved before including this instruction. 8795 */ 8796 bl common_verifyField 8797 #endif 8798 b .LOP_SPUT_BOOLEAN_finish @ resume 8799 8800 /* continuation for OP_SPUT_BYTE */ 8801 8802 /* 8803 * Continuation if the field has not yet been resolved. 8804 * r1: BBBB field ref 8805 * r10: dvmDex->pResFields 8806 */ 8807 .LOP_SPUT_BYTE_resolve: 8808 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8809 #if defined(WITH_JIT) 8810 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8811 #endif 8812 EXPORT_PC() @ resolve() could throw, so export now 8813 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8814 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8815 cmp r0, #0 @ success? 8816 beq common_exceptionThrown @ no, handle exception 8817 #if defined(WITH_JIT) 8818 /* 8819 * If the JIT is actively building a trace we need to make sure 8820 * that the field is fully resolved before including this instruction. 8821 */ 8822 bl common_verifyField 8823 #endif 8824 b .LOP_SPUT_BYTE_finish @ resume 8825 8826 /* continuation for OP_SPUT_CHAR */ 8827 8828 /* 8829 * Continuation if the field has not yet been resolved. 8830 * r1: BBBB field ref 8831 * r10: dvmDex->pResFields 8832 */ 8833 .LOP_SPUT_CHAR_resolve: 8834 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8835 #if defined(WITH_JIT) 8836 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8837 #endif 8838 EXPORT_PC() @ resolve() could throw, so export now 8839 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8840 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8841 cmp r0, #0 @ success? 8842 beq common_exceptionThrown @ no, handle exception 8843 #if defined(WITH_JIT) 8844 /* 8845 * If the JIT is actively building a trace we need to make sure 8846 * that the field is fully resolved before including this instruction. 8847 */ 8848 bl common_verifyField 8849 #endif 8850 b .LOP_SPUT_CHAR_finish @ resume 8851 8852 /* continuation for OP_SPUT_SHORT */ 8853 8854 /* 8855 * Continuation if the field has not yet been resolved. 8856 * r1: BBBB field ref 8857 * r10: dvmDex->pResFields 8858 */ 8859 .LOP_SPUT_SHORT_resolve: 8860 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8861 #if defined(WITH_JIT) 8862 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8863 #endif 8864 EXPORT_PC() @ resolve() could throw, so export now 8865 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8866 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8867 cmp r0, #0 @ success? 8868 beq common_exceptionThrown @ no, handle exception 8869 #if defined(WITH_JIT) 8870 /* 8871 * If the JIT is actively building a trace we need to make sure 8872 * that the field is fully resolved before including this instruction. 8873 */ 8874 bl common_verifyField 8875 #endif 8876 b .LOP_SPUT_SHORT_finish @ resume 8877 8878 /* continuation for OP_INVOKE_VIRTUAL */ 8879 8880 /* 8881 * At this point: 8882 * r0 = resolved base method 8883 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 8884 */ 8885 .LOP_INVOKE_VIRTUAL_continue: 8886 GET_VREG(r9, r10) @ r9<- "this" ptr 8887 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 8888 cmp r9, #0 @ is "this" null? 8889 beq common_errNullObject @ null "this", throw exception 8890 ldr r3, [r9, #offObject_clazz] @ r3<- thisPtr->clazz 8891 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 8892 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 8893 bl common_invokeMethodNoRange @ (r0=method, r9="this") 8894 8895 /* continuation for OP_INVOKE_SUPER */ 8896 8897 /* 8898 * At this point: 8899 * r0 = resolved base method 8900 * r10 = method->clazz 8901 */ 8902 .LOP_INVOKE_SUPER_continue: 8903 ldr r1, [r10, #offClassObject_super] @ r1<- method->clazz->super 8904 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 8905 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 8906 EXPORT_PC() @ must export for invoke 8907 cmp r2, r3 @ compare (methodIndex, vtableCount) 8908 bcs .LOP_INVOKE_SUPER_nsm @ method not present in superclass 8909 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 8910 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 8911 bl common_invokeMethodNoRange @ continue on 8912 8913 .LOP_INVOKE_SUPER_resolve: 8914 mov r0, r10 @ r0<- method->clazz 8915 mov r2, #METHOD_VIRTUAL @ resolver method type 8916 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8917 cmp r0, #0 @ got null? 8918 bne .LOP_INVOKE_SUPER_continue @ no, continue 8919 b common_exceptionThrown @ yes, handle exception 8920 8921 /* 8922 * Throw a NoSuchMethodError with the method name as the message. 8923 * r0 = resolved base method 8924 */ 8925 .LOP_INVOKE_SUPER_nsm: 8926 ldr r1, [r0, #offMethod_name] @ r1<- method name 8927 b common_errNoSuchMethod 8928 8929 /* continuation for OP_INVOKE_DIRECT */ 8930 8931 /* 8932 * On entry: 8933 * r1 = reference (BBBB or CCCC) 8934 * r10 = "this" register 8935 */ 8936 .LOP_INVOKE_DIRECT_resolve: 8937 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 8938 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8939 mov r2, #METHOD_DIRECT @ resolver method type 8940 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8941 cmp r0, #0 @ got null? 8942 bne .LOP_INVOKE_DIRECT_finish @ no, continue 8943 b common_exceptionThrown @ yes, handle exception 8944 8945 /* continuation for OP_INVOKE_STATIC */ 8946 8947 8948 .LOP_INVOKE_STATIC_resolve: 8949 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 8950 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8951 mov r2, #METHOD_STATIC @ resolver method type 8952 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8953 cmp r0, #0 @ got null? 8954 #if defined(WITH_JIT) 8955 /* 8956 * Check to see if we're actively building a trace. If so, 8957 * we need to keep this instruction out of it. 8958 * r10: &resolved_methodToCall 8959 */ 8960 ldrh r2, [rSELF, #offThread_subMode] 8961 beq common_exceptionThrown @ null, handle exception 8962 ands r2, #kSubModeJitTraceBuild @ trace under construction? 8963 beq common_invokeMethodNoRange @ no (r0=method, r9="this") 8964 ldr r1, [r10] @ reload resolved method 8965 cmp r1, #0 @ finished resolving? 8966 bne common_invokeMethodNoRange @ yes (r0=method, r9="this") 8967 mov r10, r0 @ preserve method 8968 mov r0, rSELF 8969 mov r1, rPC 8970 bl dvmJitEndTraceSelect @ (self, pc) 8971 mov r0, r10 8972 b common_invokeMethodNoRange @ whew, finally! 8973 #else 8974 bne common_invokeMethodNoRange @ (r0=method, r9="this") 8975 b common_exceptionThrown @ yes, handle exception 8976 #endif 8977 8978 /* continuation for OP_INVOKE_VIRTUAL_RANGE */ 8979 8980 /* 8981 * At this point: 8982 * r0 = resolved base method 8983 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 8984 */ 8985 .LOP_INVOKE_VIRTUAL_RANGE_continue: 8986 GET_VREG(r9, r10) @ r9<- "this" ptr 8987 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 8988 cmp r9, #0 @ is "this" null? 8989 beq common_errNullObject @ null "this", throw exception 8990 ldr r3, [r9, #offObject_clazz] @ r3<- thisPtr->clazz 8991 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 8992 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 8993 bl common_invokeMethodRange @ (r0=method, r9="this") 8994 8995 /* continuation for OP_INVOKE_SUPER_RANGE */ 8996 8997 /* 8998 * At this point: 8999 * r0 = resolved base method 9000 * r10 = method->clazz 9001 */ 9002 .LOP_INVOKE_SUPER_RANGE_continue: 9003 ldr r1, [r10, #offClassObject_super] @ r1<- method->clazz->super 9004 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 9005 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 9006 EXPORT_PC() @ must export for invoke 9007 cmp r2, r3 @ compare (methodIndex, vtableCount) 9008 bcs .LOP_INVOKE_SUPER_RANGE_nsm @ method not present in superclass 9009 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 9010 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 9011 bl common_invokeMethodRange @ continue on 9012 9013 .LOP_INVOKE_SUPER_RANGE_resolve: 9014 mov r0, r10 @ r0<- method->clazz 9015 mov r2, #METHOD_VIRTUAL @ resolver method type 9016 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9017 cmp r0, #0 @ got null? 9018 bne .LOP_INVOKE_SUPER_RANGE_continue @ no, continue 9019 b common_exceptionThrown @ yes, handle exception 9020 9021 /* 9022 * Throw a NoSuchMethodError with the method name as the message. 9023 * r0 = resolved base method 9024 */ 9025 .LOP_INVOKE_SUPER_RANGE_nsm: 9026 ldr r1, [r0, #offMethod_name] @ r1<- method name 9027 b common_errNoSuchMethod 9028 9029 /* continuation for OP_INVOKE_DIRECT_RANGE */ 9030 9031 /* 9032 * On entry: 9033 * r1 = reference (BBBB or CCCC) 9034 * r10 = "this" register 9035 */ 9036 .LOP_INVOKE_DIRECT_RANGE_resolve: 9037 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9038 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9039 mov r2, #METHOD_DIRECT @ resolver method type 9040 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9041 cmp r0, #0 @ got null? 9042 bne .LOP_INVOKE_DIRECT_RANGE_finish @ no, continue 9043 b common_exceptionThrown @ yes, handle exception 9044 9045 /* continuation for OP_INVOKE_STATIC_RANGE */ 9046 9047 9048 .LOP_INVOKE_STATIC_RANGE_resolve: 9049 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9050 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9051 mov r2, #METHOD_STATIC @ resolver method type 9052 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9053 cmp r0, #0 @ got null? 9054 #if defined(WITH_JIT) 9055 /* 9056 * Check to see if we're actively building a trace. If so, 9057 * we need to keep this instruction out of it. 9058 * r10: &resolved_methodToCall 9059 */ 9060 ldrh r2, [rSELF, #offThread_subMode] 9061 beq common_exceptionThrown @ null, handle exception 9062 ands r2, #kSubModeJitTraceBuild @ trace under construction? 9063 beq common_invokeMethodRange @ no (r0=method, r9="this") 9064 ldr r1, [r10] @ reload resolved method 9065 cmp r1, #0 @ finished resolving? 9066 bne common_invokeMethodRange @ yes (r0=method, r9="this") 9067 mov r10, r0 @ preserve method 9068 mov r0, rSELF 9069 mov r1, rPC 9070 bl dvmJitEndTraceSelect @ (self, pc) 9071 mov r0, r10 9072 b common_invokeMethodRange @ whew, finally! 9073 #else 9074 bne common_invokeMethodRange @ (r0=method, r9="this") 9075 b common_exceptionThrown @ yes, handle exception 9076 #endif 9077 9078 /* continuation for OP_FLOAT_TO_LONG */ 9079 /* 9080 * Convert the float in r0 to a long in r0/r1. 9081 * 9082 * We have to clip values to long min/max per the specification. The 9083 * expected common case is a "reasonable" value that converts directly 9084 * to modest integer. The EABI convert function isn't doing this for us. 9085 */ 9086 f2l_doconv: 9087 stmfd sp!, {r4, lr} 9088 mov r1, #0x5f000000 @ (float)maxlong 9089 mov r4, r0 9090 bl __aeabi_fcmpge @ is arg >= maxlong? 9091 cmp r0, #0 @ nonzero == yes 9092 mvnne r0, #0 @ return maxlong (7fffffff) 9093 mvnne r1, #0x80000000 9094 ldmnefd sp!, {r4, pc} 9095 9096 mov r0, r4 @ recover arg 9097 mov r1, #0xdf000000 @ (float)minlong 9098 bl __aeabi_fcmple @ is arg <= minlong? 9099 cmp r0, #0 @ nonzero == yes 9100 movne r0, #0 @ return minlong (80000000) 9101 movne r1, #0x80000000 9102 ldmnefd sp!, {r4, pc} 9103 9104 mov r0, r4 @ recover arg 9105 mov r1, r4 9106 bl __aeabi_fcmpeq @ is arg == self? 9107 cmp r0, #0 @ zero == no 9108 moveq r1, #0 @ return zero for NaN 9109 ldmeqfd sp!, {r4, pc} 9110 9111 mov r0, r4 @ recover arg 9112 bl __aeabi_f2lz @ convert float to long 9113 ldmfd sp!, {r4, pc} 9114 9115 /* continuation for OP_DOUBLE_TO_LONG */ 9116 /* 9117 * Convert the double in r0/r1 to a long in r0/r1. 9118 * 9119 * We have to clip values to long min/max per the specification. The 9120 * expected common case is a "reasonable" value that converts directly 9121 * to modest integer. The EABI convert function isn't doing this for us. 9122 */ 9123 d2l_doconv: 9124 stmfd sp!, {r4, r5, lr} @ save regs 9125 mov r3, #0x43000000 @ maxlong, as a double (high word) 9126 add r3, #0x00e00000 @ 0x43e00000 9127 mov r2, #0 @ maxlong, as a double (low word) 9128 sub sp, sp, #4 @ align for EABI 9129 mov r4, r0 @ save a copy of r0 9130 mov r5, r1 @ and r1 9131 bl __aeabi_dcmpge @ is arg >= maxlong? 9132 cmp r0, #0 @ nonzero == yes 9133 mvnne r0, #0 @ return maxlong (7fffffffffffffff) 9134 mvnne r1, #0x80000000 9135 bne 1f 9136 9137 mov r0, r4 @ recover arg 9138 mov r1, r5 9139 mov r3, #0xc3000000 @ minlong, as a double (high word) 9140 add r3, #0x00e00000 @ 0xc3e00000 9141 mov r2, #0 @ minlong, as a double (low word) 9142 bl __aeabi_dcmple @ is arg <= minlong? 9143 cmp r0, #0 @ nonzero == yes 9144 movne r0, #0 @ return minlong (8000000000000000) 9145 movne r1, #0x80000000 9146 bne 1f 9147 9148 mov r0, r4 @ recover arg 9149 mov r1, r5 9150 mov r2, r4 @ compare against self 9151 mov r3, r5 9152 bl __aeabi_dcmpeq @ is arg == self? 9153 cmp r0, #0 @ zero == no 9154 moveq r1, #0 @ return zero for NaN 9155 beq 1f 9156 9157 mov r0, r4 @ recover arg 9158 mov r1, r5 9159 bl __aeabi_d2lz @ convert double to long 9160 9161 1: 9162 add sp, sp, #4 9163 ldmfd sp!, {r4, r5, pc} 9164 9165 /* continuation for OP_MUL_LONG */ 9166 9167 .LOP_MUL_LONG_finish: 9168 GET_INST_OPCODE(ip) @ extract opcode from rINST 9169 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 9170 GOTO_OPCODE(ip) @ jump to next instruction 9171 9172 /* continuation for OP_SHL_LONG */ 9173 9174 .LOP_SHL_LONG_finish: 9175 mov r0, r0, asl r2 @ r0<- r0 << r2 9176 GET_INST_OPCODE(ip) @ extract opcode from rINST 9177 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9178 GOTO_OPCODE(ip) @ jump to next instruction 9179 9180 /* continuation for OP_SHR_LONG */ 9181 9182 .LOP_SHR_LONG_finish: 9183 mov r1, r1, asr r2 @ r1<- r1 >> r2 9184 GET_INST_OPCODE(ip) @ extract opcode from rINST 9185 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9186 GOTO_OPCODE(ip) @ jump to next instruction 9187 9188 /* continuation for OP_USHR_LONG */ 9189 9190 .LOP_USHR_LONG_finish: 9191 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 9192 GET_INST_OPCODE(ip) @ extract opcode from rINST 9193 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9194 GOTO_OPCODE(ip) @ jump to next instruction 9195 9196 /* continuation for OP_SHL_LONG_2ADDR */ 9197 9198 .LOP_SHL_LONG_2ADDR_finish: 9199 GET_INST_OPCODE(ip) @ extract opcode from rINST 9200 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9201 GOTO_OPCODE(ip) @ jump to next instruction 9202 9203 /* continuation for OP_SHR_LONG_2ADDR */ 9204 9205 .LOP_SHR_LONG_2ADDR_finish: 9206 GET_INST_OPCODE(ip) @ extract opcode from rINST 9207 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9208 GOTO_OPCODE(ip) @ jump to next instruction 9209 9210 /* continuation for OP_USHR_LONG_2ADDR */ 9211 9212 .LOP_USHR_LONG_2ADDR_finish: 9213 GET_INST_OPCODE(ip) @ extract opcode from rINST 9214 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9215 GOTO_OPCODE(ip) @ jump to next instruction 9216 9217 /* continuation for OP_IGET_VOLATILE */ 9218 9219 /* 9220 * Currently: 9221 * r0 holds resolved field 9222 * r9 holds object 9223 */ 9224 .LOP_IGET_VOLATILE_finish: 9225 @bl common_squeak0 9226 cmp r9, #0 @ check object for null 9227 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9228 beq common_errNullObject @ object was null 9229 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 9230 SMP_DMB @ acquiring load 9231 mov r2, rINST, lsr #8 @ r2<- A+ 9232 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9233 and r2, r2, #15 @ r2<- A 9234 GET_INST_OPCODE(ip) @ extract opcode from rINST 9235 SET_VREG(r0, r2) @ fp[A]<- r0 9236 GOTO_OPCODE(ip) @ jump to next instruction 9237 9238 /* continuation for OP_IPUT_VOLATILE */ 9239 9240 /* 9241 * Currently: 9242 * r0 holds resolved field 9243 * r9 holds object 9244 */ 9245 .LOP_IPUT_VOLATILE_finish: 9246 @bl common_squeak0 9247 mov r1, rINST, lsr #8 @ r1<- A+ 9248 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9249 and r1, r1, #15 @ r1<- A 9250 cmp r9, #0 @ check object for null 9251 GET_VREG(r0, r1) @ r0<- fp[A] 9252 beq common_errNullObject @ object was null 9253 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9254 SMP_DMB_ST @ releasing store 9255 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 9256 SMP_DMB 9257 GET_INST_OPCODE(ip) @ extract opcode from rINST 9258 GOTO_OPCODE(ip) @ jump to next instruction 9259 9260 /* continuation for OP_SGET_VOLATILE */ 9261 9262 /* 9263 * Continuation if the field has not yet been resolved. 9264 * r1: BBBB field ref 9265 * r10: dvmDex->pResFields 9266 */ 9267 .LOP_SGET_VOLATILE_resolve: 9268 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9269 #if defined(WITH_JIT) 9270 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9271 #endif 9272 EXPORT_PC() @ resolve() could throw, so export now 9273 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9274 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9275 cmp r0, #0 @ success? 9276 beq common_exceptionThrown @ no, handle exception 9277 #if defined(WITH_JIT) 9278 /* 9279 * If the JIT is actively building a trace we need to make sure 9280 * that the field is fully resolved before including this instruction. 9281 */ 9282 bl common_verifyField 9283 #endif 9284 b .LOP_SGET_VOLATILE_finish 9285 9286 /* continuation for OP_SPUT_VOLATILE */ 9287 9288 /* 9289 * Continuation if the field has not yet been resolved. 9290 * r1: BBBB field ref 9291 * r10: dvmDex->pResFields 9292 */ 9293 .LOP_SPUT_VOLATILE_resolve: 9294 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9295 #if defined(WITH_JIT) 9296 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9297 #endif 9298 EXPORT_PC() @ resolve() could throw, so export now 9299 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9300 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9301 cmp r0, #0 @ success? 9302 beq common_exceptionThrown @ no, handle exception 9303 #if defined(WITH_JIT) 9304 /* 9305 * If the JIT is actively building a trace we need to make sure 9306 * that the field is fully resolved before including this instruction. 9307 */ 9308 bl common_verifyField 9309 #endif 9310 b .LOP_SPUT_VOLATILE_finish @ resume 9311 9312 /* continuation for OP_IGET_OBJECT_VOLATILE */ 9313 9314 /* 9315 * Currently: 9316 * r0 holds resolved field 9317 * r9 holds object 9318 */ 9319 .LOP_IGET_OBJECT_VOLATILE_finish: 9320 @bl common_squeak0 9321 cmp r9, #0 @ check object for null 9322 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9323 beq common_errNullObject @ object was null 9324 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 9325 SMP_DMB @ acquiring load 9326 mov r2, rINST, lsr #8 @ r2<- A+ 9327 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9328 and r2, r2, #15 @ r2<- A 9329 GET_INST_OPCODE(ip) @ extract opcode from rINST 9330 SET_VREG(r0, r2) @ fp[A]<- r0 9331 GOTO_OPCODE(ip) @ jump to next instruction 9332 9333 /* continuation for OP_IGET_WIDE_VOLATILE */ 9334 9335 /* 9336 * Currently: 9337 * r0 holds resolved field 9338 * r9 holds object 9339 */ 9340 .LOP_IGET_WIDE_VOLATILE_finish: 9341 cmp r9, #0 @ check object for null 9342 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9343 beq common_errNullObject @ object was null 9344 .if 1 9345 add r0, r9, r3 @ r0<- address of field 9346 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 9347 .else 9348 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 9349 .endif 9350 mov r2, rINST, lsr #8 @ r2<- A+ 9351 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9352 and r2, r2, #15 @ r2<- A 9353 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 9354 GET_INST_OPCODE(ip) @ extract opcode from rINST 9355 stmia r3, {r0-r1} @ fp[A]<- r0/r1 9356 GOTO_OPCODE(ip) @ jump to next instruction 9357 9358 /* continuation for OP_IPUT_WIDE_VOLATILE */ 9359 9360 /* 9361 * Currently: 9362 * r0 holds resolved field 9363 * r9 holds object 9364 */ 9365 .LOP_IPUT_WIDE_VOLATILE_finish: 9366 mov r2, rINST, lsr #8 @ r2<- A+ 9367 cmp r9, #0 @ check object for null 9368 and r2, r2, #15 @ r2<- A 9369 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9370 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 9371 beq common_errNullObject @ object was null 9372 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9373 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 9374 GET_INST_OPCODE(r10) @ extract opcode from rINST 9375 .if 1 9376 add r2, r9, r3 @ r2<- target address 9377 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 9378 .else 9379 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 9380 .endif 9381 GOTO_OPCODE(r10) @ jump to next instruction 9382 9383 /* continuation for OP_SGET_WIDE_VOLATILE */ 9384 9385 /* 9386 * Continuation if the field has not yet been resolved. 9387 * r1: BBBB field ref 9388 * r10: dvmDex->pResFields 9389 * 9390 * Returns StaticField pointer in r0. 9391 */ 9392 .LOP_SGET_WIDE_VOLATILE_resolve: 9393 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9394 #if defined(WITH_JIT) 9395 add r10, r10, r1, lsl #2 @ r1<- &dvmDex->pResFields[field] 9396 #endif 9397 EXPORT_PC() @ resolve() could throw, so export now 9398 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9399 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9400 cmp r0, #0 @ success? 9401 beq common_exceptionThrown @ no, handle exception 9402 #if defined(WITH_JIT) 9403 /* 9404 * If the JIT is actively building a trace we need to make sure 9405 * that the field is fully resolved before including this instruction. 9406 */ 9407 bl common_verifyField 9408 #endif 9409 b .LOP_SGET_WIDE_VOLATILE_finish @ resume 9410 9411 /* continuation for OP_SPUT_WIDE_VOLATILE */ 9412 9413 /* 9414 * Continuation if the field has not yet been resolved. 9415 * r1: BBBB field ref 9416 * r9: &fp[AA] 9417 * r10: dvmDex->pResFields 9418 * 9419 * Returns StaticField pointer in r2. 9420 */ 9421 .LOP_SPUT_WIDE_VOLATILE_resolve: 9422 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9423 #if defined(WITH_JIT) 9424 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9425 #endif 9426 EXPORT_PC() @ resolve() could throw, so export now 9427 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9428 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9429 cmp r0, #0 @ success? 9430 mov r2, r0 @ copy to r2 9431 beq common_exceptionThrown @ no, handle exception 9432 #if defined(WITH_JIT) 9433 /* 9434 * If the JIT is actively building a trace we need to make sure 9435 * that the field is fully resolved before including this instruction. 9436 */ 9437 bl common_verifyField 9438 #endif 9439 b .LOP_SPUT_WIDE_VOLATILE_finish @ resume 9440 9441 /* continuation for OP_EXECUTE_INLINE */ 9442 9443 /* 9444 * Extract args, call function. 9445 * r0 = #of args (0-4) 9446 * r10 = call index 9447 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 9448 * 9449 * Other ideas: 9450 * - Use a jump table from the main piece to jump directly into the 9451 * AND/LDR pairs. Costs a data load, saves a branch. 9452 * - Have five separate pieces that do the loading, so we can work the 9453 * interleave a little better. Increases code size. 9454 */ 9455 .LOP_EXECUTE_INLINE_continue: 9456 rsb r0, r0, #4 @ r0<- 4-r0 9457 FETCH(rINST, 2) @ rINST<- FEDC 9458 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 9459 bl common_abort @ (skipped due to ARM prefetch) 9460 4: and ip, rINST, #0xf000 @ isolate F 9461 ldr r3, [rFP, ip, lsr #10] @ r3<- vF (shift right 12, left 2) 9462 3: and ip, rINST, #0x0f00 @ isolate E 9463 ldr r2, [rFP, ip, lsr #6] @ r2<- vE 9464 2: and ip, rINST, #0x00f0 @ isolate D 9465 ldr r1, [rFP, ip, lsr #2] @ r1<- vD 9466 1: and ip, rINST, #0x000f @ isolate C 9467 ldr r0, [rFP, ip, lsl #2] @ r0<- vC 9468 0: 9469 ldr rINST, .LOP_EXECUTE_INLINE_table @ table of InlineOperation 9470 5: add rINST, pc 9471 ldr pc, [rINST, r10, lsl #4] @ sizeof=16, "func" is first entry 9472 @ (not reached) 9473 9474 /* 9475 * We're debugging or profiling. 9476 * r10: opIndex 9477 */ 9478 .LOP_EXECUTE_INLINE_debugmode: 9479 mov r0, r10 9480 bl dvmResolveInlineNative 9481 cmp r0, #0 @ did it resolve? 9482 beq .LOP_EXECUTE_INLINE_resume @ no, just move on 9483 mov r9, r0 @ remember method 9484 mov r1, rSELF 9485 bl dvmFastMethodTraceEnter @ (method, self) 9486 add r1, rSELF, #offThread_retval@ r1<- &self->retval 9487 sub sp, sp, #8 @ make room for arg, +64 bit align 9488 mov r0, rINST, lsr #12 @ r0<- B 9489 str r1, [sp] @ push &self->retval 9490 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 9491 mov rINST, r0 @ save result of inline 9492 add sp, sp, #8 @ pop stack 9493 mov r0, r9 @ r0<- method 9494 mov r1, rSELF 9495 bl dvmFastNativeMethodTraceExit @ (method, self) 9496 cmp rINST, #0 @ test boolean result of inline 9497 beq common_exceptionThrown @ returned false, handle exception 9498 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 9499 GET_INST_OPCODE(ip) @ extract opcode from rINST 9500 GOTO_OPCODE(ip) @ jump to next instruction 9501 9502 9503 9504 9505 .LOP_EXECUTE_INLINE_table: 9506 .word PCREL_REF(gDvmInlineOpsTable,5b) 9507 9508 /* continuation for OP_EXECUTE_INLINE_RANGE */ 9509 9510 /* 9511 * Extract args, call function. 9512 * r0 = #of args (0-4) 9513 * r10 = call index 9514 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 9515 */ 9516 .LOP_EXECUTE_INLINE_RANGE_continue: 9517 rsb r0, r0, #4 @ r0<- 4-r0 9518 FETCH(r9, 2) @ r9<- CCCC 9519 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 9520 bl common_abort @ (skipped due to ARM prefetch) 9521 4: add ip, r9, #3 @ base+3 9522 GET_VREG(r3, ip) @ r3<- vBase[3] 9523 3: add ip, r9, #2 @ base+2 9524 GET_VREG(r2, ip) @ r2<- vBase[2] 9525 2: add ip, r9, #1 @ base+1 9526 GET_VREG(r1, ip) @ r1<- vBase[1] 9527 1: add ip, r9, #0 @ (nop) 9528 GET_VREG(r0, ip) @ r0<- vBase[0] 9529 0: 9530 ldr r9, .LOP_EXECUTE_INLINE_RANGE_table @ table of InlineOperation 9531 5: add r9, pc 9532 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 9533 @ (not reached) 9534 9535 9536 /* 9537 * We're debugging or profiling. 9538 * r10: opIndex 9539 */ 9540 .LOP_EXECUTE_INLINE_RANGE_debugmode: 9541 mov r0, r10 9542 bl dvmResolveInlineNative 9543 cmp r0, #0 @ did it resolve? 9544 beq .LOP_EXECUTE_INLINE_RANGE_resume @ no, just move on 9545 mov r9, r0 @ remember method 9546 mov r1, rSELF 9547 bl dvmFastMethodTraceEnter @ (method, self) 9548 add r1, rSELF, #offThread_retval@ r1<- &self->retval 9549 sub sp, sp, #8 @ make room for arg, +64 bit align 9550 mov r0, rINST, lsr #8 @ r0<- B 9551 mov rINST, r9 @ rINST<- method 9552 str r1, [sp] @ push &self->retval 9553 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 9554 mov r9, r0 @ save result of inline 9555 add sp, sp, #8 @ pop stack 9556 mov r0, rINST @ r0<- method 9557 mov r1, rSELF 9558 bl dvmFastNativeMethodTraceExit @ (method, self) 9559 cmp r9, #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_RANGE_table: 9569 .word PCREL_REF(gDvmInlineOpsTable,5b) 9570 9571 9572 /* continuation for OP_INVOKE_OBJECT_INIT_RANGE */ 9573 9574 .LOP_INVOKE_OBJECT_INIT_RANGE_setFinal: 9575 EXPORT_PC() @ can throw 9576 bl dvmSetFinalizable @ call dvmSetFinalizable(obj) 9577 ldr r0, [rSELF, #offThread_exception] @ r0<- self->exception 9578 cmp r0, #0 @ exception pending? 9579 bne common_exceptionThrown @ yes, handle it 9580 b .LOP_INVOKE_OBJECT_INIT_RANGE_finish 9581 9582 /* 9583 * A debugger is attached, so we need to go ahead and do 9584 * this. For simplicity, we'll just jump directly to the 9585 * corresponding handler. Note that we can't use 9586 * rIBASE here because it may be in single-step mode. 9587 * Load the primary table base directly. 9588 */ 9589 .LOP_INVOKE_OBJECT_INIT_RANGE_debugger: 9590 ldr r1, [rSELF, #offThread_mainHandlerTable] 9591 mov ip, #OP_INVOKE_DIRECT_RANGE 9592 GOTO_OPCODE_BASE(r1,ip) @ execute it 9593 9594 /* continuation for OP_IPUT_OBJECT_VOLATILE */ 9595 9596 /* 9597 * Currently: 9598 * r0 holds resolved field 9599 * r9 holds object 9600 */ 9601 .LOP_IPUT_OBJECT_VOLATILE_finish: 9602 @bl common_squeak0 9603 mov r1, rINST, lsr #8 @ r1<- A+ 9604 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9605 and r1, r1, #15 @ r1<- A 9606 cmp r9, #0 @ check object for null 9607 GET_VREG(r0, r1) @ r0<- fp[A] 9608 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 9609 beq common_errNullObject @ object was null 9610 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9611 SMP_DMB_ST @ releasing store 9612 str r0, [r9, r3] @ obj.field (32 bits)<- r0 9613 SMP_DMB 9614 GET_INST_OPCODE(ip) @ extract opcode from rINST 9615 cmp r0, #0 @ stored a null reference? 9616 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 9617 GOTO_OPCODE(ip) @ jump to next instruction 9618 9619 /* continuation for OP_SGET_OBJECT_VOLATILE */ 9620 9621 /* 9622 * Continuation if the field has not yet been resolved. 9623 * r1: BBBB field ref 9624 * r10: dvmDex->pResFields 9625 */ 9626 .LOP_SGET_OBJECT_VOLATILE_resolve: 9627 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9628 #if defined(WITH_JIT) 9629 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9630 #endif 9631 EXPORT_PC() @ resolve() could throw, so export now 9632 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9633 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9634 cmp r0, #0 @ success? 9635 beq common_exceptionThrown @ no, handle exception 9636 #if defined(WITH_JIT) 9637 /* 9638 * If the JIT is actively building a trace we need to make sure 9639 * that the field is fully resolved before including this instruction. 9640 */ 9641 bl common_verifyField 9642 #endif 9643 b .LOP_SGET_OBJECT_VOLATILE_finish 9644 9645 /* continuation for OP_SPUT_OBJECT_VOLATILE */ 9646 9647 9648 .LOP_SPUT_OBJECT_VOLATILE_end: 9649 str r1, [r0, #offStaticField_value] @ field<- vAA 9650 SMP_DMB 9651 cmp r1, #0 @ stored a null object? 9652 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 9653 GOTO_OPCODE(ip) @ jump to next instruction 9654 9655 /* Continuation if the field has not yet been resolved. 9656 * r1: BBBB field ref 9657 * r10: dvmDex->pResFields 9658 */ 9659 .LOP_SPUT_OBJECT_VOLATILE_resolve: 9660 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9661 #if defined(WITH_JIT) 9662 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9663 #endif 9664 EXPORT_PC() @ resolve() could throw, so export now 9665 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9666 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9667 cmp r0, #0 @ success? 9668 beq common_exceptionThrown @ no, handle exception 9669 #if defined(WITH_JIT) 9670 /* 9671 * If the JIT is actively building a trace we need to make sure 9672 * that the field is fully resolved before including this instruction. 9673 */ 9674 bl common_verifyField 9675 #endif 9676 b .LOP_SPUT_OBJECT_VOLATILE_finish @ resume 9677 9678 9679 .size dvmAsmSisterStart, .-dvmAsmSisterStart 9680 .global dvmAsmSisterEnd 9681 dvmAsmSisterEnd: 9682 9683 9684 .global dvmAsmAltInstructionStart 9685 .type dvmAsmAltInstructionStart, %function 9686 .text 9687 9688 dvmAsmAltInstructionStart = .L_ALT_OP_NOP 9689 /* ------------------------------ */ 9690 .balign 64 9691 .L_ALT_OP_NOP: /* 0x00 */ 9692 /* File: armv5te/alt_stub.S */ 9693 /* 9694 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9695 * any interesting requests and then jump to the real instruction 9696 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9697 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9698 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9699 * bail to the real handler if breakFlags==0. 9700 */ 9701 ldrb r3, [rSELF, #offThread_breakFlags] 9702 adrl lr, dvmAsmInstructionStart + (0 * 64) 9703 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9704 cmp r3, #0 9705 bxeq lr @ nothing to do - jump to real handler 9706 EXPORT_PC() 9707 mov r0, rPC @ arg0 9708 mov r1, rFP @ arg1 9709 mov r2, rSELF @ arg2 9710 b dvmCheckBefore @ (dPC,dFP,self) tail call 9711 9712 /* ------------------------------ */ 9713 .balign 64 9714 .L_ALT_OP_MOVE: /* 0x01 */ 9715 /* File: armv5te/alt_stub.S */ 9716 /* 9717 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9718 * any interesting requests and then jump to the real instruction 9719 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9720 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9721 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9722 * bail to the real handler if breakFlags==0. 9723 */ 9724 ldrb r3, [rSELF, #offThread_breakFlags] 9725 adrl lr, dvmAsmInstructionStart + (1 * 64) 9726 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9727 cmp r3, #0 9728 bxeq lr @ nothing to do - jump to real handler 9729 EXPORT_PC() 9730 mov r0, rPC @ arg0 9731 mov r1, rFP @ arg1 9732 mov r2, rSELF @ arg2 9733 b dvmCheckBefore @ (dPC,dFP,self) tail call 9734 9735 /* ------------------------------ */ 9736 .balign 64 9737 .L_ALT_OP_MOVE_FROM16: /* 0x02 */ 9738 /* File: armv5te/alt_stub.S */ 9739 /* 9740 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9741 * any interesting requests and then jump to the real instruction 9742 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9743 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9744 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9745 * bail to the real handler if breakFlags==0. 9746 */ 9747 ldrb r3, [rSELF, #offThread_breakFlags] 9748 adrl lr, dvmAsmInstructionStart + (2 * 64) 9749 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9750 cmp r3, #0 9751 bxeq lr @ nothing to do - jump to real handler 9752 EXPORT_PC() 9753 mov r0, rPC @ arg0 9754 mov r1, rFP @ arg1 9755 mov r2, rSELF @ arg2 9756 b dvmCheckBefore @ (dPC,dFP,self) tail call 9757 9758 /* ------------------------------ */ 9759 .balign 64 9760 .L_ALT_OP_MOVE_16: /* 0x03 */ 9761 /* File: armv5te/alt_stub.S */ 9762 /* 9763 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9764 * any interesting requests and then jump to the real instruction 9765 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9766 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9767 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9768 * bail to the real handler if breakFlags==0. 9769 */ 9770 ldrb r3, [rSELF, #offThread_breakFlags] 9771 adrl lr, dvmAsmInstructionStart + (3 * 64) 9772 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9773 cmp r3, #0 9774 bxeq lr @ nothing to do - jump to real handler 9775 EXPORT_PC() 9776 mov r0, rPC @ arg0 9777 mov r1, rFP @ arg1 9778 mov r2, rSELF @ arg2 9779 b dvmCheckBefore @ (dPC,dFP,self) tail call 9780 9781 /* ------------------------------ */ 9782 .balign 64 9783 .L_ALT_OP_MOVE_WIDE: /* 0x04 */ 9784 /* File: armv5te/alt_stub.S */ 9785 /* 9786 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9787 * any interesting requests and then jump to the real instruction 9788 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9789 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9790 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9791 * bail to the real handler if breakFlags==0. 9792 */ 9793 ldrb r3, [rSELF, #offThread_breakFlags] 9794 adrl lr, dvmAsmInstructionStart + (4 * 64) 9795 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9796 cmp r3, #0 9797 bxeq lr @ nothing to do - jump to real handler 9798 EXPORT_PC() 9799 mov r0, rPC @ arg0 9800 mov r1, rFP @ arg1 9801 mov r2, rSELF @ arg2 9802 b dvmCheckBefore @ (dPC,dFP,self) tail call 9803 9804 /* ------------------------------ */ 9805 .balign 64 9806 .L_ALT_OP_MOVE_WIDE_FROM16: /* 0x05 */ 9807 /* File: armv5te/alt_stub.S */ 9808 /* 9809 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9810 * any interesting requests and then jump to the real instruction 9811 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9812 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9813 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9814 * bail to the real handler if breakFlags==0. 9815 */ 9816 ldrb r3, [rSELF, #offThread_breakFlags] 9817 adrl lr, dvmAsmInstructionStart + (5 * 64) 9818 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9819 cmp r3, #0 9820 bxeq lr @ nothing to do - jump to real handler 9821 EXPORT_PC() 9822 mov r0, rPC @ arg0 9823 mov r1, rFP @ arg1 9824 mov r2, rSELF @ arg2 9825 b dvmCheckBefore @ (dPC,dFP,self) tail call 9826 9827 /* ------------------------------ */ 9828 .balign 64 9829 .L_ALT_OP_MOVE_WIDE_16: /* 0x06 */ 9830 /* File: armv5te/alt_stub.S */ 9831 /* 9832 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9833 * any interesting requests and then jump to the real instruction 9834 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9835 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9836 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9837 * bail to the real handler if breakFlags==0. 9838 */ 9839 ldrb r3, [rSELF, #offThread_breakFlags] 9840 adrl lr, dvmAsmInstructionStart + (6 * 64) 9841 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9842 cmp r3, #0 9843 bxeq lr @ nothing to do - jump to real handler 9844 EXPORT_PC() 9845 mov r0, rPC @ arg0 9846 mov r1, rFP @ arg1 9847 mov r2, rSELF @ arg2 9848 b dvmCheckBefore @ (dPC,dFP,self) tail call 9849 9850 /* ------------------------------ */ 9851 .balign 64 9852 .L_ALT_OP_MOVE_OBJECT: /* 0x07 */ 9853 /* File: armv5te/alt_stub.S */ 9854 /* 9855 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9856 * any interesting requests and then jump to the real instruction 9857 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9858 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9859 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9860 * bail to the real handler if breakFlags==0. 9861 */ 9862 ldrb r3, [rSELF, #offThread_breakFlags] 9863 adrl lr, dvmAsmInstructionStart + (7 * 64) 9864 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9865 cmp r3, #0 9866 bxeq lr @ nothing to do - jump to real handler 9867 EXPORT_PC() 9868 mov r0, rPC @ arg0 9869 mov r1, rFP @ arg1 9870 mov r2, rSELF @ arg2 9871 b dvmCheckBefore @ (dPC,dFP,self) tail call 9872 9873 /* ------------------------------ */ 9874 .balign 64 9875 .L_ALT_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 9876 /* File: armv5te/alt_stub.S */ 9877 /* 9878 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9879 * any interesting requests and then jump to the real instruction 9880 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9881 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9882 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9883 * bail to the real handler if breakFlags==0. 9884 */ 9885 ldrb r3, [rSELF, #offThread_breakFlags] 9886 adrl lr, dvmAsmInstructionStart + (8 * 64) 9887 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9888 cmp r3, #0 9889 bxeq lr @ nothing to do - jump to real handler 9890 EXPORT_PC() 9891 mov r0, rPC @ arg0 9892 mov r1, rFP @ arg1 9893 mov r2, rSELF @ arg2 9894 b dvmCheckBefore @ (dPC,dFP,self) tail call 9895 9896 /* ------------------------------ */ 9897 .balign 64 9898 .L_ALT_OP_MOVE_OBJECT_16: /* 0x09 */ 9899 /* File: armv5te/alt_stub.S */ 9900 /* 9901 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9902 * any interesting requests and then jump to the real instruction 9903 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9904 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9905 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9906 * bail to the real handler if breakFlags==0. 9907 */ 9908 ldrb r3, [rSELF, #offThread_breakFlags] 9909 adrl lr, dvmAsmInstructionStart + (9 * 64) 9910 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9911 cmp r3, #0 9912 bxeq lr @ nothing to do - jump to real handler 9913 EXPORT_PC() 9914 mov r0, rPC @ arg0 9915 mov r1, rFP @ arg1 9916 mov r2, rSELF @ arg2 9917 b dvmCheckBefore @ (dPC,dFP,self) tail call 9918 9919 /* ------------------------------ */ 9920 .balign 64 9921 .L_ALT_OP_MOVE_RESULT: /* 0x0a */ 9922 /* File: armv5te/alt_stub.S */ 9923 /* 9924 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9925 * any interesting requests and then jump to the real instruction 9926 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9927 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9928 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9929 * bail to the real handler if breakFlags==0. 9930 */ 9931 ldrb r3, [rSELF, #offThread_breakFlags] 9932 adrl lr, dvmAsmInstructionStart + (10 * 64) 9933 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9934 cmp r3, #0 9935 bxeq lr @ nothing to do - jump to real handler 9936 EXPORT_PC() 9937 mov r0, rPC @ arg0 9938 mov r1, rFP @ arg1 9939 mov r2, rSELF @ arg2 9940 b dvmCheckBefore @ (dPC,dFP,self) tail call 9941 9942 /* ------------------------------ */ 9943 .balign 64 9944 .L_ALT_OP_MOVE_RESULT_WIDE: /* 0x0b */ 9945 /* File: armv5te/alt_stub.S */ 9946 /* 9947 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9948 * any interesting requests and then jump to the real instruction 9949 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9950 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9951 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9952 * bail to the real handler if breakFlags==0. 9953 */ 9954 ldrb r3, [rSELF, #offThread_breakFlags] 9955 adrl lr, dvmAsmInstructionStart + (11 * 64) 9956 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9957 cmp r3, #0 9958 bxeq lr @ nothing to do - jump to real handler 9959 EXPORT_PC() 9960 mov r0, rPC @ arg0 9961 mov r1, rFP @ arg1 9962 mov r2, rSELF @ arg2 9963 b dvmCheckBefore @ (dPC,dFP,self) tail call 9964 9965 /* ------------------------------ */ 9966 .balign 64 9967 .L_ALT_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 9968 /* File: armv5te/alt_stub.S */ 9969 /* 9970 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9971 * any interesting requests and then jump to the real instruction 9972 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9973 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9974 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9975 * bail to the real handler if breakFlags==0. 9976 */ 9977 ldrb r3, [rSELF, #offThread_breakFlags] 9978 adrl lr, dvmAsmInstructionStart + (12 * 64) 9979 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9980 cmp r3, #0 9981 bxeq lr @ nothing to do - jump to real handler 9982 EXPORT_PC() 9983 mov r0, rPC @ arg0 9984 mov r1, rFP @ arg1 9985 mov r2, rSELF @ arg2 9986 b dvmCheckBefore @ (dPC,dFP,self) tail call 9987 9988 /* ------------------------------ */ 9989 .balign 64 9990 .L_ALT_OP_MOVE_EXCEPTION: /* 0x0d */ 9991 /* File: armv5te/alt_stub.S */ 9992 /* 9993 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9994 * any interesting requests and then jump to the real instruction 9995 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9996 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9997 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9998 * bail to the real handler if breakFlags==0. 9999 */ 10000 ldrb r3, [rSELF, #offThread_breakFlags] 10001 adrl lr, dvmAsmInstructionStart + (13 * 64) 10002 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10003 cmp r3, #0 10004 bxeq lr @ nothing to do - jump to real handler 10005 EXPORT_PC() 10006 mov r0, rPC @ arg0 10007 mov r1, rFP @ arg1 10008 mov r2, rSELF @ arg2 10009 b dvmCheckBefore @ (dPC,dFP,self) tail call 10010 10011 /* ------------------------------ */ 10012 .balign 64 10013 .L_ALT_OP_RETURN_VOID: /* 0x0e */ 10014 /* File: armv5te/alt_stub.S */ 10015 /* 10016 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10017 * any interesting requests and then jump to the real instruction 10018 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10019 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10020 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10021 * bail to the real handler if breakFlags==0. 10022 */ 10023 ldrb r3, [rSELF, #offThread_breakFlags] 10024 adrl lr, dvmAsmInstructionStart + (14 * 64) 10025 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10026 cmp r3, #0 10027 bxeq lr @ nothing to do - jump to real handler 10028 EXPORT_PC() 10029 mov r0, rPC @ arg0 10030 mov r1, rFP @ arg1 10031 mov r2, rSELF @ arg2 10032 b dvmCheckBefore @ (dPC,dFP,self) tail call 10033 10034 /* ------------------------------ */ 10035 .balign 64 10036 .L_ALT_OP_RETURN: /* 0x0f */ 10037 /* File: armv5te/alt_stub.S */ 10038 /* 10039 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10040 * any interesting requests and then jump to the real instruction 10041 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10042 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10043 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10044 * bail to the real handler if breakFlags==0. 10045 */ 10046 ldrb r3, [rSELF, #offThread_breakFlags] 10047 adrl lr, dvmAsmInstructionStart + (15 * 64) 10048 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10049 cmp r3, #0 10050 bxeq lr @ nothing to do - jump to real handler 10051 EXPORT_PC() 10052 mov r0, rPC @ arg0 10053 mov r1, rFP @ arg1 10054 mov r2, rSELF @ arg2 10055 b dvmCheckBefore @ (dPC,dFP,self) tail call 10056 10057 /* ------------------------------ */ 10058 .balign 64 10059 .L_ALT_OP_RETURN_WIDE: /* 0x10 */ 10060 /* File: armv5te/alt_stub.S */ 10061 /* 10062 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10063 * any interesting requests and then jump to the real instruction 10064 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10065 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10066 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10067 * bail to the real handler if breakFlags==0. 10068 */ 10069 ldrb r3, [rSELF, #offThread_breakFlags] 10070 adrl lr, dvmAsmInstructionStart + (16 * 64) 10071 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10072 cmp r3, #0 10073 bxeq lr @ nothing to do - jump to real handler 10074 EXPORT_PC() 10075 mov r0, rPC @ arg0 10076 mov r1, rFP @ arg1 10077 mov r2, rSELF @ arg2 10078 b dvmCheckBefore @ (dPC,dFP,self) tail call 10079 10080 /* ------------------------------ */ 10081 .balign 64 10082 .L_ALT_OP_RETURN_OBJECT: /* 0x11 */ 10083 /* File: armv5te/alt_stub.S */ 10084 /* 10085 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10086 * any interesting requests and then jump to the real instruction 10087 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10088 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10089 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10090 * bail to the real handler if breakFlags==0. 10091 */ 10092 ldrb r3, [rSELF, #offThread_breakFlags] 10093 adrl lr, dvmAsmInstructionStart + (17 * 64) 10094 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10095 cmp r3, #0 10096 bxeq lr @ nothing to do - jump to real handler 10097 EXPORT_PC() 10098 mov r0, rPC @ arg0 10099 mov r1, rFP @ arg1 10100 mov r2, rSELF @ arg2 10101 b dvmCheckBefore @ (dPC,dFP,self) tail call 10102 10103 /* ------------------------------ */ 10104 .balign 64 10105 .L_ALT_OP_CONST_4: /* 0x12 */ 10106 /* File: armv5te/alt_stub.S */ 10107 /* 10108 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10109 * any interesting requests and then jump to the real instruction 10110 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10111 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10112 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10113 * bail to the real handler if breakFlags==0. 10114 */ 10115 ldrb r3, [rSELF, #offThread_breakFlags] 10116 adrl lr, dvmAsmInstructionStart + (18 * 64) 10117 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10118 cmp r3, #0 10119 bxeq lr @ nothing to do - jump to real handler 10120 EXPORT_PC() 10121 mov r0, rPC @ arg0 10122 mov r1, rFP @ arg1 10123 mov r2, rSELF @ arg2 10124 b dvmCheckBefore @ (dPC,dFP,self) tail call 10125 10126 /* ------------------------------ */ 10127 .balign 64 10128 .L_ALT_OP_CONST_16: /* 0x13 */ 10129 /* File: armv5te/alt_stub.S */ 10130 /* 10131 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10132 * any interesting requests and then jump to the real instruction 10133 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10134 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10135 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10136 * bail to the real handler if breakFlags==0. 10137 */ 10138 ldrb r3, [rSELF, #offThread_breakFlags] 10139 adrl lr, dvmAsmInstructionStart + (19 * 64) 10140 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10141 cmp r3, #0 10142 bxeq lr @ nothing to do - jump to real handler 10143 EXPORT_PC() 10144 mov r0, rPC @ arg0 10145 mov r1, rFP @ arg1 10146 mov r2, rSELF @ arg2 10147 b dvmCheckBefore @ (dPC,dFP,self) tail call 10148 10149 /* ------------------------------ */ 10150 .balign 64 10151 .L_ALT_OP_CONST: /* 0x14 */ 10152 /* File: armv5te/alt_stub.S */ 10153 /* 10154 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10155 * any interesting requests and then jump to the real instruction 10156 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10157 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10158 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10159 * bail to the real handler if breakFlags==0. 10160 */ 10161 ldrb r3, [rSELF, #offThread_breakFlags] 10162 adrl lr, dvmAsmInstructionStart + (20 * 64) 10163 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10164 cmp r3, #0 10165 bxeq lr @ nothing to do - jump to real handler 10166 EXPORT_PC() 10167 mov r0, rPC @ arg0 10168 mov r1, rFP @ arg1 10169 mov r2, rSELF @ arg2 10170 b dvmCheckBefore @ (dPC,dFP,self) tail call 10171 10172 /* ------------------------------ */ 10173 .balign 64 10174 .L_ALT_OP_CONST_HIGH16: /* 0x15 */ 10175 /* File: armv5te/alt_stub.S */ 10176 /* 10177 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10178 * any interesting requests and then jump to the real instruction 10179 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10180 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10181 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10182 * bail to the real handler if breakFlags==0. 10183 */ 10184 ldrb r3, [rSELF, #offThread_breakFlags] 10185 adrl lr, dvmAsmInstructionStart + (21 * 64) 10186 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10187 cmp r3, #0 10188 bxeq lr @ nothing to do - jump to real handler 10189 EXPORT_PC() 10190 mov r0, rPC @ arg0 10191 mov r1, rFP @ arg1 10192 mov r2, rSELF @ arg2 10193 b dvmCheckBefore @ (dPC,dFP,self) tail call 10194 10195 /* ------------------------------ */ 10196 .balign 64 10197 .L_ALT_OP_CONST_WIDE_16: /* 0x16 */ 10198 /* File: armv5te/alt_stub.S */ 10199 /* 10200 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10201 * any interesting requests and then jump to the real instruction 10202 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10203 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10204 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10205 * bail to the real handler if breakFlags==0. 10206 */ 10207 ldrb r3, [rSELF, #offThread_breakFlags] 10208 adrl lr, dvmAsmInstructionStart + (22 * 64) 10209 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10210 cmp r3, #0 10211 bxeq lr @ nothing to do - jump to real handler 10212 EXPORT_PC() 10213 mov r0, rPC @ arg0 10214 mov r1, rFP @ arg1 10215 mov r2, rSELF @ arg2 10216 b dvmCheckBefore @ (dPC,dFP,self) tail call 10217 10218 /* ------------------------------ */ 10219 .balign 64 10220 .L_ALT_OP_CONST_WIDE_32: /* 0x17 */ 10221 /* File: armv5te/alt_stub.S */ 10222 /* 10223 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10224 * any interesting requests and then jump to the real instruction 10225 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10226 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10227 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10228 * bail to the real handler if breakFlags==0. 10229 */ 10230 ldrb r3, [rSELF, #offThread_breakFlags] 10231 adrl lr, dvmAsmInstructionStart + (23 * 64) 10232 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10233 cmp r3, #0 10234 bxeq lr @ nothing to do - jump to real handler 10235 EXPORT_PC() 10236 mov r0, rPC @ arg0 10237 mov r1, rFP @ arg1 10238 mov r2, rSELF @ arg2 10239 b dvmCheckBefore @ (dPC,dFP,self) tail call 10240 10241 /* ------------------------------ */ 10242 .balign 64 10243 .L_ALT_OP_CONST_WIDE: /* 0x18 */ 10244 /* File: armv5te/alt_stub.S */ 10245 /* 10246 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10247 * any interesting requests and then jump to the real instruction 10248 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10249 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10250 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10251 * bail to the real handler if breakFlags==0. 10252 */ 10253 ldrb r3, [rSELF, #offThread_breakFlags] 10254 adrl lr, dvmAsmInstructionStart + (24 * 64) 10255 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10256 cmp r3, #0 10257 bxeq lr @ nothing to do - jump to real handler 10258 EXPORT_PC() 10259 mov r0, rPC @ arg0 10260 mov r1, rFP @ arg1 10261 mov r2, rSELF @ arg2 10262 b dvmCheckBefore @ (dPC,dFP,self) tail call 10263 10264 /* ------------------------------ */ 10265 .balign 64 10266 .L_ALT_OP_CONST_WIDE_HIGH16: /* 0x19 */ 10267 /* File: armv5te/alt_stub.S */ 10268 /* 10269 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10270 * any interesting requests and then jump to the real instruction 10271 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10272 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10273 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10274 * bail to the real handler if breakFlags==0. 10275 */ 10276 ldrb r3, [rSELF, #offThread_breakFlags] 10277 adrl lr, dvmAsmInstructionStart + (25 * 64) 10278 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10279 cmp r3, #0 10280 bxeq lr @ nothing to do - jump to real handler 10281 EXPORT_PC() 10282 mov r0, rPC @ arg0 10283 mov r1, rFP @ arg1 10284 mov r2, rSELF @ arg2 10285 b dvmCheckBefore @ (dPC,dFP,self) tail call 10286 10287 /* ------------------------------ */ 10288 .balign 64 10289 .L_ALT_OP_CONST_STRING: /* 0x1a */ 10290 /* File: armv5te/alt_stub.S */ 10291 /* 10292 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10293 * any interesting requests and then jump to the real instruction 10294 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10295 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10296 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10297 * bail to the real handler if breakFlags==0. 10298 */ 10299 ldrb r3, [rSELF, #offThread_breakFlags] 10300 adrl lr, dvmAsmInstructionStart + (26 * 64) 10301 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10302 cmp r3, #0 10303 bxeq lr @ nothing to do - jump to real handler 10304 EXPORT_PC() 10305 mov r0, rPC @ arg0 10306 mov r1, rFP @ arg1 10307 mov r2, rSELF @ arg2 10308 b dvmCheckBefore @ (dPC,dFP,self) tail call 10309 10310 /* ------------------------------ */ 10311 .balign 64 10312 .L_ALT_OP_CONST_STRING_JUMBO: /* 0x1b */ 10313 /* File: armv5te/alt_stub.S */ 10314 /* 10315 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10316 * any interesting requests and then jump to the real instruction 10317 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10318 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10319 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10320 * bail to the real handler if breakFlags==0. 10321 */ 10322 ldrb r3, [rSELF, #offThread_breakFlags] 10323 adrl lr, dvmAsmInstructionStart + (27 * 64) 10324 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10325 cmp r3, #0 10326 bxeq lr @ nothing to do - jump to real handler 10327 EXPORT_PC() 10328 mov r0, rPC @ arg0 10329 mov r1, rFP @ arg1 10330 mov r2, rSELF @ arg2 10331 b dvmCheckBefore @ (dPC,dFP,self) tail call 10332 10333 /* ------------------------------ */ 10334 .balign 64 10335 .L_ALT_OP_CONST_CLASS: /* 0x1c */ 10336 /* File: armv5te/alt_stub.S */ 10337 /* 10338 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10339 * any interesting requests and then jump to the real instruction 10340 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10341 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10342 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10343 * bail to the real handler if breakFlags==0. 10344 */ 10345 ldrb r3, [rSELF, #offThread_breakFlags] 10346 adrl lr, dvmAsmInstructionStart + (28 * 64) 10347 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10348 cmp r3, #0 10349 bxeq lr @ nothing to do - jump to real handler 10350 EXPORT_PC() 10351 mov r0, rPC @ arg0 10352 mov r1, rFP @ arg1 10353 mov r2, rSELF @ arg2 10354 b dvmCheckBefore @ (dPC,dFP,self) tail call 10355 10356 /* ------------------------------ */ 10357 .balign 64 10358 .L_ALT_OP_MONITOR_ENTER: /* 0x1d */ 10359 /* File: armv5te/alt_stub.S */ 10360 /* 10361 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10362 * any interesting requests and then jump to the real instruction 10363 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10364 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10365 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10366 * bail to the real handler if breakFlags==0. 10367 */ 10368 ldrb r3, [rSELF, #offThread_breakFlags] 10369 adrl lr, dvmAsmInstructionStart + (29 * 64) 10370 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10371 cmp r3, #0 10372 bxeq lr @ nothing to do - jump to real handler 10373 EXPORT_PC() 10374 mov r0, rPC @ arg0 10375 mov r1, rFP @ arg1 10376 mov r2, rSELF @ arg2 10377 b dvmCheckBefore @ (dPC,dFP,self) tail call 10378 10379 /* ------------------------------ */ 10380 .balign 64 10381 .L_ALT_OP_MONITOR_EXIT: /* 0x1e */ 10382 /* File: armv5te/alt_stub.S */ 10383 /* 10384 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10385 * any interesting requests and then jump to the real instruction 10386 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10387 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10388 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10389 * bail to the real handler if breakFlags==0. 10390 */ 10391 ldrb r3, [rSELF, #offThread_breakFlags] 10392 adrl lr, dvmAsmInstructionStart + (30 * 64) 10393 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10394 cmp r3, #0 10395 bxeq lr @ nothing to do - jump to real handler 10396 EXPORT_PC() 10397 mov r0, rPC @ arg0 10398 mov r1, rFP @ arg1 10399 mov r2, rSELF @ arg2 10400 b dvmCheckBefore @ (dPC,dFP,self) tail call 10401 10402 /* ------------------------------ */ 10403 .balign 64 10404 .L_ALT_OP_CHECK_CAST: /* 0x1f */ 10405 /* File: armv5te/alt_stub.S */ 10406 /* 10407 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10408 * any interesting requests and then jump to the real instruction 10409 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10410 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10411 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10412 * bail to the real handler if breakFlags==0. 10413 */ 10414 ldrb r3, [rSELF, #offThread_breakFlags] 10415 adrl lr, dvmAsmInstructionStart + (31 * 64) 10416 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10417 cmp r3, #0 10418 bxeq lr @ nothing to do - jump to real handler 10419 EXPORT_PC() 10420 mov r0, rPC @ arg0 10421 mov r1, rFP @ arg1 10422 mov r2, rSELF @ arg2 10423 b dvmCheckBefore @ (dPC,dFP,self) tail call 10424 10425 /* ------------------------------ */ 10426 .balign 64 10427 .L_ALT_OP_INSTANCE_OF: /* 0x20 */ 10428 /* File: armv5te/alt_stub.S */ 10429 /* 10430 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10431 * any interesting requests and then jump to the real instruction 10432 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10433 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10434 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10435 * bail to the real handler if breakFlags==0. 10436 */ 10437 ldrb r3, [rSELF, #offThread_breakFlags] 10438 adrl lr, dvmAsmInstructionStart + (32 * 64) 10439 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10440 cmp r3, #0 10441 bxeq lr @ nothing to do - jump to real handler 10442 EXPORT_PC() 10443 mov r0, rPC @ arg0 10444 mov r1, rFP @ arg1 10445 mov r2, rSELF @ arg2 10446 b dvmCheckBefore @ (dPC,dFP,self) tail call 10447 10448 /* ------------------------------ */ 10449 .balign 64 10450 .L_ALT_OP_ARRAY_LENGTH: /* 0x21 */ 10451 /* File: armv5te/alt_stub.S */ 10452 /* 10453 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10454 * any interesting requests and then jump to the real instruction 10455 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10456 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10457 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10458 * bail to the real handler if breakFlags==0. 10459 */ 10460 ldrb r3, [rSELF, #offThread_breakFlags] 10461 adrl lr, dvmAsmInstructionStart + (33 * 64) 10462 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10463 cmp r3, #0 10464 bxeq lr @ nothing to do - jump to real handler 10465 EXPORT_PC() 10466 mov r0, rPC @ arg0 10467 mov r1, rFP @ arg1 10468 mov r2, rSELF @ arg2 10469 b dvmCheckBefore @ (dPC,dFP,self) tail call 10470 10471 /* ------------------------------ */ 10472 .balign 64 10473 .L_ALT_OP_NEW_INSTANCE: /* 0x22 */ 10474 /* File: armv5te/alt_stub.S */ 10475 /* 10476 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10477 * any interesting requests and then jump to the real instruction 10478 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10479 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10480 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10481 * bail to the real handler if breakFlags==0. 10482 */ 10483 ldrb r3, [rSELF, #offThread_breakFlags] 10484 adrl lr, dvmAsmInstructionStart + (34 * 64) 10485 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10486 cmp r3, #0 10487 bxeq lr @ nothing to do - jump to real handler 10488 EXPORT_PC() 10489 mov r0, rPC @ arg0 10490 mov r1, rFP @ arg1 10491 mov r2, rSELF @ arg2 10492 b dvmCheckBefore @ (dPC,dFP,self) tail call 10493 10494 /* ------------------------------ */ 10495 .balign 64 10496 .L_ALT_OP_NEW_ARRAY: /* 0x23 */ 10497 /* File: armv5te/alt_stub.S */ 10498 /* 10499 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10500 * any interesting requests and then jump to the real instruction 10501 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10502 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10503 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10504 * bail to the real handler if breakFlags==0. 10505 */ 10506 ldrb r3, [rSELF, #offThread_breakFlags] 10507 adrl lr, dvmAsmInstructionStart + (35 * 64) 10508 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10509 cmp r3, #0 10510 bxeq lr @ nothing to do - jump to real handler 10511 EXPORT_PC() 10512 mov r0, rPC @ arg0 10513 mov r1, rFP @ arg1 10514 mov r2, rSELF @ arg2 10515 b dvmCheckBefore @ (dPC,dFP,self) tail call 10516 10517 /* ------------------------------ */ 10518 .balign 64 10519 .L_ALT_OP_FILLED_NEW_ARRAY: /* 0x24 */ 10520 /* File: armv5te/alt_stub.S */ 10521 /* 10522 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10523 * any interesting requests and then jump to the real instruction 10524 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10525 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10526 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10527 * bail to the real handler if breakFlags==0. 10528 */ 10529 ldrb r3, [rSELF, #offThread_breakFlags] 10530 adrl lr, dvmAsmInstructionStart + (36 * 64) 10531 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10532 cmp r3, #0 10533 bxeq lr @ nothing to do - jump to real handler 10534 EXPORT_PC() 10535 mov r0, rPC @ arg0 10536 mov r1, rFP @ arg1 10537 mov r2, rSELF @ arg2 10538 b dvmCheckBefore @ (dPC,dFP,self) tail call 10539 10540 /* ------------------------------ */ 10541 .balign 64 10542 .L_ALT_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 10543 /* File: armv5te/alt_stub.S */ 10544 /* 10545 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10546 * any interesting requests and then jump to the real instruction 10547 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10548 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10549 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10550 * bail to the real handler if breakFlags==0. 10551 */ 10552 ldrb r3, [rSELF, #offThread_breakFlags] 10553 adrl lr, dvmAsmInstructionStart + (37 * 64) 10554 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10555 cmp r3, #0 10556 bxeq lr @ nothing to do - jump to real handler 10557 EXPORT_PC() 10558 mov r0, rPC @ arg0 10559 mov r1, rFP @ arg1 10560 mov r2, rSELF @ arg2 10561 b dvmCheckBefore @ (dPC,dFP,self) tail call 10562 10563 /* ------------------------------ */ 10564 .balign 64 10565 .L_ALT_OP_FILL_ARRAY_DATA: /* 0x26 */ 10566 /* File: armv5te/alt_stub.S */ 10567 /* 10568 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10569 * any interesting requests and then jump to the real instruction 10570 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10571 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10572 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10573 * bail to the real handler if breakFlags==0. 10574 */ 10575 ldrb r3, [rSELF, #offThread_breakFlags] 10576 adrl lr, dvmAsmInstructionStart + (38 * 64) 10577 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10578 cmp r3, #0 10579 bxeq lr @ nothing to do - jump to real handler 10580 EXPORT_PC() 10581 mov r0, rPC @ arg0 10582 mov r1, rFP @ arg1 10583 mov r2, rSELF @ arg2 10584 b dvmCheckBefore @ (dPC,dFP,self) tail call 10585 10586 /* ------------------------------ */ 10587 .balign 64 10588 .L_ALT_OP_THROW: /* 0x27 */ 10589 /* File: armv5te/alt_stub.S */ 10590 /* 10591 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10592 * any interesting requests and then jump to the real instruction 10593 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10594 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10595 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10596 * bail to the real handler if breakFlags==0. 10597 */ 10598 ldrb r3, [rSELF, #offThread_breakFlags] 10599 adrl lr, dvmAsmInstructionStart + (39 * 64) 10600 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10601 cmp r3, #0 10602 bxeq lr @ nothing to do - jump to real handler 10603 EXPORT_PC() 10604 mov r0, rPC @ arg0 10605 mov r1, rFP @ arg1 10606 mov r2, rSELF @ arg2 10607 b dvmCheckBefore @ (dPC,dFP,self) tail call 10608 10609 /* ------------------------------ */ 10610 .balign 64 10611 .L_ALT_OP_GOTO: /* 0x28 */ 10612 /* File: armv5te/alt_stub.S */ 10613 /* 10614 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10615 * any interesting requests and then jump to the real instruction 10616 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10617 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10618 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10619 * bail to the real handler if breakFlags==0. 10620 */ 10621 ldrb r3, [rSELF, #offThread_breakFlags] 10622 adrl lr, dvmAsmInstructionStart + (40 * 64) 10623 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10624 cmp r3, #0 10625 bxeq lr @ nothing to do - jump to real handler 10626 EXPORT_PC() 10627 mov r0, rPC @ arg0 10628 mov r1, rFP @ arg1 10629 mov r2, rSELF @ arg2 10630 b dvmCheckBefore @ (dPC,dFP,self) tail call 10631 10632 /* ------------------------------ */ 10633 .balign 64 10634 .L_ALT_OP_GOTO_16: /* 0x29 */ 10635 /* File: armv5te/alt_stub.S */ 10636 /* 10637 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10638 * any interesting requests and then jump to the real instruction 10639 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10640 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10641 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10642 * bail to the real handler if breakFlags==0. 10643 */ 10644 ldrb r3, [rSELF, #offThread_breakFlags] 10645 adrl lr, dvmAsmInstructionStart + (41 * 64) 10646 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10647 cmp r3, #0 10648 bxeq lr @ nothing to do - jump to real handler 10649 EXPORT_PC() 10650 mov r0, rPC @ arg0 10651 mov r1, rFP @ arg1 10652 mov r2, rSELF @ arg2 10653 b dvmCheckBefore @ (dPC,dFP,self) tail call 10654 10655 /* ------------------------------ */ 10656 .balign 64 10657 .L_ALT_OP_GOTO_32: /* 0x2a */ 10658 /* File: armv5te/alt_stub.S */ 10659 /* 10660 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10661 * any interesting requests and then jump to the real instruction 10662 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10663 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10664 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10665 * bail to the real handler if breakFlags==0. 10666 */ 10667 ldrb r3, [rSELF, #offThread_breakFlags] 10668 adrl lr, dvmAsmInstructionStart + (42 * 64) 10669 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10670 cmp r3, #0 10671 bxeq lr @ nothing to do - jump to real handler 10672 EXPORT_PC() 10673 mov r0, rPC @ arg0 10674 mov r1, rFP @ arg1 10675 mov r2, rSELF @ arg2 10676 b dvmCheckBefore @ (dPC,dFP,self) tail call 10677 10678 /* ------------------------------ */ 10679 .balign 64 10680 .L_ALT_OP_PACKED_SWITCH: /* 0x2b */ 10681 /* File: armv5te/alt_stub.S */ 10682 /* 10683 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10684 * any interesting requests and then jump to the real instruction 10685 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10686 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10687 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10688 * bail to the real handler if breakFlags==0. 10689 */ 10690 ldrb r3, [rSELF, #offThread_breakFlags] 10691 adrl lr, dvmAsmInstructionStart + (43 * 64) 10692 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10693 cmp r3, #0 10694 bxeq lr @ nothing to do - jump to real handler 10695 EXPORT_PC() 10696 mov r0, rPC @ arg0 10697 mov r1, rFP @ arg1 10698 mov r2, rSELF @ arg2 10699 b dvmCheckBefore @ (dPC,dFP,self) tail call 10700 10701 /* ------------------------------ */ 10702 .balign 64 10703 .L_ALT_OP_SPARSE_SWITCH: /* 0x2c */ 10704 /* File: armv5te/alt_stub.S */ 10705 /* 10706 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10707 * any interesting requests and then jump to the real instruction 10708 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10709 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10710 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10711 * bail to the real handler if breakFlags==0. 10712 */ 10713 ldrb r3, [rSELF, #offThread_breakFlags] 10714 adrl lr, dvmAsmInstructionStart + (44 * 64) 10715 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10716 cmp r3, #0 10717 bxeq lr @ nothing to do - jump to real handler 10718 EXPORT_PC() 10719 mov r0, rPC @ arg0 10720 mov r1, rFP @ arg1 10721 mov r2, rSELF @ arg2 10722 b dvmCheckBefore @ (dPC,dFP,self) tail call 10723 10724 /* ------------------------------ */ 10725 .balign 64 10726 .L_ALT_OP_CMPL_FLOAT: /* 0x2d */ 10727 /* File: armv5te/alt_stub.S */ 10728 /* 10729 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10730 * any interesting requests and then jump to the real instruction 10731 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10732 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10733 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10734 * bail to the real handler if breakFlags==0. 10735 */ 10736 ldrb r3, [rSELF, #offThread_breakFlags] 10737 adrl lr, dvmAsmInstructionStart + (45 * 64) 10738 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10739 cmp r3, #0 10740 bxeq lr @ nothing to do - jump to real handler 10741 EXPORT_PC() 10742 mov r0, rPC @ arg0 10743 mov r1, rFP @ arg1 10744 mov r2, rSELF @ arg2 10745 b dvmCheckBefore @ (dPC,dFP,self) tail call 10746 10747 /* ------------------------------ */ 10748 .balign 64 10749 .L_ALT_OP_CMPG_FLOAT: /* 0x2e */ 10750 /* File: armv5te/alt_stub.S */ 10751 /* 10752 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10753 * any interesting requests and then jump to the real instruction 10754 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10755 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10756 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10757 * bail to the real handler if breakFlags==0. 10758 */ 10759 ldrb r3, [rSELF, #offThread_breakFlags] 10760 adrl lr, dvmAsmInstructionStart + (46 * 64) 10761 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10762 cmp r3, #0 10763 bxeq lr @ nothing to do - jump to real handler 10764 EXPORT_PC() 10765 mov r0, rPC @ arg0 10766 mov r1, rFP @ arg1 10767 mov r2, rSELF @ arg2 10768 b dvmCheckBefore @ (dPC,dFP,self) tail call 10769 10770 /* ------------------------------ */ 10771 .balign 64 10772 .L_ALT_OP_CMPL_DOUBLE: /* 0x2f */ 10773 /* File: armv5te/alt_stub.S */ 10774 /* 10775 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10776 * any interesting requests and then jump to the real instruction 10777 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10778 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10779 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10780 * bail to the real handler if breakFlags==0. 10781 */ 10782 ldrb r3, [rSELF, #offThread_breakFlags] 10783 adrl lr, dvmAsmInstructionStart + (47 * 64) 10784 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10785 cmp r3, #0 10786 bxeq lr @ nothing to do - jump to real handler 10787 EXPORT_PC() 10788 mov r0, rPC @ arg0 10789 mov r1, rFP @ arg1 10790 mov r2, rSELF @ arg2 10791 b dvmCheckBefore @ (dPC,dFP,self) tail call 10792 10793 /* ------------------------------ */ 10794 .balign 64 10795 .L_ALT_OP_CMPG_DOUBLE: /* 0x30 */ 10796 /* File: armv5te/alt_stub.S */ 10797 /* 10798 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10799 * any interesting requests and then jump to the real instruction 10800 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10801 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10802 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10803 * bail to the real handler if breakFlags==0. 10804 */ 10805 ldrb r3, [rSELF, #offThread_breakFlags] 10806 adrl lr, dvmAsmInstructionStart + (48 * 64) 10807 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10808 cmp r3, #0 10809 bxeq lr @ nothing to do - jump to real handler 10810 EXPORT_PC() 10811 mov r0, rPC @ arg0 10812 mov r1, rFP @ arg1 10813 mov r2, rSELF @ arg2 10814 b dvmCheckBefore @ (dPC,dFP,self) tail call 10815 10816 /* ------------------------------ */ 10817 .balign 64 10818 .L_ALT_OP_CMP_LONG: /* 0x31 */ 10819 /* File: armv5te/alt_stub.S */ 10820 /* 10821 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10822 * any interesting requests and then jump to the real instruction 10823 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10824 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10825 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10826 * bail to the real handler if breakFlags==0. 10827 */ 10828 ldrb r3, [rSELF, #offThread_breakFlags] 10829 adrl lr, dvmAsmInstructionStart + (49 * 64) 10830 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10831 cmp r3, #0 10832 bxeq lr @ nothing to do - jump to real handler 10833 EXPORT_PC() 10834 mov r0, rPC @ arg0 10835 mov r1, rFP @ arg1 10836 mov r2, rSELF @ arg2 10837 b dvmCheckBefore @ (dPC,dFP,self) tail call 10838 10839 /* ------------------------------ */ 10840 .balign 64 10841 .L_ALT_OP_IF_EQ: /* 0x32 */ 10842 /* File: armv5te/alt_stub.S */ 10843 /* 10844 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10845 * any interesting requests and then jump to the real instruction 10846 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10847 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10848 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10849 * bail to the real handler if breakFlags==0. 10850 */ 10851 ldrb r3, [rSELF, #offThread_breakFlags] 10852 adrl lr, dvmAsmInstructionStart + (50 * 64) 10853 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10854 cmp r3, #0 10855 bxeq lr @ nothing to do - jump to real handler 10856 EXPORT_PC() 10857 mov r0, rPC @ arg0 10858 mov r1, rFP @ arg1 10859 mov r2, rSELF @ arg2 10860 b dvmCheckBefore @ (dPC,dFP,self) tail call 10861 10862 /* ------------------------------ */ 10863 .balign 64 10864 .L_ALT_OP_IF_NE: /* 0x33 */ 10865 /* File: armv5te/alt_stub.S */ 10866 /* 10867 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10868 * any interesting requests and then jump to the real instruction 10869 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10870 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10871 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10872 * bail to the real handler if breakFlags==0. 10873 */ 10874 ldrb r3, [rSELF, #offThread_breakFlags] 10875 adrl lr, dvmAsmInstructionStart + (51 * 64) 10876 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10877 cmp r3, #0 10878 bxeq lr @ nothing to do - jump to real handler 10879 EXPORT_PC() 10880 mov r0, rPC @ arg0 10881 mov r1, rFP @ arg1 10882 mov r2, rSELF @ arg2 10883 b dvmCheckBefore @ (dPC,dFP,self) tail call 10884 10885 /* ------------------------------ */ 10886 .balign 64 10887 .L_ALT_OP_IF_LT: /* 0x34 */ 10888 /* File: armv5te/alt_stub.S */ 10889 /* 10890 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10891 * any interesting requests and then jump to the real instruction 10892 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10893 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10894 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10895 * bail to the real handler if breakFlags==0. 10896 */ 10897 ldrb r3, [rSELF, #offThread_breakFlags] 10898 adrl lr, dvmAsmInstructionStart + (52 * 64) 10899 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10900 cmp r3, #0 10901 bxeq lr @ nothing to do - jump to real handler 10902 EXPORT_PC() 10903 mov r0, rPC @ arg0 10904 mov r1, rFP @ arg1 10905 mov r2, rSELF @ arg2 10906 b dvmCheckBefore @ (dPC,dFP,self) tail call 10907 10908 /* ------------------------------ */ 10909 .balign 64 10910 .L_ALT_OP_IF_GE: /* 0x35 */ 10911 /* File: armv5te/alt_stub.S */ 10912 /* 10913 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10914 * any interesting requests and then jump to the real instruction 10915 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10916 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10917 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10918 * bail to the real handler if breakFlags==0. 10919 */ 10920 ldrb r3, [rSELF, #offThread_breakFlags] 10921 adrl lr, dvmAsmInstructionStart + (53 * 64) 10922 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10923 cmp r3, #0 10924 bxeq lr @ nothing to do - jump to real handler 10925 EXPORT_PC() 10926 mov r0, rPC @ arg0 10927 mov r1, rFP @ arg1 10928 mov r2, rSELF @ arg2 10929 b dvmCheckBefore @ (dPC,dFP,self) tail call 10930 10931 /* ------------------------------ */ 10932 .balign 64 10933 .L_ALT_OP_IF_GT: /* 0x36 */ 10934 /* File: armv5te/alt_stub.S */ 10935 /* 10936 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10937 * any interesting requests and then jump to the real instruction 10938 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10939 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10940 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10941 * bail to the real handler if breakFlags==0. 10942 */ 10943 ldrb r3, [rSELF, #offThread_breakFlags] 10944 adrl lr, dvmAsmInstructionStart + (54 * 64) 10945 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10946 cmp r3, #0 10947 bxeq lr @ nothing to do - jump to real handler 10948 EXPORT_PC() 10949 mov r0, rPC @ arg0 10950 mov r1, rFP @ arg1 10951 mov r2, rSELF @ arg2 10952 b dvmCheckBefore @ (dPC,dFP,self) tail call 10953 10954 /* ------------------------------ */ 10955 .balign 64 10956 .L_ALT_OP_IF_LE: /* 0x37 */ 10957 /* File: armv5te/alt_stub.S */ 10958 /* 10959 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10960 * any interesting requests and then jump to the real instruction 10961 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10962 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10963 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10964 * bail to the real handler if breakFlags==0. 10965 */ 10966 ldrb r3, [rSELF, #offThread_breakFlags] 10967 adrl lr, dvmAsmInstructionStart + (55 * 64) 10968 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10969 cmp r3, #0 10970 bxeq lr @ nothing to do - jump to real handler 10971 EXPORT_PC() 10972 mov r0, rPC @ arg0 10973 mov r1, rFP @ arg1 10974 mov r2, rSELF @ arg2 10975 b dvmCheckBefore @ (dPC,dFP,self) tail call 10976 10977 /* ------------------------------ */ 10978 .balign 64 10979 .L_ALT_OP_IF_EQZ: /* 0x38 */ 10980 /* File: armv5te/alt_stub.S */ 10981 /* 10982 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10983 * any interesting requests and then jump to the real instruction 10984 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10985 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10986 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10987 * bail to the real handler if breakFlags==0. 10988 */ 10989 ldrb r3, [rSELF, #offThread_breakFlags] 10990 adrl lr, dvmAsmInstructionStart + (56 * 64) 10991 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10992 cmp r3, #0 10993 bxeq lr @ nothing to do - jump to real handler 10994 EXPORT_PC() 10995 mov r0, rPC @ arg0 10996 mov r1, rFP @ arg1 10997 mov r2, rSELF @ arg2 10998 b dvmCheckBefore @ (dPC,dFP,self) tail call 10999 11000 /* ------------------------------ */ 11001 .balign 64 11002 .L_ALT_OP_IF_NEZ: /* 0x39 */ 11003 /* File: armv5te/alt_stub.S */ 11004 /* 11005 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11006 * any interesting requests and then jump to the real instruction 11007 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11008 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11009 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11010 * bail to the real handler if breakFlags==0. 11011 */ 11012 ldrb r3, [rSELF, #offThread_breakFlags] 11013 adrl lr, dvmAsmInstructionStart + (57 * 64) 11014 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11015 cmp r3, #0 11016 bxeq lr @ nothing to do - jump to real handler 11017 EXPORT_PC() 11018 mov r0, rPC @ arg0 11019 mov r1, rFP @ arg1 11020 mov r2, rSELF @ arg2 11021 b dvmCheckBefore @ (dPC,dFP,self) tail call 11022 11023 /* ------------------------------ */ 11024 .balign 64 11025 .L_ALT_OP_IF_LTZ: /* 0x3a */ 11026 /* File: armv5te/alt_stub.S */ 11027 /* 11028 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11029 * any interesting requests and then jump to the real instruction 11030 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11031 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11032 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11033 * bail to the real handler if breakFlags==0. 11034 */ 11035 ldrb r3, [rSELF, #offThread_breakFlags] 11036 adrl lr, dvmAsmInstructionStart + (58 * 64) 11037 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11038 cmp r3, #0 11039 bxeq lr @ nothing to do - jump to real handler 11040 EXPORT_PC() 11041 mov r0, rPC @ arg0 11042 mov r1, rFP @ arg1 11043 mov r2, rSELF @ arg2 11044 b dvmCheckBefore @ (dPC,dFP,self) tail call 11045 11046 /* ------------------------------ */ 11047 .balign 64 11048 .L_ALT_OP_IF_GEZ: /* 0x3b */ 11049 /* File: armv5te/alt_stub.S */ 11050 /* 11051 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11052 * any interesting requests and then jump to the real instruction 11053 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11054 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11055 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11056 * bail to the real handler if breakFlags==0. 11057 */ 11058 ldrb r3, [rSELF, #offThread_breakFlags] 11059 adrl lr, dvmAsmInstructionStart + (59 * 64) 11060 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11061 cmp r3, #0 11062 bxeq lr @ nothing to do - jump to real handler 11063 EXPORT_PC() 11064 mov r0, rPC @ arg0 11065 mov r1, rFP @ arg1 11066 mov r2, rSELF @ arg2 11067 b dvmCheckBefore @ (dPC,dFP,self) tail call 11068 11069 /* ------------------------------ */ 11070 .balign 64 11071 .L_ALT_OP_IF_GTZ: /* 0x3c */ 11072 /* File: armv5te/alt_stub.S */ 11073 /* 11074 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11075 * any interesting requests and then jump to the real instruction 11076 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11077 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11078 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11079 * bail to the real handler if breakFlags==0. 11080 */ 11081 ldrb r3, [rSELF, #offThread_breakFlags] 11082 adrl lr, dvmAsmInstructionStart + (60 * 64) 11083 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11084 cmp r3, #0 11085 bxeq lr @ nothing to do - jump to real handler 11086 EXPORT_PC() 11087 mov r0, rPC @ arg0 11088 mov r1, rFP @ arg1 11089 mov r2, rSELF @ arg2 11090 b dvmCheckBefore @ (dPC,dFP,self) tail call 11091 11092 /* ------------------------------ */ 11093 .balign 64 11094 .L_ALT_OP_IF_LEZ: /* 0x3d */ 11095 /* File: armv5te/alt_stub.S */ 11096 /* 11097 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11098 * any interesting requests and then jump to the real instruction 11099 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11100 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11101 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11102 * bail to the real handler if breakFlags==0. 11103 */ 11104 ldrb r3, [rSELF, #offThread_breakFlags] 11105 adrl lr, dvmAsmInstructionStart + (61 * 64) 11106 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11107 cmp r3, #0 11108 bxeq lr @ nothing to do - jump to real handler 11109 EXPORT_PC() 11110 mov r0, rPC @ arg0 11111 mov r1, rFP @ arg1 11112 mov r2, rSELF @ arg2 11113 b dvmCheckBefore @ (dPC,dFP,self) tail call 11114 11115 /* ------------------------------ */ 11116 .balign 64 11117 .L_ALT_OP_UNUSED_3E: /* 0x3e */ 11118 /* File: armv5te/alt_stub.S */ 11119 /* 11120 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11121 * any interesting requests and then jump to the real instruction 11122 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11123 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11124 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11125 * bail to the real handler if breakFlags==0. 11126 */ 11127 ldrb r3, [rSELF, #offThread_breakFlags] 11128 adrl lr, dvmAsmInstructionStart + (62 * 64) 11129 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11130 cmp r3, #0 11131 bxeq lr @ nothing to do - jump to real handler 11132 EXPORT_PC() 11133 mov r0, rPC @ arg0 11134 mov r1, rFP @ arg1 11135 mov r2, rSELF @ arg2 11136 b dvmCheckBefore @ (dPC,dFP,self) tail call 11137 11138 /* ------------------------------ */ 11139 .balign 64 11140 .L_ALT_OP_UNUSED_3F: /* 0x3f */ 11141 /* File: armv5te/alt_stub.S */ 11142 /* 11143 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11144 * any interesting requests and then jump to the real instruction 11145 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11146 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11147 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11148 * bail to the real handler if breakFlags==0. 11149 */ 11150 ldrb r3, [rSELF, #offThread_breakFlags] 11151 adrl lr, dvmAsmInstructionStart + (63 * 64) 11152 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11153 cmp r3, #0 11154 bxeq lr @ nothing to do - jump to real handler 11155 EXPORT_PC() 11156 mov r0, rPC @ arg0 11157 mov r1, rFP @ arg1 11158 mov r2, rSELF @ arg2 11159 b dvmCheckBefore @ (dPC,dFP,self) tail call 11160 11161 /* ------------------------------ */ 11162 .balign 64 11163 .L_ALT_OP_UNUSED_40: /* 0x40 */ 11164 /* File: armv5te/alt_stub.S */ 11165 /* 11166 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11167 * any interesting requests and then jump to the real instruction 11168 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11169 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11170 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11171 * bail to the real handler if breakFlags==0. 11172 */ 11173 ldrb r3, [rSELF, #offThread_breakFlags] 11174 adrl lr, dvmAsmInstructionStart + (64 * 64) 11175 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11176 cmp r3, #0 11177 bxeq lr @ nothing to do - jump to real handler 11178 EXPORT_PC() 11179 mov r0, rPC @ arg0 11180 mov r1, rFP @ arg1 11181 mov r2, rSELF @ arg2 11182 b dvmCheckBefore @ (dPC,dFP,self) tail call 11183 11184 /* ------------------------------ */ 11185 .balign 64 11186 .L_ALT_OP_UNUSED_41: /* 0x41 */ 11187 /* File: armv5te/alt_stub.S */ 11188 /* 11189 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11190 * any interesting requests and then jump to the real instruction 11191 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11192 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11193 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11194 * bail to the real handler if breakFlags==0. 11195 */ 11196 ldrb r3, [rSELF, #offThread_breakFlags] 11197 adrl lr, dvmAsmInstructionStart + (65 * 64) 11198 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11199 cmp r3, #0 11200 bxeq lr @ nothing to do - jump to real handler 11201 EXPORT_PC() 11202 mov r0, rPC @ arg0 11203 mov r1, rFP @ arg1 11204 mov r2, rSELF @ arg2 11205 b dvmCheckBefore @ (dPC,dFP,self) tail call 11206 11207 /* ------------------------------ */ 11208 .balign 64 11209 .L_ALT_OP_UNUSED_42: /* 0x42 */ 11210 /* File: armv5te/alt_stub.S */ 11211 /* 11212 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11213 * any interesting requests and then jump to the real instruction 11214 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11215 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11216 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11217 * bail to the real handler if breakFlags==0. 11218 */ 11219 ldrb r3, [rSELF, #offThread_breakFlags] 11220 adrl lr, dvmAsmInstructionStart + (66 * 64) 11221 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11222 cmp r3, #0 11223 bxeq lr @ nothing to do - jump to real handler 11224 EXPORT_PC() 11225 mov r0, rPC @ arg0 11226 mov r1, rFP @ arg1 11227 mov r2, rSELF @ arg2 11228 b dvmCheckBefore @ (dPC,dFP,self) tail call 11229 11230 /* ------------------------------ */ 11231 .balign 64 11232 .L_ALT_OP_UNUSED_43: /* 0x43 */ 11233 /* File: armv5te/alt_stub.S */ 11234 /* 11235 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11236 * any interesting requests and then jump to the real instruction 11237 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11238 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11239 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11240 * bail to the real handler if breakFlags==0. 11241 */ 11242 ldrb r3, [rSELF, #offThread_breakFlags] 11243 adrl lr, dvmAsmInstructionStart + (67 * 64) 11244 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11245 cmp r3, #0 11246 bxeq lr @ nothing to do - jump to real handler 11247 EXPORT_PC() 11248 mov r0, rPC @ arg0 11249 mov r1, rFP @ arg1 11250 mov r2, rSELF @ arg2 11251 b dvmCheckBefore @ (dPC,dFP,self) tail call 11252 11253 /* ------------------------------ */ 11254 .balign 64 11255 .L_ALT_OP_AGET: /* 0x44 */ 11256 /* File: armv5te/alt_stub.S */ 11257 /* 11258 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11259 * any interesting requests and then jump to the real instruction 11260 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11261 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11262 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11263 * bail to the real handler if breakFlags==0. 11264 */ 11265 ldrb r3, [rSELF, #offThread_breakFlags] 11266 adrl lr, dvmAsmInstructionStart + (68 * 64) 11267 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11268 cmp r3, #0 11269 bxeq lr @ nothing to do - jump to real handler 11270 EXPORT_PC() 11271 mov r0, rPC @ arg0 11272 mov r1, rFP @ arg1 11273 mov r2, rSELF @ arg2 11274 b dvmCheckBefore @ (dPC,dFP,self) tail call 11275 11276 /* ------------------------------ */ 11277 .balign 64 11278 .L_ALT_OP_AGET_WIDE: /* 0x45 */ 11279 /* File: armv5te/alt_stub.S */ 11280 /* 11281 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11282 * any interesting requests and then jump to the real instruction 11283 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11284 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11285 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11286 * bail to the real handler if breakFlags==0. 11287 */ 11288 ldrb r3, [rSELF, #offThread_breakFlags] 11289 adrl lr, dvmAsmInstructionStart + (69 * 64) 11290 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11291 cmp r3, #0 11292 bxeq lr @ nothing to do - jump to real handler 11293 EXPORT_PC() 11294 mov r0, rPC @ arg0 11295 mov r1, rFP @ arg1 11296 mov r2, rSELF @ arg2 11297 b dvmCheckBefore @ (dPC,dFP,self) tail call 11298 11299 /* ------------------------------ */ 11300 .balign 64 11301 .L_ALT_OP_AGET_OBJECT: /* 0x46 */ 11302 /* File: armv5te/alt_stub.S */ 11303 /* 11304 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11305 * any interesting requests and then jump to the real instruction 11306 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11307 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11308 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11309 * bail to the real handler if breakFlags==0. 11310 */ 11311 ldrb r3, [rSELF, #offThread_breakFlags] 11312 adrl lr, dvmAsmInstructionStart + (70 * 64) 11313 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11314 cmp r3, #0 11315 bxeq lr @ nothing to do - jump to real handler 11316 EXPORT_PC() 11317 mov r0, rPC @ arg0 11318 mov r1, rFP @ arg1 11319 mov r2, rSELF @ arg2 11320 b dvmCheckBefore @ (dPC,dFP,self) tail call 11321 11322 /* ------------------------------ */ 11323 .balign 64 11324 .L_ALT_OP_AGET_BOOLEAN: /* 0x47 */ 11325 /* File: armv5te/alt_stub.S */ 11326 /* 11327 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11328 * any interesting requests and then jump to the real instruction 11329 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11330 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11331 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11332 * bail to the real handler if breakFlags==0. 11333 */ 11334 ldrb r3, [rSELF, #offThread_breakFlags] 11335 adrl lr, dvmAsmInstructionStart + (71 * 64) 11336 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11337 cmp r3, #0 11338 bxeq lr @ nothing to do - jump to real handler 11339 EXPORT_PC() 11340 mov r0, rPC @ arg0 11341 mov r1, rFP @ arg1 11342 mov r2, rSELF @ arg2 11343 b dvmCheckBefore @ (dPC,dFP,self) tail call 11344 11345 /* ------------------------------ */ 11346 .balign 64 11347 .L_ALT_OP_AGET_BYTE: /* 0x48 */ 11348 /* File: armv5te/alt_stub.S */ 11349 /* 11350 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11351 * any interesting requests and then jump to the real instruction 11352 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11353 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11354 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11355 * bail to the real handler if breakFlags==0. 11356 */ 11357 ldrb r3, [rSELF, #offThread_breakFlags] 11358 adrl lr, dvmAsmInstructionStart + (72 * 64) 11359 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11360 cmp r3, #0 11361 bxeq lr @ nothing to do - jump to real handler 11362 EXPORT_PC() 11363 mov r0, rPC @ arg0 11364 mov r1, rFP @ arg1 11365 mov r2, rSELF @ arg2 11366 b dvmCheckBefore @ (dPC,dFP,self) tail call 11367 11368 /* ------------------------------ */ 11369 .balign 64 11370 .L_ALT_OP_AGET_CHAR: /* 0x49 */ 11371 /* File: armv5te/alt_stub.S */ 11372 /* 11373 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11374 * any interesting requests and then jump to the real instruction 11375 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11376 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11377 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11378 * bail to the real handler if breakFlags==0. 11379 */ 11380 ldrb r3, [rSELF, #offThread_breakFlags] 11381 adrl lr, dvmAsmInstructionStart + (73 * 64) 11382 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11383 cmp r3, #0 11384 bxeq lr @ nothing to do - jump to real handler 11385 EXPORT_PC() 11386 mov r0, rPC @ arg0 11387 mov r1, rFP @ arg1 11388 mov r2, rSELF @ arg2 11389 b dvmCheckBefore @ (dPC,dFP,self) tail call 11390 11391 /* ------------------------------ */ 11392 .balign 64 11393 .L_ALT_OP_AGET_SHORT: /* 0x4a */ 11394 /* File: armv5te/alt_stub.S */ 11395 /* 11396 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11397 * any interesting requests and then jump to the real instruction 11398 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11399 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11400 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11401 * bail to the real handler if breakFlags==0. 11402 */ 11403 ldrb r3, [rSELF, #offThread_breakFlags] 11404 adrl lr, dvmAsmInstructionStart + (74 * 64) 11405 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11406 cmp r3, #0 11407 bxeq lr @ nothing to do - jump to real handler 11408 EXPORT_PC() 11409 mov r0, rPC @ arg0 11410 mov r1, rFP @ arg1 11411 mov r2, rSELF @ arg2 11412 b dvmCheckBefore @ (dPC,dFP,self) tail call 11413 11414 /* ------------------------------ */ 11415 .balign 64 11416 .L_ALT_OP_APUT: /* 0x4b */ 11417 /* File: armv5te/alt_stub.S */ 11418 /* 11419 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11420 * any interesting requests and then jump to the real instruction 11421 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11422 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11423 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11424 * bail to the real handler if breakFlags==0. 11425 */ 11426 ldrb r3, [rSELF, #offThread_breakFlags] 11427 adrl lr, dvmAsmInstructionStart + (75 * 64) 11428 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11429 cmp r3, #0 11430 bxeq lr @ nothing to do - jump to real handler 11431 EXPORT_PC() 11432 mov r0, rPC @ arg0 11433 mov r1, rFP @ arg1 11434 mov r2, rSELF @ arg2 11435 b dvmCheckBefore @ (dPC,dFP,self) tail call 11436 11437 /* ------------------------------ */ 11438 .balign 64 11439 .L_ALT_OP_APUT_WIDE: /* 0x4c */ 11440 /* File: armv5te/alt_stub.S */ 11441 /* 11442 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11443 * any interesting requests and then jump to the real instruction 11444 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11445 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11446 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11447 * bail to the real handler if breakFlags==0. 11448 */ 11449 ldrb r3, [rSELF, #offThread_breakFlags] 11450 adrl lr, dvmAsmInstructionStart + (76 * 64) 11451 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11452 cmp r3, #0 11453 bxeq lr @ nothing to do - jump to real handler 11454 EXPORT_PC() 11455 mov r0, rPC @ arg0 11456 mov r1, rFP @ arg1 11457 mov r2, rSELF @ arg2 11458 b dvmCheckBefore @ (dPC,dFP,self) tail call 11459 11460 /* ------------------------------ */ 11461 .balign 64 11462 .L_ALT_OP_APUT_OBJECT: /* 0x4d */ 11463 /* File: armv5te/alt_stub.S */ 11464 /* 11465 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11466 * any interesting requests and then jump to the real instruction 11467 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11468 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11469 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11470 * bail to the real handler if breakFlags==0. 11471 */ 11472 ldrb r3, [rSELF, #offThread_breakFlags] 11473 adrl lr, dvmAsmInstructionStart + (77 * 64) 11474 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11475 cmp r3, #0 11476 bxeq lr @ nothing to do - jump to real handler 11477 EXPORT_PC() 11478 mov r0, rPC @ arg0 11479 mov r1, rFP @ arg1 11480 mov r2, rSELF @ arg2 11481 b dvmCheckBefore @ (dPC,dFP,self) tail call 11482 11483 /* ------------------------------ */ 11484 .balign 64 11485 .L_ALT_OP_APUT_BOOLEAN: /* 0x4e */ 11486 /* File: armv5te/alt_stub.S */ 11487 /* 11488 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11489 * any interesting requests and then jump to the real instruction 11490 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11491 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11492 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11493 * bail to the real handler if breakFlags==0. 11494 */ 11495 ldrb r3, [rSELF, #offThread_breakFlags] 11496 adrl lr, dvmAsmInstructionStart + (78 * 64) 11497 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11498 cmp r3, #0 11499 bxeq lr @ nothing to do - jump to real handler 11500 EXPORT_PC() 11501 mov r0, rPC @ arg0 11502 mov r1, rFP @ arg1 11503 mov r2, rSELF @ arg2 11504 b dvmCheckBefore @ (dPC,dFP,self) tail call 11505 11506 /* ------------------------------ */ 11507 .balign 64 11508 .L_ALT_OP_APUT_BYTE: /* 0x4f */ 11509 /* File: armv5te/alt_stub.S */ 11510 /* 11511 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11512 * any interesting requests and then jump to the real instruction 11513 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11514 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11515 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11516 * bail to the real handler if breakFlags==0. 11517 */ 11518 ldrb r3, [rSELF, #offThread_breakFlags] 11519 adrl lr, dvmAsmInstructionStart + (79 * 64) 11520 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11521 cmp r3, #0 11522 bxeq lr @ nothing to do - jump to real handler 11523 EXPORT_PC() 11524 mov r0, rPC @ arg0 11525 mov r1, rFP @ arg1 11526 mov r2, rSELF @ arg2 11527 b dvmCheckBefore @ (dPC,dFP,self) tail call 11528 11529 /* ------------------------------ */ 11530 .balign 64 11531 .L_ALT_OP_APUT_CHAR: /* 0x50 */ 11532 /* File: armv5te/alt_stub.S */ 11533 /* 11534 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11535 * any interesting requests and then jump to the real instruction 11536 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11537 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11538 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11539 * bail to the real handler if breakFlags==0. 11540 */ 11541 ldrb r3, [rSELF, #offThread_breakFlags] 11542 adrl lr, dvmAsmInstructionStart + (80 * 64) 11543 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11544 cmp r3, #0 11545 bxeq lr @ nothing to do - jump to real handler 11546 EXPORT_PC() 11547 mov r0, rPC @ arg0 11548 mov r1, rFP @ arg1 11549 mov r2, rSELF @ arg2 11550 b dvmCheckBefore @ (dPC,dFP,self) tail call 11551 11552 /* ------------------------------ */ 11553 .balign 64 11554 .L_ALT_OP_APUT_SHORT: /* 0x51 */ 11555 /* File: armv5te/alt_stub.S */ 11556 /* 11557 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11558 * any interesting requests and then jump to the real instruction 11559 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11560 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11561 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11562 * bail to the real handler if breakFlags==0. 11563 */ 11564 ldrb r3, [rSELF, #offThread_breakFlags] 11565 adrl lr, dvmAsmInstructionStart + (81 * 64) 11566 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11567 cmp r3, #0 11568 bxeq lr @ nothing to do - jump to real handler 11569 EXPORT_PC() 11570 mov r0, rPC @ arg0 11571 mov r1, rFP @ arg1 11572 mov r2, rSELF @ arg2 11573 b dvmCheckBefore @ (dPC,dFP,self) tail call 11574 11575 /* ------------------------------ */ 11576 .balign 64 11577 .L_ALT_OP_IGET: /* 0x52 */ 11578 /* File: armv5te/alt_stub.S */ 11579 /* 11580 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11581 * any interesting requests and then jump to the real instruction 11582 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11583 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11584 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11585 * bail to the real handler if breakFlags==0. 11586 */ 11587 ldrb r3, [rSELF, #offThread_breakFlags] 11588 adrl lr, dvmAsmInstructionStart + (82 * 64) 11589 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11590 cmp r3, #0 11591 bxeq lr @ nothing to do - jump to real handler 11592 EXPORT_PC() 11593 mov r0, rPC @ arg0 11594 mov r1, rFP @ arg1 11595 mov r2, rSELF @ arg2 11596 b dvmCheckBefore @ (dPC,dFP,self) tail call 11597 11598 /* ------------------------------ */ 11599 .balign 64 11600 .L_ALT_OP_IGET_WIDE: /* 0x53 */ 11601 /* File: armv5te/alt_stub.S */ 11602 /* 11603 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11604 * any interesting requests and then jump to the real instruction 11605 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11606 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11607 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11608 * bail to the real handler if breakFlags==0. 11609 */ 11610 ldrb r3, [rSELF, #offThread_breakFlags] 11611 adrl lr, dvmAsmInstructionStart + (83 * 64) 11612 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11613 cmp r3, #0 11614 bxeq lr @ nothing to do - jump to real handler 11615 EXPORT_PC() 11616 mov r0, rPC @ arg0 11617 mov r1, rFP @ arg1 11618 mov r2, rSELF @ arg2 11619 b dvmCheckBefore @ (dPC,dFP,self) tail call 11620 11621 /* ------------------------------ */ 11622 .balign 64 11623 .L_ALT_OP_IGET_OBJECT: /* 0x54 */ 11624 /* File: armv5te/alt_stub.S */ 11625 /* 11626 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11627 * any interesting requests and then jump to the real instruction 11628 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11629 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11630 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11631 * bail to the real handler if breakFlags==0. 11632 */ 11633 ldrb r3, [rSELF, #offThread_breakFlags] 11634 adrl lr, dvmAsmInstructionStart + (84 * 64) 11635 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11636 cmp r3, #0 11637 bxeq lr @ nothing to do - jump to real handler 11638 EXPORT_PC() 11639 mov r0, rPC @ arg0 11640 mov r1, rFP @ arg1 11641 mov r2, rSELF @ arg2 11642 b dvmCheckBefore @ (dPC,dFP,self) tail call 11643 11644 /* ------------------------------ */ 11645 .balign 64 11646 .L_ALT_OP_IGET_BOOLEAN: /* 0x55 */ 11647 /* File: armv5te/alt_stub.S */ 11648 /* 11649 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11650 * any interesting requests and then jump to the real instruction 11651 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11652 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11653 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11654 * bail to the real handler if breakFlags==0. 11655 */ 11656 ldrb r3, [rSELF, #offThread_breakFlags] 11657 adrl lr, dvmAsmInstructionStart + (85 * 64) 11658 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11659 cmp r3, #0 11660 bxeq lr @ nothing to do - jump to real handler 11661 EXPORT_PC() 11662 mov r0, rPC @ arg0 11663 mov r1, rFP @ arg1 11664 mov r2, rSELF @ arg2 11665 b dvmCheckBefore @ (dPC,dFP,self) tail call 11666 11667 /* ------------------------------ */ 11668 .balign 64 11669 .L_ALT_OP_IGET_BYTE: /* 0x56 */ 11670 /* File: armv5te/alt_stub.S */ 11671 /* 11672 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11673 * any interesting requests and then jump to the real instruction 11674 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11675 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11676 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11677 * bail to the real handler if breakFlags==0. 11678 */ 11679 ldrb r3, [rSELF, #offThread_breakFlags] 11680 adrl lr, dvmAsmInstructionStart + (86 * 64) 11681 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11682 cmp r3, #0 11683 bxeq lr @ nothing to do - jump to real handler 11684 EXPORT_PC() 11685 mov r0, rPC @ arg0 11686 mov r1, rFP @ arg1 11687 mov r2, rSELF @ arg2 11688 b dvmCheckBefore @ (dPC,dFP,self) tail call 11689 11690 /* ------------------------------ */ 11691 .balign 64 11692 .L_ALT_OP_IGET_CHAR: /* 0x57 */ 11693 /* File: armv5te/alt_stub.S */ 11694 /* 11695 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11696 * any interesting requests and then jump to the real instruction 11697 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11698 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11699 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11700 * bail to the real handler if breakFlags==0. 11701 */ 11702 ldrb r3, [rSELF, #offThread_breakFlags] 11703 adrl lr, dvmAsmInstructionStart + (87 * 64) 11704 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11705 cmp r3, #0 11706 bxeq lr @ nothing to do - jump to real handler 11707 EXPORT_PC() 11708 mov r0, rPC @ arg0 11709 mov r1, rFP @ arg1 11710 mov r2, rSELF @ arg2 11711 b dvmCheckBefore @ (dPC,dFP,self) tail call 11712 11713 /* ------------------------------ */ 11714 .balign 64 11715 .L_ALT_OP_IGET_SHORT: /* 0x58 */ 11716 /* File: armv5te/alt_stub.S */ 11717 /* 11718 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11719 * any interesting requests and then jump to the real instruction 11720 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11721 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11722 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11723 * bail to the real handler if breakFlags==0. 11724 */ 11725 ldrb r3, [rSELF, #offThread_breakFlags] 11726 adrl lr, dvmAsmInstructionStart + (88 * 64) 11727 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11728 cmp r3, #0 11729 bxeq lr @ nothing to do - jump to real handler 11730 EXPORT_PC() 11731 mov r0, rPC @ arg0 11732 mov r1, rFP @ arg1 11733 mov r2, rSELF @ arg2 11734 b dvmCheckBefore @ (dPC,dFP,self) tail call 11735 11736 /* ------------------------------ */ 11737 .balign 64 11738 .L_ALT_OP_IPUT: /* 0x59 */ 11739 /* File: armv5te/alt_stub.S */ 11740 /* 11741 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11742 * any interesting requests and then jump to the real instruction 11743 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11744 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11745 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11746 * bail to the real handler if breakFlags==0. 11747 */ 11748 ldrb r3, [rSELF, #offThread_breakFlags] 11749 adrl lr, dvmAsmInstructionStart + (89 * 64) 11750 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11751 cmp r3, #0 11752 bxeq lr @ nothing to do - jump to real handler 11753 EXPORT_PC() 11754 mov r0, rPC @ arg0 11755 mov r1, rFP @ arg1 11756 mov r2, rSELF @ arg2 11757 b dvmCheckBefore @ (dPC,dFP,self) tail call 11758 11759 /* ------------------------------ */ 11760 .balign 64 11761 .L_ALT_OP_IPUT_WIDE: /* 0x5a */ 11762 /* File: armv5te/alt_stub.S */ 11763 /* 11764 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11765 * any interesting requests and then jump to the real instruction 11766 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11767 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11768 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11769 * bail to the real handler if breakFlags==0. 11770 */ 11771 ldrb r3, [rSELF, #offThread_breakFlags] 11772 adrl lr, dvmAsmInstructionStart + (90 * 64) 11773 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11774 cmp r3, #0 11775 bxeq lr @ nothing to do - jump to real handler 11776 EXPORT_PC() 11777 mov r0, rPC @ arg0 11778 mov r1, rFP @ arg1 11779 mov r2, rSELF @ arg2 11780 b dvmCheckBefore @ (dPC,dFP,self) tail call 11781 11782 /* ------------------------------ */ 11783 .balign 64 11784 .L_ALT_OP_IPUT_OBJECT: /* 0x5b */ 11785 /* File: armv5te/alt_stub.S */ 11786 /* 11787 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11788 * any interesting requests and then jump to the real instruction 11789 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11790 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11791 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11792 * bail to the real handler if breakFlags==0. 11793 */ 11794 ldrb r3, [rSELF, #offThread_breakFlags] 11795 adrl lr, dvmAsmInstructionStart + (91 * 64) 11796 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11797 cmp r3, #0 11798 bxeq lr @ nothing to do - jump to real handler 11799 EXPORT_PC() 11800 mov r0, rPC @ arg0 11801 mov r1, rFP @ arg1 11802 mov r2, rSELF @ arg2 11803 b dvmCheckBefore @ (dPC,dFP,self) tail call 11804 11805 /* ------------------------------ */ 11806 .balign 64 11807 .L_ALT_OP_IPUT_BOOLEAN: /* 0x5c */ 11808 /* File: armv5te/alt_stub.S */ 11809 /* 11810 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11811 * any interesting requests and then jump to the real instruction 11812 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11813 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11814 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11815 * bail to the real handler if breakFlags==0. 11816 */ 11817 ldrb r3, [rSELF, #offThread_breakFlags] 11818 adrl lr, dvmAsmInstructionStart + (92 * 64) 11819 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11820 cmp r3, #0 11821 bxeq lr @ nothing to do - jump to real handler 11822 EXPORT_PC() 11823 mov r0, rPC @ arg0 11824 mov r1, rFP @ arg1 11825 mov r2, rSELF @ arg2 11826 b dvmCheckBefore @ (dPC,dFP,self) tail call 11827 11828 /* ------------------------------ */ 11829 .balign 64 11830 .L_ALT_OP_IPUT_BYTE: /* 0x5d */ 11831 /* File: armv5te/alt_stub.S */ 11832 /* 11833 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11834 * any interesting requests and then jump to the real instruction 11835 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11836 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11837 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11838 * bail to the real handler if breakFlags==0. 11839 */ 11840 ldrb r3, [rSELF, #offThread_breakFlags] 11841 adrl lr, dvmAsmInstructionStart + (93 * 64) 11842 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11843 cmp r3, #0 11844 bxeq lr @ nothing to do - jump to real handler 11845 EXPORT_PC() 11846 mov r0, rPC @ arg0 11847 mov r1, rFP @ arg1 11848 mov r2, rSELF @ arg2 11849 b dvmCheckBefore @ (dPC,dFP,self) tail call 11850 11851 /* ------------------------------ */ 11852 .balign 64 11853 .L_ALT_OP_IPUT_CHAR: /* 0x5e */ 11854 /* File: armv5te/alt_stub.S */ 11855 /* 11856 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11857 * any interesting requests and then jump to the real instruction 11858 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11859 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11860 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11861 * bail to the real handler if breakFlags==0. 11862 */ 11863 ldrb r3, [rSELF, #offThread_breakFlags] 11864 adrl lr, dvmAsmInstructionStart + (94 * 64) 11865 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11866 cmp r3, #0 11867 bxeq lr @ nothing to do - jump to real handler 11868 EXPORT_PC() 11869 mov r0, rPC @ arg0 11870 mov r1, rFP @ arg1 11871 mov r2, rSELF @ arg2 11872 b dvmCheckBefore @ (dPC,dFP,self) tail call 11873 11874 /* ------------------------------ */ 11875 .balign 64 11876 .L_ALT_OP_IPUT_SHORT: /* 0x5f */ 11877 /* File: armv5te/alt_stub.S */ 11878 /* 11879 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11880 * any interesting requests and then jump to the real instruction 11881 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11882 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11883 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11884 * bail to the real handler if breakFlags==0. 11885 */ 11886 ldrb r3, [rSELF, #offThread_breakFlags] 11887 adrl lr, dvmAsmInstructionStart + (95 * 64) 11888 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11889 cmp r3, #0 11890 bxeq lr @ nothing to do - jump to real handler 11891 EXPORT_PC() 11892 mov r0, rPC @ arg0 11893 mov r1, rFP @ arg1 11894 mov r2, rSELF @ arg2 11895 b dvmCheckBefore @ (dPC,dFP,self) tail call 11896 11897 /* ------------------------------ */ 11898 .balign 64 11899 .L_ALT_OP_SGET: /* 0x60 */ 11900 /* File: armv5te/alt_stub.S */ 11901 /* 11902 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11903 * any interesting requests and then jump to the real instruction 11904 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11905 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11906 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11907 * bail to the real handler if breakFlags==0. 11908 */ 11909 ldrb r3, [rSELF, #offThread_breakFlags] 11910 adrl lr, dvmAsmInstructionStart + (96 * 64) 11911 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11912 cmp r3, #0 11913 bxeq lr @ nothing to do - jump to real handler 11914 EXPORT_PC() 11915 mov r0, rPC @ arg0 11916 mov r1, rFP @ arg1 11917 mov r2, rSELF @ arg2 11918 b dvmCheckBefore @ (dPC,dFP,self) tail call 11919 11920 /* ------------------------------ */ 11921 .balign 64 11922 .L_ALT_OP_SGET_WIDE: /* 0x61 */ 11923 /* File: armv5te/alt_stub.S */ 11924 /* 11925 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11926 * any interesting requests and then jump to the real instruction 11927 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11928 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11929 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11930 * bail to the real handler if breakFlags==0. 11931 */ 11932 ldrb r3, [rSELF, #offThread_breakFlags] 11933 adrl lr, dvmAsmInstructionStart + (97 * 64) 11934 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11935 cmp r3, #0 11936 bxeq lr @ nothing to do - jump to real handler 11937 EXPORT_PC() 11938 mov r0, rPC @ arg0 11939 mov r1, rFP @ arg1 11940 mov r2, rSELF @ arg2 11941 b dvmCheckBefore @ (dPC,dFP,self) tail call 11942 11943 /* ------------------------------ */ 11944 .balign 64 11945 .L_ALT_OP_SGET_OBJECT: /* 0x62 */ 11946 /* File: armv5te/alt_stub.S */ 11947 /* 11948 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11949 * any interesting requests and then jump to the real instruction 11950 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11951 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11952 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11953 * bail to the real handler if breakFlags==0. 11954 */ 11955 ldrb r3, [rSELF, #offThread_breakFlags] 11956 adrl lr, dvmAsmInstructionStart + (98 * 64) 11957 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11958 cmp r3, #0 11959 bxeq lr @ nothing to do - jump to real handler 11960 EXPORT_PC() 11961 mov r0, rPC @ arg0 11962 mov r1, rFP @ arg1 11963 mov r2, rSELF @ arg2 11964 b dvmCheckBefore @ (dPC,dFP,self) tail call 11965 11966 /* ------------------------------ */ 11967 .balign 64 11968 .L_ALT_OP_SGET_BOOLEAN: /* 0x63 */ 11969 /* File: armv5te/alt_stub.S */ 11970 /* 11971 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11972 * any interesting requests and then jump to the real instruction 11973 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11974 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11975 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11976 * bail to the real handler if breakFlags==0. 11977 */ 11978 ldrb r3, [rSELF, #offThread_breakFlags] 11979 adrl lr, dvmAsmInstructionStart + (99 * 64) 11980 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11981 cmp r3, #0 11982 bxeq lr @ nothing to do - jump to real handler 11983 EXPORT_PC() 11984 mov r0, rPC @ arg0 11985 mov r1, rFP @ arg1 11986 mov r2, rSELF @ arg2 11987 b dvmCheckBefore @ (dPC,dFP,self) tail call 11988 11989 /* ------------------------------ */ 11990 .balign 64 11991 .L_ALT_OP_SGET_BYTE: /* 0x64 */ 11992 /* File: armv5te/alt_stub.S */ 11993 /* 11994 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11995 * any interesting requests and then jump to the real instruction 11996 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11997 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11998 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11999 * bail to the real handler if breakFlags==0. 12000 */ 12001 ldrb r3, [rSELF, #offThread_breakFlags] 12002 adrl lr, dvmAsmInstructionStart + (100 * 64) 12003 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12004 cmp r3, #0 12005 bxeq lr @ nothing to do - jump to real handler 12006 EXPORT_PC() 12007 mov r0, rPC @ arg0 12008 mov r1, rFP @ arg1 12009 mov r2, rSELF @ arg2 12010 b dvmCheckBefore @ (dPC,dFP,self) tail call 12011 12012 /* ------------------------------ */ 12013 .balign 64 12014 .L_ALT_OP_SGET_CHAR: /* 0x65 */ 12015 /* File: armv5te/alt_stub.S */ 12016 /* 12017 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12018 * any interesting requests and then jump to the real instruction 12019 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12020 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12021 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12022 * bail to the real handler if breakFlags==0. 12023 */ 12024 ldrb r3, [rSELF, #offThread_breakFlags] 12025 adrl lr, dvmAsmInstructionStart + (101 * 64) 12026 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12027 cmp r3, #0 12028 bxeq lr @ nothing to do - jump to real handler 12029 EXPORT_PC() 12030 mov r0, rPC @ arg0 12031 mov r1, rFP @ arg1 12032 mov r2, rSELF @ arg2 12033 b dvmCheckBefore @ (dPC,dFP,self) tail call 12034 12035 /* ------------------------------ */ 12036 .balign 64 12037 .L_ALT_OP_SGET_SHORT: /* 0x66 */ 12038 /* File: armv5te/alt_stub.S */ 12039 /* 12040 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12041 * any interesting requests and then jump to the real instruction 12042 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12043 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12044 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12045 * bail to the real handler if breakFlags==0. 12046 */ 12047 ldrb r3, [rSELF, #offThread_breakFlags] 12048 adrl lr, dvmAsmInstructionStart + (102 * 64) 12049 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12050 cmp r3, #0 12051 bxeq lr @ nothing to do - jump to real handler 12052 EXPORT_PC() 12053 mov r0, rPC @ arg0 12054 mov r1, rFP @ arg1 12055 mov r2, rSELF @ arg2 12056 b dvmCheckBefore @ (dPC,dFP,self) tail call 12057 12058 /* ------------------------------ */ 12059 .balign 64 12060 .L_ALT_OP_SPUT: /* 0x67 */ 12061 /* File: armv5te/alt_stub.S */ 12062 /* 12063 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12064 * any interesting requests and then jump to the real instruction 12065 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12066 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12067 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12068 * bail to the real handler if breakFlags==0. 12069 */ 12070 ldrb r3, [rSELF, #offThread_breakFlags] 12071 adrl lr, dvmAsmInstructionStart + (103 * 64) 12072 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12073 cmp r3, #0 12074 bxeq lr @ nothing to do - jump to real handler 12075 EXPORT_PC() 12076 mov r0, rPC @ arg0 12077 mov r1, rFP @ arg1 12078 mov r2, rSELF @ arg2 12079 b dvmCheckBefore @ (dPC,dFP,self) tail call 12080 12081 /* ------------------------------ */ 12082 .balign 64 12083 .L_ALT_OP_SPUT_WIDE: /* 0x68 */ 12084 /* File: armv5te/alt_stub.S */ 12085 /* 12086 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12087 * any interesting requests and then jump to the real instruction 12088 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12089 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12090 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12091 * bail to the real handler if breakFlags==0. 12092 */ 12093 ldrb r3, [rSELF, #offThread_breakFlags] 12094 adrl lr, dvmAsmInstructionStart + (104 * 64) 12095 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12096 cmp r3, #0 12097 bxeq lr @ nothing to do - jump to real handler 12098 EXPORT_PC() 12099 mov r0, rPC @ arg0 12100 mov r1, rFP @ arg1 12101 mov r2, rSELF @ arg2 12102 b dvmCheckBefore @ (dPC,dFP,self) tail call 12103 12104 /* ------------------------------ */ 12105 .balign 64 12106 .L_ALT_OP_SPUT_OBJECT: /* 0x69 */ 12107 /* File: armv5te/alt_stub.S */ 12108 /* 12109 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12110 * any interesting requests and then jump to the real instruction 12111 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12112 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12113 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12114 * bail to the real handler if breakFlags==0. 12115 */ 12116 ldrb r3, [rSELF, #offThread_breakFlags] 12117 adrl lr, dvmAsmInstructionStart + (105 * 64) 12118 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12119 cmp r3, #0 12120 bxeq lr @ nothing to do - jump to real handler 12121 EXPORT_PC() 12122 mov r0, rPC @ arg0 12123 mov r1, rFP @ arg1 12124 mov r2, rSELF @ arg2 12125 b dvmCheckBefore @ (dPC,dFP,self) tail call 12126 12127 /* ------------------------------ */ 12128 .balign 64 12129 .L_ALT_OP_SPUT_BOOLEAN: /* 0x6a */ 12130 /* File: armv5te/alt_stub.S */ 12131 /* 12132 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12133 * any interesting requests and then jump to the real instruction 12134 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12135 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12136 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12137 * bail to the real handler if breakFlags==0. 12138 */ 12139 ldrb r3, [rSELF, #offThread_breakFlags] 12140 adrl lr, dvmAsmInstructionStart + (106 * 64) 12141 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12142 cmp r3, #0 12143 bxeq lr @ nothing to do - jump to real handler 12144 EXPORT_PC() 12145 mov r0, rPC @ arg0 12146 mov r1, rFP @ arg1 12147 mov r2, rSELF @ arg2 12148 b dvmCheckBefore @ (dPC,dFP,self) tail call 12149 12150 /* ------------------------------ */ 12151 .balign 64 12152 .L_ALT_OP_SPUT_BYTE: /* 0x6b */ 12153 /* File: armv5te/alt_stub.S */ 12154 /* 12155 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12156 * any interesting requests and then jump to the real instruction 12157 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12158 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12159 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12160 * bail to the real handler if breakFlags==0. 12161 */ 12162 ldrb r3, [rSELF, #offThread_breakFlags] 12163 adrl lr, dvmAsmInstructionStart + (107 * 64) 12164 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12165 cmp r3, #0 12166 bxeq lr @ nothing to do - jump to real handler 12167 EXPORT_PC() 12168 mov r0, rPC @ arg0 12169 mov r1, rFP @ arg1 12170 mov r2, rSELF @ arg2 12171 b dvmCheckBefore @ (dPC,dFP,self) tail call 12172 12173 /* ------------------------------ */ 12174 .balign 64 12175 .L_ALT_OP_SPUT_CHAR: /* 0x6c */ 12176 /* File: armv5te/alt_stub.S */ 12177 /* 12178 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12179 * any interesting requests and then jump to the real instruction 12180 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12181 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12182 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12183 * bail to the real handler if breakFlags==0. 12184 */ 12185 ldrb r3, [rSELF, #offThread_breakFlags] 12186 adrl lr, dvmAsmInstructionStart + (108 * 64) 12187 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12188 cmp r3, #0 12189 bxeq lr @ nothing to do - jump to real handler 12190 EXPORT_PC() 12191 mov r0, rPC @ arg0 12192 mov r1, rFP @ arg1 12193 mov r2, rSELF @ arg2 12194 b dvmCheckBefore @ (dPC,dFP,self) tail call 12195 12196 /* ------------------------------ */ 12197 .balign 64 12198 .L_ALT_OP_SPUT_SHORT: /* 0x6d */ 12199 /* File: armv5te/alt_stub.S */ 12200 /* 12201 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12202 * any interesting requests and then jump to the real instruction 12203 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12204 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12205 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12206 * bail to the real handler if breakFlags==0. 12207 */ 12208 ldrb r3, [rSELF, #offThread_breakFlags] 12209 adrl lr, dvmAsmInstructionStart + (109 * 64) 12210 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12211 cmp r3, #0 12212 bxeq lr @ nothing to do - jump to real handler 12213 EXPORT_PC() 12214 mov r0, rPC @ arg0 12215 mov r1, rFP @ arg1 12216 mov r2, rSELF @ arg2 12217 b dvmCheckBefore @ (dPC,dFP,self) tail call 12218 12219 /* ------------------------------ */ 12220 .balign 64 12221 .L_ALT_OP_INVOKE_VIRTUAL: /* 0x6e */ 12222 /* File: armv5te/alt_stub.S */ 12223 /* 12224 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12225 * any interesting requests and then jump to the real instruction 12226 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12227 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12228 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12229 * bail to the real handler if breakFlags==0. 12230 */ 12231 ldrb r3, [rSELF, #offThread_breakFlags] 12232 adrl lr, dvmAsmInstructionStart + (110 * 64) 12233 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12234 cmp r3, #0 12235 bxeq lr @ nothing to do - jump to real handler 12236 EXPORT_PC() 12237 mov r0, rPC @ arg0 12238 mov r1, rFP @ arg1 12239 mov r2, rSELF @ arg2 12240 b dvmCheckBefore @ (dPC,dFP,self) tail call 12241 12242 /* ------------------------------ */ 12243 .balign 64 12244 .L_ALT_OP_INVOKE_SUPER: /* 0x6f */ 12245 /* File: armv5te/alt_stub.S */ 12246 /* 12247 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12248 * any interesting requests and then jump to the real instruction 12249 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12250 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12251 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12252 * bail to the real handler if breakFlags==0. 12253 */ 12254 ldrb r3, [rSELF, #offThread_breakFlags] 12255 adrl lr, dvmAsmInstructionStart + (111 * 64) 12256 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12257 cmp r3, #0 12258 bxeq lr @ nothing to do - jump to real handler 12259 EXPORT_PC() 12260 mov r0, rPC @ arg0 12261 mov r1, rFP @ arg1 12262 mov r2, rSELF @ arg2 12263 b dvmCheckBefore @ (dPC,dFP,self) tail call 12264 12265 /* ------------------------------ */ 12266 .balign 64 12267 .L_ALT_OP_INVOKE_DIRECT: /* 0x70 */ 12268 /* File: armv5te/alt_stub.S */ 12269 /* 12270 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12271 * any interesting requests and then jump to the real instruction 12272 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12273 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12274 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12275 * bail to the real handler if breakFlags==0. 12276 */ 12277 ldrb r3, [rSELF, #offThread_breakFlags] 12278 adrl lr, dvmAsmInstructionStart + (112 * 64) 12279 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12280 cmp r3, #0 12281 bxeq lr @ nothing to do - jump to real handler 12282 EXPORT_PC() 12283 mov r0, rPC @ arg0 12284 mov r1, rFP @ arg1 12285 mov r2, rSELF @ arg2 12286 b dvmCheckBefore @ (dPC,dFP,self) tail call 12287 12288 /* ------------------------------ */ 12289 .balign 64 12290 .L_ALT_OP_INVOKE_STATIC: /* 0x71 */ 12291 /* File: armv5te/alt_stub.S */ 12292 /* 12293 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12294 * any interesting requests and then jump to the real instruction 12295 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12296 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12297 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12298 * bail to the real handler if breakFlags==0. 12299 */ 12300 ldrb r3, [rSELF, #offThread_breakFlags] 12301 adrl lr, dvmAsmInstructionStart + (113 * 64) 12302 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12303 cmp r3, #0 12304 bxeq lr @ nothing to do - jump to real handler 12305 EXPORT_PC() 12306 mov r0, rPC @ arg0 12307 mov r1, rFP @ arg1 12308 mov r2, rSELF @ arg2 12309 b dvmCheckBefore @ (dPC,dFP,self) tail call 12310 12311 /* ------------------------------ */ 12312 .balign 64 12313 .L_ALT_OP_INVOKE_INTERFACE: /* 0x72 */ 12314 /* File: armv5te/alt_stub.S */ 12315 /* 12316 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12317 * any interesting requests and then jump to the real instruction 12318 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12319 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12320 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12321 * bail to the real handler if breakFlags==0. 12322 */ 12323 ldrb r3, [rSELF, #offThread_breakFlags] 12324 adrl lr, dvmAsmInstructionStart + (114 * 64) 12325 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12326 cmp r3, #0 12327 bxeq lr @ nothing to do - jump to real handler 12328 EXPORT_PC() 12329 mov r0, rPC @ arg0 12330 mov r1, rFP @ arg1 12331 mov r2, rSELF @ arg2 12332 b dvmCheckBefore @ (dPC,dFP,self) tail call 12333 12334 /* ------------------------------ */ 12335 .balign 64 12336 .L_ALT_OP_UNUSED_73: /* 0x73 */ 12337 /* File: armv5te/alt_stub.S */ 12338 /* 12339 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12340 * any interesting requests and then jump to the real instruction 12341 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12342 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12343 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12344 * bail to the real handler if breakFlags==0. 12345 */ 12346 ldrb r3, [rSELF, #offThread_breakFlags] 12347 adrl lr, dvmAsmInstructionStart + (115 * 64) 12348 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12349 cmp r3, #0 12350 bxeq lr @ nothing to do - jump to real handler 12351 EXPORT_PC() 12352 mov r0, rPC @ arg0 12353 mov r1, rFP @ arg1 12354 mov r2, rSELF @ arg2 12355 b dvmCheckBefore @ (dPC,dFP,self) tail call 12356 12357 /* ------------------------------ */ 12358 .balign 64 12359 .L_ALT_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 12360 /* File: armv5te/alt_stub.S */ 12361 /* 12362 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12363 * any interesting requests and then jump to the real instruction 12364 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12365 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12366 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12367 * bail to the real handler if breakFlags==0. 12368 */ 12369 ldrb r3, [rSELF, #offThread_breakFlags] 12370 adrl lr, dvmAsmInstructionStart + (116 * 64) 12371 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12372 cmp r3, #0 12373 bxeq lr @ nothing to do - jump to real handler 12374 EXPORT_PC() 12375 mov r0, rPC @ arg0 12376 mov r1, rFP @ arg1 12377 mov r2, rSELF @ arg2 12378 b dvmCheckBefore @ (dPC,dFP,self) tail call 12379 12380 /* ------------------------------ */ 12381 .balign 64 12382 .L_ALT_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 12383 /* File: armv5te/alt_stub.S */ 12384 /* 12385 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12386 * any interesting requests and then jump to the real instruction 12387 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12388 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12389 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12390 * bail to the real handler if breakFlags==0. 12391 */ 12392 ldrb r3, [rSELF, #offThread_breakFlags] 12393 adrl lr, dvmAsmInstructionStart + (117 * 64) 12394 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12395 cmp r3, #0 12396 bxeq lr @ nothing to do - jump to real handler 12397 EXPORT_PC() 12398 mov r0, rPC @ arg0 12399 mov r1, rFP @ arg1 12400 mov r2, rSELF @ arg2 12401 b dvmCheckBefore @ (dPC,dFP,self) tail call 12402 12403 /* ------------------------------ */ 12404 .balign 64 12405 .L_ALT_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 12406 /* File: armv5te/alt_stub.S */ 12407 /* 12408 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12409 * any interesting requests and then jump to the real instruction 12410 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12411 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12412 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12413 * bail to the real handler if breakFlags==0. 12414 */ 12415 ldrb r3, [rSELF, #offThread_breakFlags] 12416 adrl lr, dvmAsmInstructionStart + (118 * 64) 12417 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12418 cmp r3, #0 12419 bxeq lr @ nothing to do - jump to real handler 12420 EXPORT_PC() 12421 mov r0, rPC @ arg0 12422 mov r1, rFP @ arg1 12423 mov r2, rSELF @ arg2 12424 b dvmCheckBefore @ (dPC,dFP,self) tail call 12425 12426 /* ------------------------------ */ 12427 .balign 64 12428 .L_ALT_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 12429 /* File: armv5te/alt_stub.S */ 12430 /* 12431 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12432 * any interesting requests and then jump to the real instruction 12433 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12434 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12435 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12436 * bail to the real handler if breakFlags==0. 12437 */ 12438 ldrb r3, [rSELF, #offThread_breakFlags] 12439 adrl lr, dvmAsmInstructionStart + (119 * 64) 12440 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12441 cmp r3, #0 12442 bxeq lr @ nothing to do - jump to real handler 12443 EXPORT_PC() 12444 mov r0, rPC @ arg0 12445 mov r1, rFP @ arg1 12446 mov r2, rSELF @ arg2 12447 b dvmCheckBefore @ (dPC,dFP,self) tail call 12448 12449 /* ------------------------------ */ 12450 .balign 64 12451 .L_ALT_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 12452 /* File: armv5te/alt_stub.S */ 12453 /* 12454 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12455 * any interesting requests and then jump to the real instruction 12456 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12457 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12458 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12459 * bail to the real handler if breakFlags==0. 12460 */ 12461 ldrb r3, [rSELF, #offThread_breakFlags] 12462 adrl lr, dvmAsmInstructionStart + (120 * 64) 12463 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12464 cmp r3, #0 12465 bxeq lr @ nothing to do - jump to real handler 12466 EXPORT_PC() 12467 mov r0, rPC @ arg0 12468 mov r1, rFP @ arg1 12469 mov r2, rSELF @ arg2 12470 b dvmCheckBefore @ (dPC,dFP,self) tail call 12471 12472 /* ------------------------------ */ 12473 .balign 64 12474 .L_ALT_OP_UNUSED_79: /* 0x79 */ 12475 /* File: armv5te/alt_stub.S */ 12476 /* 12477 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12478 * any interesting requests and then jump to the real instruction 12479 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12480 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12481 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12482 * bail to the real handler if breakFlags==0. 12483 */ 12484 ldrb r3, [rSELF, #offThread_breakFlags] 12485 adrl lr, dvmAsmInstructionStart + (121 * 64) 12486 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12487 cmp r3, #0 12488 bxeq lr @ nothing to do - jump to real handler 12489 EXPORT_PC() 12490 mov r0, rPC @ arg0 12491 mov r1, rFP @ arg1 12492 mov r2, rSELF @ arg2 12493 b dvmCheckBefore @ (dPC,dFP,self) tail call 12494 12495 /* ------------------------------ */ 12496 .balign 64 12497 .L_ALT_OP_UNUSED_7A: /* 0x7a */ 12498 /* File: armv5te/alt_stub.S */ 12499 /* 12500 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12501 * any interesting requests and then jump to the real instruction 12502 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12503 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12504 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12505 * bail to the real handler if breakFlags==0. 12506 */ 12507 ldrb r3, [rSELF, #offThread_breakFlags] 12508 adrl lr, dvmAsmInstructionStart + (122 * 64) 12509 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12510 cmp r3, #0 12511 bxeq lr @ nothing to do - jump to real handler 12512 EXPORT_PC() 12513 mov r0, rPC @ arg0 12514 mov r1, rFP @ arg1 12515 mov r2, rSELF @ arg2 12516 b dvmCheckBefore @ (dPC,dFP,self) tail call 12517 12518 /* ------------------------------ */ 12519 .balign 64 12520 .L_ALT_OP_NEG_INT: /* 0x7b */ 12521 /* File: armv5te/alt_stub.S */ 12522 /* 12523 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12524 * any interesting requests and then jump to the real instruction 12525 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12526 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12527 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12528 * bail to the real handler if breakFlags==0. 12529 */ 12530 ldrb r3, [rSELF, #offThread_breakFlags] 12531 adrl lr, dvmAsmInstructionStart + (123 * 64) 12532 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12533 cmp r3, #0 12534 bxeq lr @ nothing to do - jump to real handler 12535 EXPORT_PC() 12536 mov r0, rPC @ arg0 12537 mov r1, rFP @ arg1 12538 mov r2, rSELF @ arg2 12539 b dvmCheckBefore @ (dPC,dFP,self) tail call 12540 12541 /* ------------------------------ */ 12542 .balign 64 12543 .L_ALT_OP_NOT_INT: /* 0x7c */ 12544 /* File: armv5te/alt_stub.S */ 12545 /* 12546 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12547 * any interesting requests and then jump to the real instruction 12548 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12549 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12550 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12551 * bail to the real handler if breakFlags==0. 12552 */ 12553 ldrb r3, [rSELF, #offThread_breakFlags] 12554 adrl lr, dvmAsmInstructionStart + (124 * 64) 12555 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12556 cmp r3, #0 12557 bxeq lr @ nothing to do - jump to real handler 12558 EXPORT_PC() 12559 mov r0, rPC @ arg0 12560 mov r1, rFP @ arg1 12561 mov r2, rSELF @ arg2 12562 b dvmCheckBefore @ (dPC,dFP,self) tail call 12563 12564 /* ------------------------------ */ 12565 .balign 64 12566 .L_ALT_OP_NEG_LONG: /* 0x7d */ 12567 /* File: armv5te/alt_stub.S */ 12568 /* 12569 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12570 * any interesting requests and then jump to the real instruction 12571 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12572 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12573 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12574 * bail to the real handler if breakFlags==0. 12575 */ 12576 ldrb r3, [rSELF, #offThread_breakFlags] 12577 adrl lr, dvmAsmInstructionStart + (125 * 64) 12578 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12579 cmp r3, #0 12580 bxeq lr @ nothing to do - jump to real handler 12581 EXPORT_PC() 12582 mov r0, rPC @ arg0 12583 mov r1, rFP @ arg1 12584 mov r2, rSELF @ arg2 12585 b dvmCheckBefore @ (dPC,dFP,self) tail call 12586 12587 /* ------------------------------ */ 12588 .balign 64 12589 .L_ALT_OP_NOT_LONG: /* 0x7e */ 12590 /* File: armv5te/alt_stub.S */ 12591 /* 12592 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12593 * any interesting requests and then jump to the real instruction 12594 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12595 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12596 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12597 * bail to the real handler if breakFlags==0. 12598 */ 12599 ldrb r3, [rSELF, #offThread_breakFlags] 12600 adrl lr, dvmAsmInstructionStart + (126 * 64) 12601 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12602 cmp r3, #0 12603 bxeq lr @ nothing to do - jump to real handler 12604 EXPORT_PC() 12605 mov r0, rPC @ arg0 12606 mov r1, rFP @ arg1 12607 mov r2, rSELF @ arg2 12608 b dvmCheckBefore @ (dPC,dFP,self) tail call 12609 12610 /* ------------------------------ */ 12611 .balign 64 12612 .L_ALT_OP_NEG_FLOAT: /* 0x7f */ 12613 /* File: armv5te/alt_stub.S */ 12614 /* 12615 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12616 * any interesting requests and then jump to the real instruction 12617 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12618 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12619 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12620 * bail to the real handler if breakFlags==0. 12621 */ 12622 ldrb r3, [rSELF, #offThread_breakFlags] 12623 adrl lr, dvmAsmInstructionStart + (127 * 64) 12624 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12625 cmp r3, #0 12626 bxeq lr @ nothing to do - jump to real handler 12627 EXPORT_PC() 12628 mov r0, rPC @ arg0 12629 mov r1, rFP @ arg1 12630 mov r2, rSELF @ arg2 12631 b dvmCheckBefore @ (dPC,dFP,self) tail call 12632 12633 /* ------------------------------ */ 12634 .balign 64 12635 .L_ALT_OP_NEG_DOUBLE: /* 0x80 */ 12636 /* File: armv5te/alt_stub.S */ 12637 /* 12638 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12639 * any interesting requests and then jump to the real instruction 12640 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12641 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12642 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12643 * bail to the real handler if breakFlags==0. 12644 */ 12645 ldrb r3, [rSELF, #offThread_breakFlags] 12646 adrl lr, dvmAsmInstructionStart + (128 * 64) 12647 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12648 cmp r3, #0 12649 bxeq lr @ nothing to do - jump to real handler 12650 EXPORT_PC() 12651 mov r0, rPC @ arg0 12652 mov r1, rFP @ arg1 12653 mov r2, rSELF @ arg2 12654 b dvmCheckBefore @ (dPC,dFP,self) tail call 12655 12656 /* ------------------------------ */ 12657 .balign 64 12658 .L_ALT_OP_INT_TO_LONG: /* 0x81 */ 12659 /* File: armv5te/alt_stub.S */ 12660 /* 12661 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12662 * any interesting requests and then jump to the real instruction 12663 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12664 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12665 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12666 * bail to the real handler if breakFlags==0. 12667 */ 12668 ldrb r3, [rSELF, #offThread_breakFlags] 12669 adrl lr, dvmAsmInstructionStart + (129 * 64) 12670 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12671 cmp r3, #0 12672 bxeq lr @ nothing to do - jump to real handler 12673 EXPORT_PC() 12674 mov r0, rPC @ arg0 12675 mov r1, rFP @ arg1 12676 mov r2, rSELF @ arg2 12677 b dvmCheckBefore @ (dPC,dFP,self) tail call 12678 12679 /* ------------------------------ */ 12680 .balign 64 12681 .L_ALT_OP_INT_TO_FLOAT: /* 0x82 */ 12682 /* File: armv5te/alt_stub.S */ 12683 /* 12684 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12685 * any interesting requests and then jump to the real instruction 12686 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12687 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12688 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12689 * bail to the real handler if breakFlags==0. 12690 */ 12691 ldrb r3, [rSELF, #offThread_breakFlags] 12692 adrl lr, dvmAsmInstructionStart + (130 * 64) 12693 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12694 cmp r3, #0 12695 bxeq lr @ nothing to do - jump to real handler 12696 EXPORT_PC() 12697 mov r0, rPC @ arg0 12698 mov r1, rFP @ arg1 12699 mov r2, rSELF @ arg2 12700 b dvmCheckBefore @ (dPC,dFP,self) tail call 12701 12702 /* ------------------------------ */ 12703 .balign 64 12704 .L_ALT_OP_INT_TO_DOUBLE: /* 0x83 */ 12705 /* File: armv5te/alt_stub.S */ 12706 /* 12707 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12708 * any interesting requests and then jump to the real instruction 12709 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12710 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12711 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12712 * bail to the real handler if breakFlags==0. 12713 */ 12714 ldrb r3, [rSELF, #offThread_breakFlags] 12715 adrl lr, dvmAsmInstructionStart + (131 * 64) 12716 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12717 cmp r3, #0 12718 bxeq lr @ nothing to do - jump to real handler 12719 EXPORT_PC() 12720 mov r0, rPC @ arg0 12721 mov r1, rFP @ arg1 12722 mov r2, rSELF @ arg2 12723 b dvmCheckBefore @ (dPC,dFP,self) tail call 12724 12725 /* ------------------------------ */ 12726 .balign 64 12727 .L_ALT_OP_LONG_TO_INT: /* 0x84 */ 12728 /* File: armv5te/alt_stub.S */ 12729 /* 12730 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12731 * any interesting requests and then jump to the real instruction 12732 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12733 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12734 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12735 * bail to the real handler if breakFlags==0. 12736 */ 12737 ldrb r3, [rSELF, #offThread_breakFlags] 12738 adrl lr, dvmAsmInstructionStart + (132 * 64) 12739 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12740 cmp r3, #0 12741 bxeq lr @ nothing to do - jump to real handler 12742 EXPORT_PC() 12743 mov r0, rPC @ arg0 12744 mov r1, rFP @ arg1 12745 mov r2, rSELF @ arg2 12746 b dvmCheckBefore @ (dPC,dFP,self) tail call 12747 12748 /* ------------------------------ */ 12749 .balign 64 12750 .L_ALT_OP_LONG_TO_FLOAT: /* 0x85 */ 12751 /* File: armv5te/alt_stub.S */ 12752 /* 12753 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12754 * any interesting requests and then jump to the real instruction 12755 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12756 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12757 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12758 * bail to the real handler if breakFlags==0. 12759 */ 12760 ldrb r3, [rSELF, #offThread_breakFlags] 12761 adrl lr, dvmAsmInstructionStart + (133 * 64) 12762 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12763 cmp r3, #0 12764 bxeq lr @ nothing to do - jump to real handler 12765 EXPORT_PC() 12766 mov r0, rPC @ arg0 12767 mov r1, rFP @ arg1 12768 mov r2, rSELF @ arg2 12769 b dvmCheckBefore @ (dPC,dFP,self) tail call 12770 12771 /* ------------------------------ */ 12772 .balign 64 12773 .L_ALT_OP_LONG_TO_DOUBLE: /* 0x86 */ 12774 /* File: armv5te/alt_stub.S */ 12775 /* 12776 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12777 * any interesting requests and then jump to the real instruction 12778 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12779 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12780 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12781 * bail to the real handler if breakFlags==0. 12782 */ 12783 ldrb r3, [rSELF, #offThread_breakFlags] 12784 adrl lr, dvmAsmInstructionStart + (134 * 64) 12785 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12786 cmp r3, #0 12787 bxeq lr @ nothing to do - jump to real handler 12788 EXPORT_PC() 12789 mov r0, rPC @ arg0 12790 mov r1, rFP @ arg1 12791 mov r2, rSELF @ arg2 12792 b dvmCheckBefore @ (dPC,dFP,self) tail call 12793 12794 /* ------------------------------ */ 12795 .balign 64 12796 .L_ALT_OP_FLOAT_TO_INT: /* 0x87 */ 12797 /* File: armv5te/alt_stub.S */ 12798 /* 12799 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12800 * any interesting requests and then jump to the real instruction 12801 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12802 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12803 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12804 * bail to the real handler if breakFlags==0. 12805 */ 12806 ldrb r3, [rSELF, #offThread_breakFlags] 12807 adrl lr, dvmAsmInstructionStart + (135 * 64) 12808 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12809 cmp r3, #0 12810 bxeq lr @ nothing to do - jump to real handler 12811 EXPORT_PC() 12812 mov r0, rPC @ arg0 12813 mov r1, rFP @ arg1 12814 mov r2, rSELF @ arg2 12815 b dvmCheckBefore @ (dPC,dFP,self) tail call 12816 12817 /* ------------------------------ */ 12818 .balign 64 12819 .L_ALT_OP_FLOAT_TO_LONG: /* 0x88 */ 12820 /* File: armv5te/alt_stub.S */ 12821 /* 12822 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12823 * any interesting requests and then jump to the real instruction 12824 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12825 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12826 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12827 * bail to the real handler if breakFlags==0. 12828 */ 12829 ldrb r3, [rSELF, #offThread_breakFlags] 12830 adrl lr, dvmAsmInstructionStart + (136 * 64) 12831 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12832 cmp r3, #0 12833 bxeq lr @ nothing to do - jump to real handler 12834 EXPORT_PC() 12835 mov r0, rPC @ arg0 12836 mov r1, rFP @ arg1 12837 mov r2, rSELF @ arg2 12838 b dvmCheckBefore @ (dPC,dFP,self) tail call 12839 12840 /* ------------------------------ */ 12841 .balign 64 12842 .L_ALT_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 12843 /* File: armv5te/alt_stub.S */ 12844 /* 12845 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12846 * any interesting requests and then jump to the real instruction 12847 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12848 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12849 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12850 * bail to the real handler if breakFlags==0. 12851 */ 12852 ldrb r3, [rSELF, #offThread_breakFlags] 12853 adrl lr, dvmAsmInstructionStart + (137 * 64) 12854 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12855 cmp r3, #0 12856 bxeq lr @ nothing to do - jump to real handler 12857 EXPORT_PC() 12858 mov r0, rPC @ arg0 12859 mov r1, rFP @ arg1 12860 mov r2, rSELF @ arg2 12861 b dvmCheckBefore @ (dPC,dFP,self) tail call 12862 12863 /* ------------------------------ */ 12864 .balign 64 12865 .L_ALT_OP_DOUBLE_TO_INT: /* 0x8a */ 12866 /* File: armv5te/alt_stub.S */ 12867 /* 12868 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12869 * any interesting requests and then jump to the real instruction 12870 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12871 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12872 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12873 * bail to the real handler if breakFlags==0. 12874 */ 12875 ldrb r3, [rSELF, #offThread_breakFlags] 12876 adrl lr, dvmAsmInstructionStart + (138 * 64) 12877 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12878 cmp r3, #0 12879 bxeq lr @ nothing to do - jump to real handler 12880 EXPORT_PC() 12881 mov r0, rPC @ arg0 12882 mov r1, rFP @ arg1 12883 mov r2, rSELF @ arg2 12884 b dvmCheckBefore @ (dPC,dFP,self) tail call 12885 12886 /* ------------------------------ */ 12887 .balign 64 12888 .L_ALT_OP_DOUBLE_TO_LONG: /* 0x8b */ 12889 /* File: armv5te/alt_stub.S */ 12890 /* 12891 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12892 * any interesting requests and then jump to the real instruction 12893 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12894 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12895 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12896 * bail to the real handler if breakFlags==0. 12897 */ 12898 ldrb r3, [rSELF, #offThread_breakFlags] 12899 adrl lr, dvmAsmInstructionStart + (139 * 64) 12900 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12901 cmp r3, #0 12902 bxeq lr @ nothing to do - jump to real handler 12903 EXPORT_PC() 12904 mov r0, rPC @ arg0 12905 mov r1, rFP @ arg1 12906 mov r2, rSELF @ arg2 12907 b dvmCheckBefore @ (dPC,dFP,self) tail call 12908 12909 /* ------------------------------ */ 12910 .balign 64 12911 .L_ALT_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 12912 /* File: armv5te/alt_stub.S */ 12913 /* 12914 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12915 * any interesting requests and then jump to the real instruction 12916 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12917 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12918 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12919 * bail to the real handler if breakFlags==0. 12920 */ 12921 ldrb r3, [rSELF, #offThread_breakFlags] 12922 adrl lr, dvmAsmInstructionStart + (140 * 64) 12923 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12924 cmp r3, #0 12925 bxeq lr @ nothing to do - jump to real handler 12926 EXPORT_PC() 12927 mov r0, rPC @ arg0 12928 mov r1, rFP @ arg1 12929 mov r2, rSELF @ arg2 12930 b dvmCheckBefore @ (dPC,dFP,self) tail call 12931 12932 /* ------------------------------ */ 12933 .balign 64 12934 .L_ALT_OP_INT_TO_BYTE: /* 0x8d */ 12935 /* File: armv5te/alt_stub.S */ 12936 /* 12937 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12938 * any interesting requests and then jump to the real instruction 12939 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12940 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12941 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12942 * bail to the real handler if breakFlags==0. 12943 */ 12944 ldrb r3, [rSELF, #offThread_breakFlags] 12945 adrl lr, dvmAsmInstructionStart + (141 * 64) 12946 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12947 cmp r3, #0 12948 bxeq lr @ nothing to do - jump to real handler 12949 EXPORT_PC() 12950 mov r0, rPC @ arg0 12951 mov r1, rFP @ arg1 12952 mov r2, rSELF @ arg2 12953 b dvmCheckBefore @ (dPC,dFP,self) tail call 12954 12955 /* ------------------------------ */ 12956 .balign 64 12957 .L_ALT_OP_INT_TO_CHAR: /* 0x8e */ 12958 /* File: armv5te/alt_stub.S */ 12959 /* 12960 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12961 * any interesting requests and then jump to the real instruction 12962 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12963 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12964 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12965 * bail to the real handler if breakFlags==0. 12966 */ 12967 ldrb r3, [rSELF, #offThread_breakFlags] 12968 adrl lr, dvmAsmInstructionStart + (142 * 64) 12969 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12970 cmp r3, #0 12971 bxeq lr @ nothing to do - jump to real handler 12972 EXPORT_PC() 12973 mov r0, rPC @ arg0 12974 mov r1, rFP @ arg1 12975 mov r2, rSELF @ arg2 12976 b dvmCheckBefore @ (dPC,dFP,self) tail call 12977 12978 /* ------------------------------ */ 12979 .balign 64 12980 .L_ALT_OP_INT_TO_SHORT: /* 0x8f */ 12981 /* File: armv5te/alt_stub.S */ 12982 /* 12983 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12984 * any interesting requests and then jump to the real instruction 12985 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12986 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12987 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12988 * bail to the real handler if breakFlags==0. 12989 */ 12990 ldrb r3, [rSELF, #offThread_breakFlags] 12991 adrl lr, dvmAsmInstructionStart + (143 * 64) 12992 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12993 cmp r3, #0 12994 bxeq lr @ nothing to do - jump to real handler 12995 EXPORT_PC() 12996 mov r0, rPC @ arg0 12997 mov r1, rFP @ arg1 12998 mov r2, rSELF @ arg2 12999 b dvmCheckBefore @ (dPC,dFP,self) tail call 13000 13001 /* ------------------------------ */ 13002 .balign 64 13003 .L_ALT_OP_ADD_INT: /* 0x90 */ 13004 /* File: armv5te/alt_stub.S */ 13005 /* 13006 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13007 * any interesting requests and then jump to the real instruction 13008 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13009 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13010 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13011 * bail to the real handler if breakFlags==0. 13012 */ 13013 ldrb r3, [rSELF, #offThread_breakFlags] 13014 adrl lr, dvmAsmInstructionStart + (144 * 64) 13015 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13016 cmp r3, #0 13017 bxeq lr @ nothing to do - jump to real handler 13018 EXPORT_PC() 13019 mov r0, rPC @ arg0 13020 mov r1, rFP @ arg1 13021 mov r2, rSELF @ arg2 13022 b dvmCheckBefore @ (dPC,dFP,self) tail call 13023 13024 /* ------------------------------ */ 13025 .balign 64 13026 .L_ALT_OP_SUB_INT: /* 0x91 */ 13027 /* File: armv5te/alt_stub.S */ 13028 /* 13029 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13030 * any interesting requests and then jump to the real instruction 13031 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13032 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13033 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13034 * bail to the real handler if breakFlags==0. 13035 */ 13036 ldrb r3, [rSELF, #offThread_breakFlags] 13037 adrl lr, dvmAsmInstructionStart + (145 * 64) 13038 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13039 cmp r3, #0 13040 bxeq lr @ nothing to do - jump to real handler 13041 EXPORT_PC() 13042 mov r0, rPC @ arg0 13043 mov r1, rFP @ arg1 13044 mov r2, rSELF @ arg2 13045 b dvmCheckBefore @ (dPC,dFP,self) tail call 13046 13047 /* ------------------------------ */ 13048 .balign 64 13049 .L_ALT_OP_MUL_INT: /* 0x92 */ 13050 /* File: armv5te/alt_stub.S */ 13051 /* 13052 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13053 * any interesting requests and then jump to the real instruction 13054 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13055 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13056 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13057 * bail to the real handler if breakFlags==0. 13058 */ 13059 ldrb r3, [rSELF, #offThread_breakFlags] 13060 adrl lr, dvmAsmInstructionStart + (146 * 64) 13061 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13062 cmp r3, #0 13063 bxeq lr @ nothing to do - jump to real handler 13064 EXPORT_PC() 13065 mov r0, rPC @ arg0 13066 mov r1, rFP @ arg1 13067 mov r2, rSELF @ arg2 13068 b dvmCheckBefore @ (dPC,dFP,self) tail call 13069 13070 /* ------------------------------ */ 13071 .balign 64 13072 .L_ALT_OP_DIV_INT: /* 0x93 */ 13073 /* File: armv5te/alt_stub.S */ 13074 /* 13075 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13076 * any interesting requests and then jump to the real instruction 13077 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13078 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13079 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13080 * bail to the real handler if breakFlags==0. 13081 */ 13082 ldrb r3, [rSELF, #offThread_breakFlags] 13083 adrl lr, dvmAsmInstructionStart + (147 * 64) 13084 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13085 cmp r3, #0 13086 bxeq lr @ nothing to do - jump to real handler 13087 EXPORT_PC() 13088 mov r0, rPC @ arg0 13089 mov r1, rFP @ arg1 13090 mov r2, rSELF @ arg2 13091 b dvmCheckBefore @ (dPC,dFP,self) tail call 13092 13093 /* ------------------------------ */ 13094 .balign 64 13095 .L_ALT_OP_REM_INT: /* 0x94 */ 13096 /* File: armv5te/alt_stub.S */ 13097 /* 13098 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13099 * any interesting requests and then jump to the real instruction 13100 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13101 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13102 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13103 * bail to the real handler if breakFlags==0. 13104 */ 13105 ldrb r3, [rSELF, #offThread_breakFlags] 13106 adrl lr, dvmAsmInstructionStart + (148 * 64) 13107 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13108 cmp r3, #0 13109 bxeq lr @ nothing to do - jump to real handler 13110 EXPORT_PC() 13111 mov r0, rPC @ arg0 13112 mov r1, rFP @ arg1 13113 mov r2, rSELF @ arg2 13114 b dvmCheckBefore @ (dPC,dFP,self) tail call 13115 13116 /* ------------------------------ */ 13117 .balign 64 13118 .L_ALT_OP_AND_INT: /* 0x95 */ 13119 /* File: armv5te/alt_stub.S */ 13120 /* 13121 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13122 * any interesting requests and then jump to the real instruction 13123 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13124 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13125 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13126 * bail to the real handler if breakFlags==0. 13127 */ 13128 ldrb r3, [rSELF, #offThread_breakFlags] 13129 adrl lr, dvmAsmInstructionStart + (149 * 64) 13130 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13131 cmp r3, #0 13132 bxeq lr @ nothing to do - jump to real handler 13133 EXPORT_PC() 13134 mov r0, rPC @ arg0 13135 mov r1, rFP @ arg1 13136 mov r2, rSELF @ arg2 13137 b dvmCheckBefore @ (dPC,dFP,self) tail call 13138 13139 /* ------------------------------ */ 13140 .balign 64 13141 .L_ALT_OP_OR_INT: /* 0x96 */ 13142 /* File: armv5te/alt_stub.S */ 13143 /* 13144 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13145 * any interesting requests and then jump to the real instruction 13146 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13147 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13148 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13149 * bail to the real handler if breakFlags==0. 13150 */ 13151 ldrb r3, [rSELF, #offThread_breakFlags] 13152 adrl lr, dvmAsmInstructionStart + (150 * 64) 13153 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13154 cmp r3, #0 13155 bxeq lr @ nothing to do - jump to real handler 13156 EXPORT_PC() 13157 mov r0, rPC @ arg0 13158 mov r1, rFP @ arg1 13159 mov r2, rSELF @ arg2 13160 b dvmCheckBefore @ (dPC,dFP,self) tail call 13161 13162 /* ------------------------------ */ 13163 .balign 64 13164 .L_ALT_OP_XOR_INT: /* 0x97 */ 13165 /* File: armv5te/alt_stub.S */ 13166 /* 13167 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13168 * any interesting requests and then jump to the real instruction 13169 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13170 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13171 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13172 * bail to the real handler if breakFlags==0. 13173 */ 13174 ldrb r3, [rSELF, #offThread_breakFlags] 13175 adrl lr, dvmAsmInstructionStart + (151 * 64) 13176 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13177 cmp r3, #0 13178 bxeq lr @ nothing to do - jump to real handler 13179 EXPORT_PC() 13180 mov r0, rPC @ arg0 13181 mov r1, rFP @ arg1 13182 mov r2, rSELF @ arg2 13183 b dvmCheckBefore @ (dPC,dFP,self) tail call 13184 13185 /* ------------------------------ */ 13186 .balign 64 13187 .L_ALT_OP_SHL_INT: /* 0x98 */ 13188 /* File: armv5te/alt_stub.S */ 13189 /* 13190 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13191 * any interesting requests and then jump to the real instruction 13192 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13193 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13194 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13195 * bail to the real handler if breakFlags==0. 13196 */ 13197 ldrb r3, [rSELF, #offThread_breakFlags] 13198 adrl lr, dvmAsmInstructionStart + (152 * 64) 13199 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13200 cmp r3, #0 13201 bxeq lr @ nothing to do - jump to real handler 13202 EXPORT_PC() 13203 mov r0, rPC @ arg0 13204 mov r1, rFP @ arg1 13205 mov r2, rSELF @ arg2 13206 b dvmCheckBefore @ (dPC,dFP,self) tail call 13207 13208 /* ------------------------------ */ 13209 .balign 64 13210 .L_ALT_OP_SHR_INT: /* 0x99 */ 13211 /* File: armv5te/alt_stub.S */ 13212 /* 13213 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13214 * any interesting requests and then jump to the real instruction 13215 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13216 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13217 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13218 * bail to the real handler if breakFlags==0. 13219 */ 13220 ldrb r3, [rSELF, #offThread_breakFlags] 13221 adrl lr, dvmAsmInstructionStart + (153 * 64) 13222 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13223 cmp r3, #0 13224 bxeq lr @ nothing to do - jump to real handler 13225 EXPORT_PC() 13226 mov r0, rPC @ arg0 13227 mov r1, rFP @ arg1 13228 mov r2, rSELF @ arg2 13229 b dvmCheckBefore @ (dPC,dFP,self) tail call 13230 13231 /* ------------------------------ */ 13232 .balign 64 13233 .L_ALT_OP_USHR_INT: /* 0x9a */ 13234 /* File: armv5te/alt_stub.S */ 13235 /* 13236 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13237 * any interesting requests and then jump to the real instruction 13238 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13239 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13240 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13241 * bail to the real handler if breakFlags==0. 13242 */ 13243 ldrb r3, [rSELF, #offThread_breakFlags] 13244 adrl lr, dvmAsmInstructionStart + (154 * 64) 13245 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13246 cmp r3, #0 13247 bxeq lr @ nothing to do - jump to real handler 13248 EXPORT_PC() 13249 mov r0, rPC @ arg0 13250 mov r1, rFP @ arg1 13251 mov r2, rSELF @ arg2 13252 b dvmCheckBefore @ (dPC,dFP,self) tail call 13253 13254 /* ------------------------------ */ 13255 .balign 64 13256 .L_ALT_OP_ADD_LONG: /* 0x9b */ 13257 /* File: armv5te/alt_stub.S */ 13258 /* 13259 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13260 * any interesting requests and then jump to the real instruction 13261 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13262 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13263 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13264 * bail to the real handler if breakFlags==0. 13265 */ 13266 ldrb r3, [rSELF, #offThread_breakFlags] 13267 adrl lr, dvmAsmInstructionStart + (155 * 64) 13268 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13269 cmp r3, #0 13270 bxeq lr @ nothing to do - jump to real handler 13271 EXPORT_PC() 13272 mov r0, rPC @ arg0 13273 mov r1, rFP @ arg1 13274 mov r2, rSELF @ arg2 13275 b dvmCheckBefore @ (dPC,dFP,self) tail call 13276 13277 /* ------------------------------ */ 13278 .balign 64 13279 .L_ALT_OP_SUB_LONG: /* 0x9c */ 13280 /* File: armv5te/alt_stub.S */ 13281 /* 13282 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13283 * any interesting requests and then jump to the real instruction 13284 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13285 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13286 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13287 * bail to the real handler if breakFlags==0. 13288 */ 13289 ldrb r3, [rSELF, #offThread_breakFlags] 13290 adrl lr, dvmAsmInstructionStart + (156 * 64) 13291 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13292 cmp r3, #0 13293 bxeq lr @ nothing to do - jump to real handler 13294 EXPORT_PC() 13295 mov r0, rPC @ arg0 13296 mov r1, rFP @ arg1 13297 mov r2, rSELF @ arg2 13298 b dvmCheckBefore @ (dPC,dFP,self) tail call 13299 13300 /* ------------------------------ */ 13301 .balign 64 13302 .L_ALT_OP_MUL_LONG: /* 0x9d */ 13303 /* File: armv5te/alt_stub.S */ 13304 /* 13305 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13306 * any interesting requests and then jump to the real instruction 13307 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13308 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13309 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13310 * bail to the real handler if breakFlags==0. 13311 */ 13312 ldrb r3, [rSELF, #offThread_breakFlags] 13313 adrl lr, dvmAsmInstructionStart + (157 * 64) 13314 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13315 cmp r3, #0 13316 bxeq lr @ nothing to do - jump to real handler 13317 EXPORT_PC() 13318 mov r0, rPC @ arg0 13319 mov r1, rFP @ arg1 13320 mov r2, rSELF @ arg2 13321 b dvmCheckBefore @ (dPC,dFP,self) tail call 13322 13323 /* ------------------------------ */ 13324 .balign 64 13325 .L_ALT_OP_DIV_LONG: /* 0x9e */ 13326 /* File: armv5te/alt_stub.S */ 13327 /* 13328 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13329 * any interesting requests and then jump to the real instruction 13330 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13331 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13332 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13333 * bail to the real handler if breakFlags==0. 13334 */ 13335 ldrb r3, [rSELF, #offThread_breakFlags] 13336 adrl lr, dvmAsmInstructionStart + (158 * 64) 13337 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13338 cmp r3, #0 13339 bxeq lr @ nothing to do - jump to real handler 13340 EXPORT_PC() 13341 mov r0, rPC @ arg0 13342 mov r1, rFP @ arg1 13343 mov r2, rSELF @ arg2 13344 b dvmCheckBefore @ (dPC,dFP,self) tail call 13345 13346 /* ------------------------------ */ 13347 .balign 64 13348 .L_ALT_OP_REM_LONG: /* 0x9f */ 13349 /* File: armv5te/alt_stub.S */ 13350 /* 13351 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13352 * any interesting requests and then jump to the real instruction 13353 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13354 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13355 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13356 * bail to the real handler if breakFlags==0. 13357 */ 13358 ldrb r3, [rSELF, #offThread_breakFlags] 13359 adrl lr, dvmAsmInstructionStart + (159 * 64) 13360 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13361 cmp r3, #0 13362 bxeq lr @ nothing to do - jump to real handler 13363 EXPORT_PC() 13364 mov r0, rPC @ arg0 13365 mov r1, rFP @ arg1 13366 mov r2, rSELF @ arg2 13367 b dvmCheckBefore @ (dPC,dFP,self) tail call 13368 13369 /* ------------------------------ */ 13370 .balign 64 13371 .L_ALT_OP_AND_LONG: /* 0xa0 */ 13372 /* File: armv5te/alt_stub.S */ 13373 /* 13374 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13375 * any interesting requests and then jump to the real instruction 13376 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13377 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13378 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13379 * bail to the real handler if breakFlags==0. 13380 */ 13381 ldrb r3, [rSELF, #offThread_breakFlags] 13382 adrl lr, dvmAsmInstructionStart + (160 * 64) 13383 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13384 cmp r3, #0 13385 bxeq lr @ nothing to do - jump to real handler 13386 EXPORT_PC() 13387 mov r0, rPC @ arg0 13388 mov r1, rFP @ arg1 13389 mov r2, rSELF @ arg2 13390 b dvmCheckBefore @ (dPC,dFP,self) tail call 13391 13392 /* ------------------------------ */ 13393 .balign 64 13394 .L_ALT_OP_OR_LONG: /* 0xa1 */ 13395 /* File: armv5te/alt_stub.S */ 13396 /* 13397 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13398 * any interesting requests and then jump to the real instruction 13399 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13400 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13401 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13402 * bail to the real handler if breakFlags==0. 13403 */ 13404 ldrb r3, [rSELF, #offThread_breakFlags] 13405 adrl lr, dvmAsmInstructionStart + (161 * 64) 13406 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13407 cmp r3, #0 13408 bxeq lr @ nothing to do - jump to real handler 13409 EXPORT_PC() 13410 mov r0, rPC @ arg0 13411 mov r1, rFP @ arg1 13412 mov r2, rSELF @ arg2 13413 b dvmCheckBefore @ (dPC,dFP,self) tail call 13414 13415 /* ------------------------------ */ 13416 .balign 64 13417 .L_ALT_OP_XOR_LONG: /* 0xa2 */ 13418 /* File: armv5te/alt_stub.S */ 13419 /* 13420 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13421 * any interesting requests and then jump to the real instruction 13422 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13423 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13424 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13425 * bail to the real handler if breakFlags==0. 13426 */ 13427 ldrb r3, [rSELF, #offThread_breakFlags] 13428 adrl lr, dvmAsmInstructionStart + (162 * 64) 13429 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13430 cmp r3, #0 13431 bxeq lr @ nothing to do - jump to real handler 13432 EXPORT_PC() 13433 mov r0, rPC @ arg0 13434 mov r1, rFP @ arg1 13435 mov r2, rSELF @ arg2 13436 b dvmCheckBefore @ (dPC,dFP,self) tail call 13437 13438 /* ------------------------------ */ 13439 .balign 64 13440 .L_ALT_OP_SHL_LONG: /* 0xa3 */ 13441 /* File: armv5te/alt_stub.S */ 13442 /* 13443 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13444 * any interesting requests and then jump to the real instruction 13445 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13446 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13447 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13448 * bail to the real handler if breakFlags==0. 13449 */ 13450 ldrb r3, [rSELF, #offThread_breakFlags] 13451 adrl lr, dvmAsmInstructionStart + (163 * 64) 13452 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13453 cmp r3, #0 13454 bxeq lr @ nothing to do - jump to real handler 13455 EXPORT_PC() 13456 mov r0, rPC @ arg0 13457 mov r1, rFP @ arg1 13458 mov r2, rSELF @ arg2 13459 b dvmCheckBefore @ (dPC,dFP,self) tail call 13460 13461 /* ------------------------------ */ 13462 .balign 64 13463 .L_ALT_OP_SHR_LONG: /* 0xa4 */ 13464 /* File: armv5te/alt_stub.S */ 13465 /* 13466 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13467 * any interesting requests and then jump to the real instruction 13468 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13469 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13470 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13471 * bail to the real handler if breakFlags==0. 13472 */ 13473 ldrb r3, [rSELF, #offThread_breakFlags] 13474 adrl lr, dvmAsmInstructionStart + (164 * 64) 13475 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13476 cmp r3, #0 13477 bxeq lr @ nothing to do - jump to real handler 13478 EXPORT_PC() 13479 mov r0, rPC @ arg0 13480 mov r1, rFP @ arg1 13481 mov r2, rSELF @ arg2 13482 b dvmCheckBefore @ (dPC,dFP,self) tail call 13483 13484 /* ------------------------------ */ 13485 .balign 64 13486 .L_ALT_OP_USHR_LONG: /* 0xa5 */ 13487 /* File: armv5te/alt_stub.S */ 13488 /* 13489 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13490 * any interesting requests and then jump to the real instruction 13491 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13492 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13493 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13494 * bail to the real handler if breakFlags==0. 13495 */ 13496 ldrb r3, [rSELF, #offThread_breakFlags] 13497 adrl lr, dvmAsmInstructionStart + (165 * 64) 13498 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13499 cmp r3, #0 13500 bxeq lr @ nothing to do - jump to real handler 13501 EXPORT_PC() 13502 mov r0, rPC @ arg0 13503 mov r1, rFP @ arg1 13504 mov r2, rSELF @ arg2 13505 b dvmCheckBefore @ (dPC,dFP,self) tail call 13506 13507 /* ------------------------------ */ 13508 .balign 64 13509 .L_ALT_OP_ADD_FLOAT: /* 0xa6 */ 13510 /* File: armv5te/alt_stub.S */ 13511 /* 13512 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13513 * any interesting requests and then jump to the real instruction 13514 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13515 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13516 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13517 * bail to the real handler if breakFlags==0. 13518 */ 13519 ldrb r3, [rSELF, #offThread_breakFlags] 13520 adrl lr, dvmAsmInstructionStart + (166 * 64) 13521 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13522 cmp r3, #0 13523 bxeq lr @ nothing to do - jump to real handler 13524 EXPORT_PC() 13525 mov r0, rPC @ arg0 13526 mov r1, rFP @ arg1 13527 mov r2, rSELF @ arg2 13528 b dvmCheckBefore @ (dPC,dFP,self) tail call 13529 13530 /* ------------------------------ */ 13531 .balign 64 13532 .L_ALT_OP_SUB_FLOAT: /* 0xa7 */ 13533 /* File: armv5te/alt_stub.S */ 13534 /* 13535 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13536 * any interesting requests and then jump to the real instruction 13537 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13538 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13539 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13540 * bail to the real handler if breakFlags==0. 13541 */ 13542 ldrb r3, [rSELF, #offThread_breakFlags] 13543 adrl lr, dvmAsmInstructionStart + (167 * 64) 13544 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13545 cmp r3, #0 13546 bxeq lr @ nothing to do - jump to real handler 13547 EXPORT_PC() 13548 mov r0, rPC @ arg0 13549 mov r1, rFP @ arg1 13550 mov r2, rSELF @ arg2 13551 b dvmCheckBefore @ (dPC,dFP,self) tail call 13552 13553 /* ------------------------------ */ 13554 .balign 64 13555 .L_ALT_OP_MUL_FLOAT: /* 0xa8 */ 13556 /* File: armv5te/alt_stub.S */ 13557 /* 13558 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13559 * any interesting requests and then jump to the real instruction 13560 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13561 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13562 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13563 * bail to the real handler if breakFlags==0. 13564 */ 13565 ldrb r3, [rSELF, #offThread_breakFlags] 13566 adrl lr, dvmAsmInstructionStart + (168 * 64) 13567 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13568 cmp r3, #0 13569 bxeq lr @ nothing to do - jump to real handler 13570 EXPORT_PC() 13571 mov r0, rPC @ arg0 13572 mov r1, rFP @ arg1 13573 mov r2, rSELF @ arg2 13574 b dvmCheckBefore @ (dPC,dFP,self) tail call 13575 13576 /* ------------------------------ */ 13577 .balign 64 13578 .L_ALT_OP_DIV_FLOAT: /* 0xa9 */ 13579 /* File: armv5te/alt_stub.S */ 13580 /* 13581 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13582 * any interesting requests and then jump to the real instruction 13583 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13584 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13585 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13586 * bail to the real handler if breakFlags==0. 13587 */ 13588 ldrb r3, [rSELF, #offThread_breakFlags] 13589 adrl lr, dvmAsmInstructionStart + (169 * 64) 13590 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13591 cmp r3, #0 13592 bxeq lr @ nothing to do - jump to real handler 13593 EXPORT_PC() 13594 mov r0, rPC @ arg0 13595 mov r1, rFP @ arg1 13596 mov r2, rSELF @ arg2 13597 b dvmCheckBefore @ (dPC,dFP,self) tail call 13598 13599 /* ------------------------------ */ 13600 .balign 64 13601 .L_ALT_OP_REM_FLOAT: /* 0xaa */ 13602 /* File: armv5te/alt_stub.S */ 13603 /* 13604 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13605 * any interesting requests and then jump to the real instruction 13606 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13607 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13608 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13609 * bail to the real handler if breakFlags==0. 13610 */ 13611 ldrb r3, [rSELF, #offThread_breakFlags] 13612 adrl lr, dvmAsmInstructionStart + (170 * 64) 13613 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13614 cmp r3, #0 13615 bxeq lr @ nothing to do - jump to real handler 13616 EXPORT_PC() 13617 mov r0, rPC @ arg0 13618 mov r1, rFP @ arg1 13619 mov r2, rSELF @ arg2 13620 b dvmCheckBefore @ (dPC,dFP,self) tail call 13621 13622 /* ------------------------------ */ 13623 .balign 64 13624 .L_ALT_OP_ADD_DOUBLE: /* 0xab */ 13625 /* File: armv5te/alt_stub.S */ 13626 /* 13627 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13628 * any interesting requests and then jump to the real instruction 13629 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13630 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13631 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13632 * bail to the real handler if breakFlags==0. 13633 */ 13634 ldrb r3, [rSELF, #offThread_breakFlags] 13635 adrl lr, dvmAsmInstructionStart + (171 * 64) 13636 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13637 cmp r3, #0 13638 bxeq lr @ nothing to do - jump to real handler 13639 EXPORT_PC() 13640 mov r0, rPC @ arg0 13641 mov r1, rFP @ arg1 13642 mov r2, rSELF @ arg2 13643 b dvmCheckBefore @ (dPC,dFP,self) tail call 13644 13645 /* ------------------------------ */ 13646 .balign 64 13647 .L_ALT_OP_SUB_DOUBLE: /* 0xac */ 13648 /* File: armv5te/alt_stub.S */ 13649 /* 13650 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13651 * any interesting requests and then jump to the real instruction 13652 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13653 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13654 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13655 * bail to the real handler if breakFlags==0. 13656 */ 13657 ldrb r3, [rSELF, #offThread_breakFlags] 13658 adrl lr, dvmAsmInstructionStart + (172 * 64) 13659 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13660 cmp r3, #0 13661 bxeq lr @ nothing to do - jump to real handler 13662 EXPORT_PC() 13663 mov r0, rPC @ arg0 13664 mov r1, rFP @ arg1 13665 mov r2, rSELF @ arg2 13666 b dvmCheckBefore @ (dPC,dFP,self) tail call 13667 13668 /* ------------------------------ */ 13669 .balign 64 13670 .L_ALT_OP_MUL_DOUBLE: /* 0xad */ 13671 /* File: armv5te/alt_stub.S */ 13672 /* 13673 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13674 * any interesting requests and then jump to the real instruction 13675 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13676 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13677 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13678 * bail to the real handler if breakFlags==0. 13679 */ 13680 ldrb r3, [rSELF, #offThread_breakFlags] 13681 adrl lr, dvmAsmInstructionStart + (173 * 64) 13682 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13683 cmp r3, #0 13684 bxeq lr @ nothing to do - jump to real handler 13685 EXPORT_PC() 13686 mov r0, rPC @ arg0 13687 mov r1, rFP @ arg1 13688 mov r2, rSELF @ arg2 13689 b dvmCheckBefore @ (dPC,dFP,self) tail call 13690 13691 /* ------------------------------ */ 13692 .balign 64 13693 .L_ALT_OP_DIV_DOUBLE: /* 0xae */ 13694 /* File: armv5te/alt_stub.S */ 13695 /* 13696 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13697 * any interesting requests and then jump to the real instruction 13698 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13699 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13700 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13701 * bail to the real handler if breakFlags==0. 13702 */ 13703 ldrb r3, [rSELF, #offThread_breakFlags] 13704 adrl lr, dvmAsmInstructionStart + (174 * 64) 13705 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13706 cmp r3, #0 13707 bxeq lr @ nothing to do - jump to real handler 13708 EXPORT_PC() 13709 mov r0, rPC @ arg0 13710 mov r1, rFP @ arg1 13711 mov r2, rSELF @ arg2 13712 b dvmCheckBefore @ (dPC,dFP,self) tail call 13713 13714 /* ------------------------------ */ 13715 .balign 64 13716 .L_ALT_OP_REM_DOUBLE: /* 0xaf */ 13717 /* File: armv5te/alt_stub.S */ 13718 /* 13719 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13720 * any interesting requests and then jump to the real instruction 13721 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13722 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13723 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13724 * bail to the real handler if breakFlags==0. 13725 */ 13726 ldrb r3, [rSELF, #offThread_breakFlags] 13727 adrl lr, dvmAsmInstructionStart + (175 * 64) 13728 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13729 cmp r3, #0 13730 bxeq lr @ nothing to do - jump to real handler 13731 EXPORT_PC() 13732 mov r0, rPC @ arg0 13733 mov r1, rFP @ arg1 13734 mov r2, rSELF @ arg2 13735 b dvmCheckBefore @ (dPC,dFP,self) tail call 13736 13737 /* ------------------------------ */ 13738 .balign 64 13739 .L_ALT_OP_ADD_INT_2ADDR: /* 0xb0 */ 13740 /* File: armv5te/alt_stub.S */ 13741 /* 13742 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13743 * any interesting requests and then jump to the real instruction 13744 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13745 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13746 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13747 * bail to the real handler if breakFlags==0. 13748 */ 13749 ldrb r3, [rSELF, #offThread_breakFlags] 13750 adrl lr, dvmAsmInstructionStart + (176 * 64) 13751 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13752 cmp r3, #0 13753 bxeq lr @ nothing to do - jump to real handler 13754 EXPORT_PC() 13755 mov r0, rPC @ arg0 13756 mov r1, rFP @ arg1 13757 mov r2, rSELF @ arg2 13758 b dvmCheckBefore @ (dPC,dFP,self) tail call 13759 13760 /* ------------------------------ */ 13761 .balign 64 13762 .L_ALT_OP_SUB_INT_2ADDR: /* 0xb1 */ 13763 /* File: armv5te/alt_stub.S */ 13764 /* 13765 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13766 * any interesting requests and then jump to the real instruction 13767 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13768 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13769 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13770 * bail to the real handler if breakFlags==0. 13771 */ 13772 ldrb r3, [rSELF, #offThread_breakFlags] 13773 adrl lr, dvmAsmInstructionStart + (177 * 64) 13774 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13775 cmp r3, #0 13776 bxeq lr @ nothing to do - jump to real handler 13777 EXPORT_PC() 13778 mov r0, rPC @ arg0 13779 mov r1, rFP @ arg1 13780 mov r2, rSELF @ arg2 13781 b dvmCheckBefore @ (dPC,dFP,self) tail call 13782 13783 /* ------------------------------ */ 13784 .balign 64 13785 .L_ALT_OP_MUL_INT_2ADDR: /* 0xb2 */ 13786 /* File: armv5te/alt_stub.S */ 13787 /* 13788 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13789 * any interesting requests and then jump to the real instruction 13790 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13791 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13792 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13793 * bail to the real handler if breakFlags==0. 13794 */ 13795 ldrb r3, [rSELF, #offThread_breakFlags] 13796 adrl lr, dvmAsmInstructionStart + (178 * 64) 13797 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13798 cmp r3, #0 13799 bxeq lr @ nothing to do - jump to real handler 13800 EXPORT_PC() 13801 mov r0, rPC @ arg0 13802 mov r1, rFP @ arg1 13803 mov r2, rSELF @ arg2 13804 b dvmCheckBefore @ (dPC,dFP,self) tail call 13805 13806 /* ------------------------------ */ 13807 .balign 64 13808 .L_ALT_OP_DIV_INT_2ADDR: /* 0xb3 */ 13809 /* File: armv5te/alt_stub.S */ 13810 /* 13811 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13812 * any interesting requests and then jump to the real instruction 13813 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13814 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13815 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13816 * bail to the real handler if breakFlags==0. 13817 */ 13818 ldrb r3, [rSELF, #offThread_breakFlags] 13819 adrl lr, dvmAsmInstructionStart + (179 * 64) 13820 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13821 cmp r3, #0 13822 bxeq lr @ nothing to do - jump to real handler 13823 EXPORT_PC() 13824 mov r0, rPC @ arg0 13825 mov r1, rFP @ arg1 13826 mov r2, rSELF @ arg2 13827 b dvmCheckBefore @ (dPC,dFP,self) tail call 13828 13829 /* ------------------------------ */ 13830 .balign 64 13831 .L_ALT_OP_REM_INT_2ADDR: /* 0xb4 */ 13832 /* File: armv5te/alt_stub.S */ 13833 /* 13834 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13835 * any interesting requests and then jump to the real instruction 13836 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13837 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13838 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13839 * bail to the real handler if breakFlags==0. 13840 */ 13841 ldrb r3, [rSELF, #offThread_breakFlags] 13842 adrl lr, dvmAsmInstructionStart + (180 * 64) 13843 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13844 cmp r3, #0 13845 bxeq lr @ nothing to do - jump to real handler 13846 EXPORT_PC() 13847 mov r0, rPC @ arg0 13848 mov r1, rFP @ arg1 13849 mov r2, rSELF @ arg2 13850 b dvmCheckBefore @ (dPC,dFP,self) tail call 13851 13852 /* ------------------------------ */ 13853 .balign 64 13854 .L_ALT_OP_AND_INT_2ADDR: /* 0xb5 */ 13855 /* File: armv5te/alt_stub.S */ 13856 /* 13857 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13858 * any interesting requests and then jump to the real instruction 13859 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13860 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13861 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13862 * bail to the real handler if breakFlags==0. 13863 */ 13864 ldrb r3, [rSELF, #offThread_breakFlags] 13865 adrl lr, dvmAsmInstructionStart + (181 * 64) 13866 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13867 cmp r3, #0 13868 bxeq lr @ nothing to do - jump to real handler 13869 EXPORT_PC() 13870 mov r0, rPC @ arg0 13871 mov r1, rFP @ arg1 13872 mov r2, rSELF @ arg2 13873 b dvmCheckBefore @ (dPC,dFP,self) tail call 13874 13875 /* ------------------------------ */ 13876 .balign 64 13877 .L_ALT_OP_OR_INT_2ADDR: /* 0xb6 */ 13878 /* File: armv5te/alt_stub.S */ 13879 /* 13880 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13881 * any interesting requests and then jump to the real instruction 13882 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13883 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13884 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13885 * bail to the real handler if breakFlags==0. 13886 */ 13887 ldrb r3, [rSELF, #offThread_breakFlags] 13888 adrl lr, dvmAsmInstructionStart + (182 * 64) 13889 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13890 cmp r3, #0 13891 bxeq lr @ nothing to do - jump to real handler 13892 EXPORT_PC() 13893 mov r0, rPC @ arg0 13894 mov r1, rFP @ arg1 13895 mov r2, rSELF @ arg2 13896 b dvmCheckBefore @ (dPC,dFP,self) tail call 13897 13898 /* ------------------------------ */ 13899 .balign 64 13900 .L_ALT_OP_XOR_INT_2ADDR: /* 0xb7 */ 13901 /* File: armv5te/alt_stub.S */ 13902 /* 13903 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13904 * any interesting requests and then jump to the real instruction 13905 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13906 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13907 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13908 * bail to the real handler if breakFlags==0. 13909 */ 13910 ldrb r3, [rSELF, #offThread_breakFlags] 13911 adrl lr, dvmAsmInstructionStart + (183 * 64) 13912 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13913 cmp r3, #0 13914 bxeq lr @ nothing to do - jump to real handler 13915 EXPORT_PC() 13916 mov r0, rPC @ arg0 13917 mov r1, rFP @ arg1 13918 mov r2, rSELF @ arg2 13919 b dvmCheckBefore @ (dPC,dFP,self) tail call 13920 13921 /* ------------------------------ */ 13922 .balign 64 13923 .L_ALT_OP_SHL_INT_2ADDR: /* 0xb8 */ 13924 /* File: armv5te/alt_stub.S */ 13925 /* 13926 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13927 * any interesting requests and then jump to the real instruction 13928 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13929 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13930 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13931 * bail to the real handler if breakFlags==0. 13932 */ 13933 ldrb r3, [rSELF, #offThread_breakFlags] 13934 adrl lr, dvmAsmInstructionStart + (184 * 64) 13935 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13936 cmp r3, #0 13937 bxeq lr @ nothing to do - jump to real handler 13938 EXPORT_PC() 13939 mov r0, rPC @ arg0 13940 mov r1, rFP @ arg1 13941 mov r2, rSELF @ arg2 13942 b dvmCheckBefore @ (dPC,dFP,self) tail call 13943 13944 /* ------------------------------ */ 13945 .balign 64 13946 .L_ALT_OP_SHR_INT_2ADDR: /* 0xb9 */ 13947 /* File: armv5te/alt_stub.S */ 13948 /* 13949 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13950 * any interesting requests and then jump to the real instruction 13951 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13952 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13953 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13954 * bail to the real handler if breakFlags==0. 13955 */ 13956 ldrb r3, [rSELF, #offThread_breakFlags] 13957 adrl lr, dvmAsmInstructionStart + (185 * 64) 13958 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13959 cmp r3, #0 13960 bxeq lr @ nothing to do - jump to real handler 13961 EXPORT_PC() 13962 mov r0, rPC @ arg0 13963 mov r1, rFP @ arg1 13964 mov r2, rSELF @ arg2 13965 b dvmCheckBefore @ (dPC,dFP,self) tail call 13966 13967 /* ------------------------------ */ 13968 .balign 64 13969 .L_ALT_OP_USHR_INT_2ADDR: /* 0xba */ 13970 /* File: armv5te/alt_stub.S */ 13971 /* 13972 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13973 * any interesting requests and then jump to the real instruction 13974 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13975 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13976 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13977 * bail to the real handler if breakFlags==0. 13978 */ 13979 ldrb r3, [rSELF, #offThread_breakFlags] 13980 adrl lr, dvmAsmInstructionStart + (186 * 64) 13981 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13982 cmp r3, #0 13983 bxeq lr @ nothing to do - jump to real handler 13984 EXPORT_PC() 13985 mov r0, rPC @ arg0 13986 mov r1, rFP @ arg1 13987 mov r2, rSELF @ arg2 13988 b dvmCheckBefore @ (dPC,dFP,self) tail call 13989 13990 /* ------------------------------ */ 13991 .balign 64 13992 .L_ALT_OP_ADD_LONG_2ADDR: /* 0xbb */ 13993 /* File: armv5te/alt_stub.S */ 13994 /* 13995 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13996 * any interesting requests and then jump to the real instruction 13997 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13998 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13999 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14000 * bail to the real handler if breakFlags==0. 14001 */ 14002 ldrb r3, [rSELF, #offThread_breakFlags] 14003 adrl lr, dvmAsmInstructionStart + (187 * 64) 14004 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14005 cmp r3, #0 14006 bxeq lr @ nothing to do - jump to real handler 14007 EXPORT_PC() 14008 mov r0, rPC @ arg0 14009 mov r1, rFP @ arg1 14010 mov r2, rSELF @ arg2 14011 b dvmCheckBefore @ (dPC,dFP,self) tail call 14012 14013 /* ------------------------------ */ 14014 .balign 64 14015 .L_ALT_OP_SUB_LONG_2ADDR: /* 0xbc */ 14016 /* File: armv5te/alt_stub.S */ 14017 /* 14018 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14019 * any interesting requests and then jump to the real instruction 14020 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14021 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14022 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14023 * bail to the real handler if breakFlags==0. 14024 */ 14025 ldrb r3, [rSELF, #offThread_breakFlags] 14026 adrl lr, dvmAsmInstructionStart + (188 * 64) 14027 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14028 cmp r3, #0 14029 bxeq lr @ nothing to do - jump to real handler 14030 EXPORT_PC() 14031 mov r0, rPC @ arg0 14032 mov r1, rFP @ arg1 14033 mov r2, rSELF @ arg2 14034 b dvmCheckBefore @ (dPC,dFP,self) tail call 14035 14036 /* ------------------------------ */ 14037 .balign 64 14038 .L_ALT_OP_MUL_LONG_2ADDR: /* 0xbd */ 14039 /* File: armv5te/alt_stub.S */ 14040 /* 14041 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14042 * any interesting requests and then jump to the real instruction 14043 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14044 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14045 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14046 * bail to the real handler if breakFlags==0. 14047 */ 14048 ldrb r3, [rSELF, #offThread_breakFlags] 14049 adrl lr, dvmAsmInstructionStart + (189 * 64) 14050 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14051 cmp r3, #0 14052 bxeq lr @ nothing to do - jump to real handler 14053 EXPORT_PC() 14054 mov r0, rPC @ arg0 14055 mov r1, rFP @ arg1 14056 mov r2, rSELF @ arg2 14057 b dvmCheckBefore @ (dPC,dFP,self) tail call 14058 14059 /* ------------------------------ */ 14060 .balign 64 14061 .L_ALT_OP_DIV_LONG_2ADDR: /* 0xbe */ 14062 /* File: armv5te/alt_stub.S */ 14063 /* 14064 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14065 * any interesting requests and then jump to the real instruction 14066 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14067 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14068 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14069 * bail to the real handler if breakFlags==0. 14070 */ 14071 ldrb r3, [rSELF, #offThread_breakFlags] 14072 adrl lr, dvmAsmInstructionStart + (190 * 64) 14073 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14074 cmp r3, #0 14075 bxeq lr @ nothing to do - jump to real handler 14076 EXPORT_PC() 14077 mov r0, rPC @ arg0 14078 mov r1, rFP @ arg1 14079 mov r2, rSELF @ arg2 14080 b dvmCheckBefore @ (dPC,dFP,self) tail call 14081 14082 /* ------------------------------ */ 14083 .balign 64 14084 .L_ALT_OP_REM_LONG_2ADDR: /* 0xbf */ 14085 /* File: armv5te/alt_stub.S */ 14086 /* 14087 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14088 * any interesting requests and then jump to the real instruction 14089 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14090 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14091 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14092 * bail to the real handler if breakFlags==0. 14093 */ 14094 ldrb r3, [rSELF, #offThread_breakFlags] 14095 adrl lr, dvmAsmInstructionStart + (191 * 64) 14096 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14097 cmp r3, #0 14098 bxeq lr @ nothing to do - jump to real handler 14099 EXPORT_PC() 14100 mov r0, rPC @ arg0 14101 mov r1, rFP @ arg1 14102 mov r2, rSELF @ arg2 14103 b dvmCheckBefore @ (dPC,dFP,self) tail call 14104 14105 /* ------------------------------ */ 14106 .balign 64 14107 .L_ALT_OP_AND_LONG_2ADDR: /* 0xc0 */ 14108 /* File: armv5te/alt_stub.S */ 14109 /* 14110 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14111 * any interesting requests and then jump to the real instruction 14112 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14113 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14114 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14115 * bail to the real handler if breakFlags==0. 14116 */ 14117 ldrb r3, [rSELF, #offThread_breakFlags] 14118 adrl lr, dvmAsmInstructionStart + (192 * 64) 14119 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14120 cmp r3, #0 14121 bxeq lr @ nothing to do - jump to real handler 14122 EXPORT_PC() 14123 mov r0, rPC @ arg0 14124 mov r1, rFP @ arg1 14125 mov r2, rSELF @ arg2 14126 b dvmCheckBefore @ (dPC,dFP,self) tail call 14127 14128 /* ------------------------------ */ 14129 .balign 64 14130 .L_ALT_OP_OR_LONG_2ADDR: /* 0xc1 */ 14131 /* File: armv5te/alt_stub.S */ 14132 /* 14133 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14134 * any interesting requests and then jump to the real instruction 14135 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14136 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14137 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14138 * bail to the real handler if breakFlags==0. 14139 */ 14140 ldrb r3, [rSELF, #offThread_breakFlags] 14141 adrl lr, dvmAsmInstructionStart + (193 * 64) 14142 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14143 cmp r3, #0 14144 bxeq lr @ nothing to do - jump to real handler 14145 EXPORT_PC() 14146 mov r0, rPC @ arg0 14147 mov r1, rFP @ arg1 14148 mov r2, rSELF @ arg2 14149 b dvmCheckBefore @ (dPC,dFP,self) tail call 14150 14151 /* ------------------------------ */ 14152 .balign 64 14153 .L_ALT_OP_XOR_LONG_2ADDR: /* 0xc2 */ 14154 /* File: armv5te/alt_stub.S */ 14155 /* 14156 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14157 * any interesting requests and then jump to the real instruction 14158 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14159 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14160 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14161 * bail to the real handler if breakFlags==0. 14162 */ 14163 ldrb r3, [rSELF, #offThread_breakFlags] 14164 adrl lr, dvmAsmInstructionStart + (194 * 64) 14165 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14166 cmp r3, #0 14167 bxeq lr @ nothing to do - jump to real handler 14168 EXPORT_PC() 14169 mov r0, rPC @ arg0 14170 mov r1, rFP @ arg1 14171 mov r2, rSELF @ arg2 14172 b dvmCheckBefore @ (dPC,dFP,self) tail call 14173 14174 /* ------------------------------ */ 14175 .balign 64 14176 .L_ALT_OP_SHL_LONG_2ADDR: /* 0xc3 */ 14177 /* File: armv5te/alt_stub.S */ 14178 /* 14179 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14180 * any interesting requests and then jump to the real instruction 14181 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14182 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14183 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14184 * bail to the real handler if breakFlags==0. 14185 */ 14186 ldrb r3, [rSELF, #offThread_breakFlags] 14187 adrl lr, dvmAsmInstructionStart + (195 * 64) 14188 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14189 cmp r3, #0 14190 bxeq lr @ nothing to do - jump to real handler 14191 EXPORT_PC() 14192 mov r0, rPC @ arg0 14193 mov r1, rFP @ arg1 14194 mov r2, rSELF @ arg2 14195 b dvmCheckBefore @ (dPC,dFP,self) tail call 14196 14197 /* ------------------------------ */ 14198 .balign 64 14199 .L_ALT_OP_SHR_LONG_2ADDR: /* 0xc4 */ 14200 /* File: armv5te/alt_stub.S */ 14201 /* 14202 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14203 * any interesting requests and then jump to the real instruction 14204 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14205 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14206 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14207 * bail to the real handler if breakFlags==0. 14208 */ 14209 ldrb r3, [rSELF, #offThread_breakFlags] 14210 adrl lr, dvmAsmInstructionStart + (196 * 64) 14211 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14212 cmp r3, #0 14213 bxeq lr @ nothing to do - jump to real handler 14214 EXPORT_PC() 14215 mov r0, rPC @ arg0 14216 mov r1, rFP @ arg1 14217 mov r2, rSELF @ arg2 14218 b dvmCheckBefore @ (dPC,dFP,self) tail call 14219 14220 /* ------------------------------ */ 14221 .balign 64 14222 .L_ALT_OP_USHR_LONG_2ADDR: /* 0xc5 */ 14223 /* File: armv5te/alt_stub.S */ 14224 /* 14225 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14226 * any interesting requests and then jump to the real instruction 14227 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14228 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14229 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14230 * bail to the real handler if breakFlags==0. 14231 */ 14232 ldrb r3, [rSELF, #offThread_breakFlags] 14233 adrl lr, dvmAsmInstructionStart + (197 * 64) 14234 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14235 cmp r3, #0 14236 bxeq lr @ nothing to do - jump to real handler 14237 EXPORT_PC() 14238 mov r0, rPC @ arg0 14239 mov r1, rFP @ arg1 14240 mov r2, rSELF @ arg2 14241 b dvmCheckBefore @ (dPC,dFP,self) tail call 14242 14243 /* ------------------------------ */ 14244 .balign 64 14245 .L_ALT_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 14246 /* File: armv5te/alt_stub.S */ 14247 /* 14248 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14249 * any interesting requests and then jump to the real instruction 14250 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14251 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14252 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14253 * bail to the real handler if breakFlags==0. 14254 */ 14255 ldrb r3, [rSELF, #offThread_breakFlags] 14256 adrl lr, dvmAsmInstructionStart + (198 * 64) 14257 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14258 cmp r3, #0 14259 bxeq lr @ nothing to do - jump to real handler 14260 EXPORT_PC() 14261 mov r0, rPC @ arg0 14262 mov r1, rFP @ arg1 14263 mov r2, rSELF @ arg2 14264 b dvmCheckBefore @ (dPC,dFP,self) tail call 14265 14266 /* ------------------------------ */ 14267 .balign 64 14268 .L_ALT_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 14269 /* File: armv5te/alt_stub.S */ 14270 /* 14271 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14272 * any interesting requests and then jump to the real instruction 14273 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14274 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14275 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14276 * bail to the real handler if breakFlags==0. 14277 */ 14278 ldrb r3, [rSELF, #offThread_breakFlags] 14279 adrl lr, dvmAsmInstructionStart + (199 * 64) 14280 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14281 cmp r3, #0 14282 bxeq lr @ nothing to do - jump to real handler 14283 EXPORT_PC() 14284 mov r0, rPC @ arg0 14285 mov r1, rFP @ arg1 14286 mov r2, rSELF @ arg2 14287 b dvmCheckBefore @ (dPC,dFP,self) tail call 14288 14289 /* ------------------------------ */ 14290 .balign 64 14291 .L_ALT_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 14292 /* File: armv5te/alt_stub.S */ 14293 /* 14294 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14295 * any interesting requests and then jump to the real instruction 14296 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14297 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14298 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14299 * bail to the real handler if breakFlags==0. 14300 */ 14301 ldrb r3, [rSELF, #offThread_breakFlags] 14302 adrl lr, dvmAsmInstructionStart + (200 * 64) 14303 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14304 cmp r3, #0 14305 bxeq lr @ nothing to do - jump to real handler 14306 EXPORT_PC() 14307 mov r0, rPC @ arg0 14308 mov r1, rFP @ arg1 14309 mov r2, rSELF @ arg2 14310 b dvmCheckBefore @ (dPC,dFP,self) tail call 14311 14312 /* ------------------------------ */ 14313 .balign 64 14314 .L_ALT_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 14315 /* File: armv5te/alt_stub.S */ 14316 /* 14317 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14318 * any interesting requests and then jump to the real instruction 14319 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14320 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14321 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14322 * bail to the real handler if breakFlags==0. 14323 */ 14324 ldrb r3, [rSELF, #offThread_breakFlags] 14325 adrl lr, dvmAsmInstructionStart + (201 * 64) 14326 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14327 cmp r3, #0 14328 bxeq lr @ nothing to do - jump to real handler 14329 EXPORT_PC() 14330 mov r0, rPC @ arg0 14331 mov r1, rFP @ arg1 14332 mov r2, rSELF @ arg2 14333 b dvmCheckBefore @ (dPC,dFP,self) tail call 14334 14335 /* ------------------------------ */ 14336 .balign 64 14337 .L_ALT_OP_REM_FLOAT_2ADDR: /* 0xca */ 14338 /* File: armv5te/alt_stub.S */ 14339 /* 14340 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14341 * any interesting requests and then jump to the real instruction 14342 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14343 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14344 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14345 * bail to the real handler if breakFlags==0. 14346 */ 14347 ldrb r3, [rSELF, #offThread_breakFlags] 14348 adrl lr, dvmAsmInstructionStart + (202 * 64) 14349 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14350 cmp r3, #0 14351 bxeq lr @ nothing to do - jump to real handler 14352 EXPORT_PC() 14353 mov r0, rPC @ arg0 14354 mov r1, rFP @ arg1 14355 mov r2, rSELF @ arg2 14356 b dvmCheckBefore @ (dPC,dFP,self) tail call 14357 14358 /* ------------------------------ */ 14359 .balign 64 14360 .L_ALT_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 14361 /* File: armv5te/alt_stub.S */ 14362 /* 14363 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14364 * any interesting requests and then jump to the real instruction 14365 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14366 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14367 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14368 * bail to the real handler if breakFlags==0. 14369 */ 14370 ldrb r3, [rSELF, #offThread_breakFlags] 14371 adrl lr, dvmAsmInstructionStart + (203 * 64) 14372 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14373 cmp r3, #0 14374 bxeq lr @ nothing to do - jump to real handler 14375 EXPORT_PC() 14376 mov r0, rPC @ arg0 14377 mov r1, rFP @ arg1 14378 mov r2, rSELF @ arg2 14379 b dvmCheckBefore @ (dPC,dFP,self) tail call 14380 14381 /* ------------------------------ */ 14382 .balign 64 14383 .L_ALT_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 14384 /* File: armv5te/alt_stub.S */ 14385 /* 14386 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14387 * any interesting requests and then jump to the real instruction 14388 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14389 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14390 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14391 * bail to the real handler if breakFlags==0. 14392 */ 14393 ldrb r3, [rSELF, #offThread_breakFlags] 14394 adrl lr, dvmAsmInstructionStart + (204 * 64) 14395 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14396 cmp r3, #0 14397 bxeq lr @ nothing to do - jump to real handler 14398 EXPORT_PC() 14399 mov r0, rPC @ arg0 14400 mov r1, rFP @ arg1 14401 mov r2, rSELF @ arg2 14402 b dvmCheckBefore @ (dPC,dFP,self) tail call 14403 14404 /* ------------------------------ */ 14405 .balign 64 14406 .L_ALT_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 14407 /* File: armv5te/alt_stub.S */ 14408 /* 14409 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14410 * any interesting requests and then jump to the real instruction 14411 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14412 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14413 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14414 * bail to the real handler if breakFlags==0. 14415 */ 14416 ldrb r3, [rSELF, #offThread_breakFlags] 14417 adrl lr, dvmAsmInstructionStart + (205 * 64) 14418 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14419 cmp r3, #0 14420 bxeq lr @ nothing to do - jump to real handler 14421 EXPORT_PC() 14422 mov r0, rPC @ arg0 14423 mov r1, rFP @ arg1 14424 mov r2, rSELF @ arg2 14425 b dvmCheckBefore @ (dPC,dFP,self) tail call 14426 14427 /* ------------------------------ */ 14428 .balign 64 14429 .L_ALT_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 14430 /* File: armv5te/alt_stub.S */ 14431 /* 14432 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14433 * any interesting requests and then jump to the real instruction 14434 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14435 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14436 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14437 * bail to the real handler if breakFlags==0. 14438 */ 14439 ldrb r3, [rSELF, #offThread_breakFlags] 14440 adrl lr, dvmAsmInstructionStart + (206 * 64) 14441 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14442 cmp r3, #0 14443 bxeq lr @ nothing to do - jump to real handler 14444 EXPORT_PC() 14445 mov r0, rPC @ arg0 14446 mov r1, rFP @ arg1 14447 mov r2, rSELF @ arg2 14448 b dvmCheckBefore @ (dPC,dFP,self) tail call 14449 14450 /* ------------------------------ */ 14451 .balign 64 14452 .L_ALT_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 14453 /* File: armv5te/alt_stub.S */ 14454 /* 14455 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14456 * any interesting requests and then jump to the real instruction 14457 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14458 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14459 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14460 * bail to the real handler if breakFlags==0. 14461 */ 14462 ldrb r3, [rSELF, #offThread_breakFlags] 14463 adrl lr, dvmAsmInstructionStart + (207 * 64) 14464 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14465 cmp r3, #0 14466 bxeq lr @ nothing to do - jump to real handler 14467 EXPORT_PC() 14468 mov r0, rPC @ arg0 14469 mov r1, rFP @ arg1 14470 mov r2, rSELF @ arg2 14471 b dvmCheckBefore @ (dPC,dFP,self) tail call 14472 14473 /* ------------------------------ */ 14474 .balign 64 14475 .L_ALT_OP_ADD_INT_LIT16: /* 0xd0 */ 14476 /* File: armv5te/alt_stub.S */ 14477 /* 14478 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14479 * any interesting requests and then jump to the real instruction 14480 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14481 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14482 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14483 * bail to the real handler if breakFlags==0. 14484 */ 14485 ldrb r3, [rSELF, #offThread_breakFlags] 14486 adrl lr, dvmAsmInstructionStart + (208 * 64) 14487 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14488 cmp r3, #0 14489 bxeq lr @ nothing to do - jump to real handler 14490 EXPORT_PC() 14491 mov r0, rPC @ arg0 14492 mov r1, rFP @ arg1 14493 mov r2, rSELF @ arg2 14494 b dvmCheckBefore @ (dPC,dFP,self) tail call 14495 14496 /* ------------------------------ */ 14497 .balign 64 14498 .L_ALT_OP_RSUB_INT: /* 0xd1 */ 14499 /* File: armv5te/alt_stub.S */ 14500 /* 14501 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14502 * any interesting requests and then jump to the real instruction 14503 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14504 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14505 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14506 * bail to the real handler if breakFlags==0. 14507 */ 14508 ldrb r3, [rSELF, #offThread_breakFlags] 14509 adrl lr, dvmAsmInstructionStart + (209 * 64) 14510 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14511 cmp r3, #0 14512 bxeq lr @ nothing to do - jump to real handler 14513 EXPORT_PC() 14514 mov r0, rPC @ arg0 14515 mov r1, rFP @ arg1 14516 mov r2, rSELF @ arg2 14517 b dvmCheckBefore @ (dPC,dFP,self) tail call 14518 14519 /* ------------------------------ */ 14520 .balign 64 14521 .L_ALT_OP_MUL_INT_LIT16: /* 0xd2 */ 14522 /* File: armv5te/alt_stub.S */ 14523 /* 14524 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14525 * any interesting requests and then jump to the real instruction 14526 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14527 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14528 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14529 * bail to the real handler if breakFlags==0. 14530 */ 14531 ldrb r3, [rSELF, #offThread_breakFlags] 14532 adrl lr, dvmAsmInstructionStart + (210 * 64) 14533 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14534 cmp r3, #0 14535 bxeq lr @ nothing to do - jump to real handler 14536 EXPORT_PC() 14537 mov r0, rPC @ arg0 14538 mov r1, rFP @ arg1 14539 mov r2, rSELF @ arg2 14540 b dvmCheckBefore @ (dPC,dFP,self) tail call 14541 14542 /* ------------------------------ */ 14543 .balign 64 14544 .L_ALT_OP_DIV_INT_LIT16: /* 0xd3 */ 14545 /* File: armv5te/alt_stub.S */ 14546 /* 14547 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14548 * any interesting requests and then jump to the real instruction 14549 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14550 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14551 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14552 * bail to the real handler if breakFlags==0. 14553 */ 14554 ldrb r3, [rSELF, #offThread_breakFlags] 14555 adrl lr, dvmAsmInstructionStart + (211 * 64) 14556 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14557 cmp r3, #0 14558 bxeq lr @ nothing to do - jump to real handler 14559 EXPORT_PC() 14560 mov r0, rPC @ arg0 14561 mov r1, rFP @ arg1 14562 mov r2, rSELF @ arg2 14563 b dvmCheckBefore @ (dPC,dFP,self) tail call 14564 14565 /* ------------------------------ */ 14566 .balign 64 14567 .L_ALT_OP_REM_INT_LIT16: /* 0xd4 */ 14568 /* File: armv5te/alt_stub.S */ 14569 /* 14570 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14571 * any interesting requests and then jump to the real instruction 14572 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14573 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14574 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14575 * bail to the real handler if breakFlags==0. 14576 */ 14577 ldrb r3, [rSELF, #offThread_breakFlags] 14578 adrl lr, dvmAsmInstructionStart + (212 * 64) 14579 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14580 cmp r3, #0 14581 bxeq lr @ nothing to do - jump to real handler 14582 EXPORT_PC() 14583 mov r0, rPC @ arg0 14584 mov r1, rFP @ arg1 14585 mov r2, rSELF @ arg2 14586 b dvmCheckBefore @ (dPC,dFP,self) tail call 14587 14588 /* ------------------------------ */ 14589 .balign 64 14590 .L_ALT_OP_AND_INT_LIT16: /* 0xd5 */ 14591 /* File: armv5te/alt_stub.S */ 14592 /* 14593 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14594 * any interesting requests and then jump to the real instruction 14595 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14596 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14597 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14598 * bail to the real handler if breakFlags==0. 14599 */ 14600 ldrb r3, [rSELF, #offThread_breakFlags] 14601 adrl lr, dvmAsmInstructionStart + (213 * 64) 14602 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14603 cmp r3, #0 14604 bxeq lr @ nothing to do - jump to real handler 14605 EXPORT_PC() 14606 mov r0, rPC @ arg0 14607 mov r1, rFP @ arg1 14608 mov r2, rSELF @ arg2 14609 b dvmCheckBefore @ (dPC,dFP,self) tail call 14610 14611 /* ------------------------------ */ 14612 .balign 64 14613 .L_ALT_OP_OR_INT_LIT16: /* 0xd6 */ 14614 /* File: armv5te/alt_stub.S */ 14615 /* 14616 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14617 * any interesting requests and then jump to the real instruction 14618 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14619 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14620 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14621 * bail to the real handler if breakFlags==0. 14622 */ 14623 ldrb r3, [rSELF, #offThread_breakFlags] 14624 adrl lr, dvmAsmInstructionStart + (214 * 64) 14625 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14626 cmp r3, #0 14627 bxeq lr @ nothing to do - jump to real handler 14628 EXPORT_PC() 14629 mov r0, rPC @ arg0 14630 mov r1, rFP @ arg1 14631 mov r2, rSELF @ arg2 14632 b dvmCheckBefore @ (dPC,dFP,self) tail call 14633 14634 /* ------------------------------ */ 14635 .balign 64 14636 .L_ALT_OP_XOR_INT_LIT16: /* 0xd7 */ 14637 /* File: armv5te/alt_stub.S */ 14638 /* 14639 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14640 * any interesting requests and then jump to the real instruction 14641 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14642 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14643 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14644 * bail to the real handler if breakFlags==0. 14645 */ 14646 ldrb r3, [rSELF, #offThread_breakFlags] 14647 adrl lr, dvmAsmInstructionStart + (215 * 64) 14648 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14649 cmp r3, #0 14650 bxeq lr @ nothing to do - jump to real handler 14651 EXPORT_PC() 14652 mov r0, rPC @ arg0 14653 mov r1, rFP @ arg1 14654 mov r2, rSELF @ arg2 14655 b dvmCheckBefore @ (dPC,dFP,self) tail call 14656 14657 /* ------------------------------ */ 14658 .balign 64 14659 .L_ALT_OP_ADD_INT_LIT8: /* 0xd8 */ 14660 /* File: armv5te/alt_stub.S */ 14661 /* 14662 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14663 * any interesting requests and then jump to the real instruction 14664 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14665 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14666 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14667 * bail to the real handler if breakFlags==0. 14668 */ 14669 ldrb r3, [rSELF, #offThread_breakFlags] 14670 adrl lr, dvmAsmInstructionStart + (216 * 64) 14671 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14672 cmp r3, #0 14673 bxeq lr @ nothing to do - jump to real handler 14674 EXPORT_PC() 14675 mov r0, rPC @ arg0 14676 mov r1, rFP @ arg1 14677 mov r2, rSELF @ arg2 14678 b dvmCheckBefore @ (dPC,dFP,self) tail call 14679 14680 /* ------------------------------ */ 14681 .balign 64 14682 .L_ALT_OP_RSUB_INT_LIT8: /* 0xd9 */ 14683 /* File: armv5te/alt_stub.S */ 14684 /* 14685 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14686 * any interesting requests and then jump to the real instruction 14687 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14688 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14689 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14690 * bail to the real handler if breakFlags==0. 14691 */ 14692 ldrb r3, [rSELF, #offThread_breakFlags] 14693 adrl lr, dvmAsmInstructionStart + (217 * 64) 14694 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14695 cmp r3, #0 14696 bxeq lr @ nothing to do - jump to real handler 14697 EXPORT_PC() 14698 mov r0, rPC @ arg0 14699 mov r1, rFP @ arg1 14700 mov r2, rSELF @ arg2 14701 b dvmCheckBefore @ (dPC,dFP,self) tail call 14702 14703 /* ------------------------------ */ 14704 .balign 64 14705 .L_ALT_OP_MUL_INT_LIT8: /* 0xda */ 14706 /* File: armv5te/alt_stub.S */ 14707 /* 14708 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14709 * any interesting requests and then jump to the real instruction 14710 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14711 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14712 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14713 * bail to the real handler if breakFlags==0. 14714 */ 14715 ldrb r3, [rSELF, #offThread_breakFlags] 14716 adrl lr, dvmAsmInstructionStart + (218 * 64) 14717 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14718 cmp r3, #0 14719 bxeq lr @ nothing to do - jump to real handler 14720 EXPORT_PC() 14721 mov r0, rPC @ arg0 14722 mov r1, rFP @ arg1 14723 mov r2, rSELF @ arg2 14724 b dvmCheckBefore @ (dPC,dFP,self) tail call 14725 14726 /* ------------------------------ */ 14727 .balign 64 14728 .L_ALT_OP_DIV_INT_LIT8: /* 0xdb */ 14729 /* File: armv5te/alt_stub.S */ 14730 /* 14731 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14732 * any interesting requests and then jump to the real instruction 14733 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14734 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14735 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14736 * bail to the real handler if breakFlags==0. 14737 */ 14738 ldrb r3, [rSELF, #offThread_breakFlags] 14739 adrl lr, dvmAsmInstructionStart + (219 * 64) 14740 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14741 cmp r3, #0 14742 bxeq lr @ nothing to do - jump to real handler 14743 EXPORT_PC() 14744 mov r0, rPC @ arg0 14745 mov r1, rFP @ arg1 14746 mov r2, rSELF @ arg2 14747 b dvmCheckBefore @ (dPC,dFP,self) tail call 14748 14749 /* ------------------------------ */ 14750 .balign 64 14751 .L_ALT_OP_REM_INT_LIT8: /* 0xdc */ 14752 /* File: armv5te/alt_stub.S */ 14753 /* 14754 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14755 * any interesting requests and then jump to the real instruction 14756 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14757 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14758 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14759 * bail to the real handler if breakFlags==0. 14760 */ 14761 ldrb r3, [rSELF, #offThread_breakFlags] 14762 adrl lr, dvmAsmInstructionStart + (220 * 64) 14763 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14764 cmp r3, #0 14765 bxeq lr @ nothing to do - jump to real handler 14766 EXPORT_PC() 14767 mov r0, rPC @ arg0 14768 mov r1, rFP @ arg1 14769 mov r2, rSELF @ arg2 14770 b dvmCheckBefore @ (dPC,dFP,self) tail call 14771 14772 /* ------------------------------ */ 14773 .balign 64 14774 .L_ALT_OP_AND_INT_LIT8: /* 0xdd */ 14775 /* File: armv5te/alt_stub.S */ 14776 /* 14777 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14778 * any interesting requests and then jump to the real instruction 14779 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14780 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14781 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14782 * bail to the real handler if breakFlags==0. 14783 */ 14784 ldrb r3, [rSELF, #offThread_breakFlags] 14785 adrl lr, dvmAsmInstructionStart + (221 * 64) 14786 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14787 cmp r3, #0 14788 bxeq lr @ nothing to do - jump to real handler 14789 EXPORT_PC() 14790 mov r0, rPC @ arg0 14791 mov r1, rFP @ arg1 14792 mov r2, rSELF @ arg2 14793 b dvmCheckBefore @ (dPC,dFP,self) tail call 14794 14795 /* ------------------------------ */ 14796 .balign 64 14797 .L_ALT_OP_OR_INT_LIT8: /* 0xde */ 14798 /* File: armv5te/alt_stub.S */ 14799 /* 14800 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14801 * any interesting requests and then jump to the real instruction 14802 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14803 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14804 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14805 * bail to the real handler if breakFlags==0. 14806 */ 14807 ldrb r3, [rSELF, #offThread_breakFlags] 14808 adrl lr, dvmAsmInstructionStart + (222 * 64) 14809 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14810 cmp r3, #0 14811 bxeq lr @ nothing to do - jump to real handler 14812 EXPORT_PC() 14813 mov r0, rPC @ arg0 14814 mov r1, rFP @ arg1 14815 mov r2, rSELF @ arg2 14816 b dvmCheckBefore @ (dPC,dFP,self) tail call 14817 14818 /* ------------------------------ */ 14819 .balign 64 14820 .L_ALT_OP_XOR_INT_LIT8: /* 0xdf */ 14821 /* File: armv5te/alt_stub.S */ 14822 /* 14823 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14824 * any interesting requests and then jump to the real instruction 14825 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14826 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14827 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14828 * bail to the real handler if breakFlags==0. 14829 */ 14830 ldrb r3, [rSELF, #offThread_breakFlags] 14831 adrl lr, dvmAsmInstructionStart + (223 * 64) 14832 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14833 cmp r3, #0 14834 bxeq lr @ nothing to do - jump to real handler 14835 EXPORT_PC() 14836 mov r0, rPC @ arg0 14837 mov r1, rFP @ arg1 14838 mov r2, rSELF @ arg2 14839 b dvmCheckBefore @ (dPC,dFP,self) tail call 14840 14841 /* ------------------------------ */ 14842 .balign 64 14843 .L_ALT_OP_SHL_INT_LIT8: /* 0xe0 */ 14844 /* File: armv5te/alt_stub.S */ 14845 /* 14846 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14847 * any interesting requests and then jump to the real instruction 14848 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14849 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14850 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14851 * bail to the real handler if breakFlags==0. 14852 */ 14853 ldrb r3, [rSELF, #offThread_breakFlags] 14854 adrl lr, dvmAsmInstructionStart + (224 * 64) 14855 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14856 cmp r3, #0 14857 bxeq lr @ nothing to do - jump to real handler 14858 EXPORT_PC() 14859 mov r0, rPC @ arg0 14860 mov r1, rFP @ arg1 14861 mov r2, rSELF @ arg2 14862 b dvmCheckBefore @ (dPC,dFP,self) tail call 14863 14864 /* ------------------------------ */ 14865 .balign 64 14866 .L_ALT_OP_SHR_INT_LIT8: /* 0xe1 */ 14867 /* File: armv5te/alt_stub.S */ 14868 /* 14869 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14870 * any interesting requests and then jump to the real instruction 14871 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14872 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14873 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14874 * bail to the real handler if breakFlags==0. 14875 */ 14876 ldrb r3, [rSELF, #offThread_breakFlags] 14877 adrl lr, dvmAsmInstructionStart + (225 * 64) 14878 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14879 cmp r3, #0 14880 bxeq lr @ nothing to do - jump to real handler 14881 EXPORT_PC() 14882 mov r0, rPC @ arg0 14883 mov r1, rFP @ arg1 14884 mov r2, rSELF @ arg2 14885 b dvmCheckBefore @ (dPC,dFP,self) tail call 14886 14887 /* ------------------------------ */ 14888 .balign 64 14889 .L_ALT_OP_USHR_INT_LIT8: /* 0xe2 */ 14890 /* File: armv5te/alt_stub.S */ 14891 /* 14892 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14893 * any interesting requests and then jump to the real instruction 14894 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14895 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14896 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14897 * bail to the real handler if breakFlags==0. 14898 */ 14899 ldrb r3, [rSELF, #offThread_breakFlags] 14900 adrl lr, dvmAsmInstructionStart + (226 * 64) 14901 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14902 cmp r3, #0 14903 bxeq lr @ nothing to do - jump to real handler 14904 EXPORT_PC() 14905 mov r0, rPC @ arg0 14906 mov r1, rFP @ arg1 14907 mov r2, rSELF @ arg2 14908 b dvmCheckBefore @ (dPC,dFP,self) tail call 14909 14910 /* ------------------------------ */ 14911 .balign 64 14912 .L_ALT_OP_IGET_VOLATILE: /* 0xe3 */ 14913 /* File: armv5te/alt_stub.S */ 14914 /* 14915 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14916 * any interesting requests and then jump to the real instruction 14917 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14918 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14919 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14920 * bail to the real handler if breakFlags==0. 14921 */ 14922 ldrb r3, [rSELF, #offThread_breakFlags] 14923 adrl lr, dvmAsmInstructionStart + (227 * 64) 14924 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14925 cmp r3, #0 14926 bxeq lr @ nothing to do - jump to real handler 14927 EXPORT_PC() 14928 mov r0, rPC @ arg0 14929 mov r1, rFP @ arg1 14930 mov r2, rSELF @ arg2 14931 b dvmCheckBefore @ (dPC,dFP,self) tail call 14932 14933 /* ------------------------------ */ 14934 .balign 64 14935 .L_ALT_OP_IPUT_VOLATILE: /* 0xe4 */ 14936 /* File: armv5te/alt_stub.S */ 14937 /* 14938 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14939 * any interesting requests and then jump to the real instruction 14940 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14941 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14942 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14943 * bail to the real handler if breakFlags==0. 14944 */ 14945 ldrb r3, [rSELF, #offThread_breakFlags] 14946 adrl lr, dvmAsmInstructionStart + (228 * 64) 14947 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14948 cmp r3, #0 14949 bxeq lr @ nothing to do - jump to real handler 14950 EXPORT_PC() 14951 mov r0, rPC @ arg0 14952 mov r1, rFP @ arg1 14953 mov r2, rSELF @ arg2 14954 b dvmCheckBefore @ (dPC,dFP,self) tail call 14955 14956 /* ------------------------------ */ 14957 .balign 64 14958 .L_ALT_OP_SGET_VOLATILE: /* 0xe5 */ 14959 /* File: armv5te/alt_stub.S */ 14960 /* 14961 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14962 * any interesting requests and then jump to the real instruction 14963 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14964 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14965 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14966 * bail to the real handler if breakFlags==0. 14967 */ 14968 ldrb r3, [rSELF, #offThread_breakFlags] 14969 adrl lr, dvmAsmInstructionStart + (229 * 64) 14970 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14971 cmp r3, #0 14972 bxeq lr @ nothing to do - jump to real handler 14973 EXPORT_PC() 14974 mov r0, rPC @ arg0 14975 mov r1, rFP @ arg1 14976 mov r2, rSELF @ arg2 14977 b dvmCheckBefore @ (dPC,dFP,self) tail call 14978 14979 /* ------------------------------ */ 14980 .balign 64 14981 .L_ALT_OP_SPUT_VOLATILE: /* 0xe6 */ 14982 /* File: armv5te/alt_stub.S */ 14983 /* 14984 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14985 * any interesting requests and then jump to the real instruction 14986 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14987 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14988 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14989 * bail to the real handler if breakFlags==0. 14990 */ 14991 ldrb r3, [rSELF, #offThread_breakFlags] 14992 adrl lr, dvmAsmInstructionStart + (230 * 64) 14993 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14994 cmp r3, #0 14995 bxeq lr @ nothing to do - jump to real handler 14996 EXPORT_PC() 14997 mov r0, rPC @ arg0 14998 mov r1, rFP @ arg1 14999 mov r2, rSELF @ arg2 15000 b dvmCheckBefore @ (dPC,dFP,self) tail call 15001 15002 /* ------------------------------ */ 15003 .balign 64 15004 .L_ALT_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 15005 /* File: armv5te/alt_stub.S */ 15006 /* 15007 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15008 * any interesting requests and then jump to the real instruction 15009 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15010 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15011 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15012 * bail to the real handler if breakFlags==0. 15013 */ 15014 ldrb r3, [rSELF, #offThread_breakFlags] 15015 adrl lr, dvmAsmInstructionStart + (231 * 64) 15016 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15017 cmp r3, #0 15018 bxeq lr @ nothing to do - jump to real handler 15019 EXPORT_PC() 15020 mov r0, rPC @ arg0 15021 mov r1, rFP @ arg1 15022 mov r2, rSELF @ arg2 15023 b dvmCheckBefore @ (dPC,dFP,self) tail call 15024 15025 /* ------------------------------ */ 15026 .balign 64 15027 .L_ALT_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 15028 /* File: armv5te/alt_stub.S */ 15029 /* 15030 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15031 * any interesting requests and then jump to the real instruction 15032 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15033 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15034 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15035 * bail to the real handler if breakFlags==0. 15036 */ 15037 ldrb r3, [rSELF, #offThread_breakFlags] 15038 adrl lr, dvmAsmInstructionStart + (232 * 64) 15039 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15040 cmp r3, #0 15041 bxeq lr @ nothing to do - jump to real handler 15042 EXPORT_PC() 15043 mov r0, rPC @ arg0 15044 mov r1, rFP @ arg1 15045 mov r2, rSELF @ arg2 15046 b dvmCheckBefore @ (dPC,dFP,self) tail call 15047 15048 /* ------------------------------ */ 15049 .balign 64 15050 .L_ALT_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 15051 /* File: armv5te/alt_stub.S */ 15052 /* 15053 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15054 * any interesting requests and then jump to the real instruction 15055 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15056 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15057 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15058 * bail to the real handler if breakFlags==0. 15059 */ 15060 ldrb r3, [rSELF, #offThread_breakFlags] 15061 adrl lr, dvmAsmInstructionStart + (233 * 64) 15062 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15063 cmp r3, #0 15064 bxeq lr @ nothing to do - jump to real handler 15065 EXPORT_PC() 15066 mov r0, rPC @ arg0 15067 mov r1, rFP @ arg1 15068 mov r2, rSELF @ arg2 15069 b dvmCheckBefore @ (dPC,dFP,self) tail call 15070 15071 /* ------------------------------ */ 15072 .balign 64 15073 .L_ALT_OP_SGET_WIDE_VOLATILE: /* 0xea */ 15074 /* File: armv5te/alt_stub.S */ 15075 /* 15076 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15077 * any interesting requests and then jump to the real instruction 15078 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15079 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15080 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15081 * bail to the real handler if breakFlags==0. 15082 */ 15083 ldrb r3, [rSELF, #offThread_breakFlags] 15084 adrl lr, dvmAsmInstructionStart + (234 * 64) 15085 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15086 cmp r3, #0 15087 bxeq lr @ nothing to do - jump to real handler 15088 EXPORT_PC() 15089 mov r0, rPC @ arg0 15090 mov r1, rFP @ arg1 15091 mov r2, rSELF @ arg2 15092 b dvmCheckBefore @ (dPC,dFP,self) tail call 15093 15094 /* ------------------------------ */ 15095 .balign 64 15096 .L_ALT_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 15097 /* File: armv5te/alt_stub.S */ 15098 /* 15099 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15100 * any interesting requests and then jump to the real instruction 15101 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15102 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15103 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15104 * bail to the real handler if breakFlags==0. 15105 */ 15106 ldrb r3, [rSELF, #offThread_breakFlags] 15107 adrl lr, dvmAsmInstructionStart + (235 * 64) 15108 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15109 cmp r3, #0 15110 bxeq lr @ nothing to do - jump to real handler 15111 EXPORT_PC() 15112 mov r0, rPC @ arg0 15113 mov r1, rFP @ arg1 15114 mov r2, rSELF @ arg2 15115 b dvmCheckBefore @ (dPC,dFP,self) tail call 15116 15117 /* ------------------------------ */ 15118 .balign 64 15119 .L_ALT_OP_BREAKPOINT: /* 0xec */ 15120 /* File: armv5te/alt_stub.S */ 15121 /* 15122 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15123 * any interesting requests and then jump to the real instruction 15124 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15125 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15126 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15127 * bail to the real handler if breakFlags==0. 15128 */ 15129 ldrb r3, [rSELF, #offThread_breakFlags] 15130 adrl lr, dvmAsmInstructionStart + (236 * 64) 15131 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15132 cmp r3, #0 15133 bxeq lr @ nothing to do - jump to real handler 15134 EXPORT_PC() 15135 mov r0, rPC @ arg0 15136 mov r1, rFP @ arg1 15137 mov r2, rSELF @ arg2 15138 b dvmCheckBefore @ (dPC,dFP,self) tail call 15139 15140 /* ------------------------------ */ 15141 .balign 64 15142 .L_ALT_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 15143 /* File: armv5te/alt_stub.S */ 15144 /* 15145 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15146 * any interesting requests and then jump to the real instruction 15147 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15148 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15149 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15150 * bail to the real handler if breakFlags==0. 15151 */ 15152 ldrb r3, [rSELF, #offThread_breakFlags] 15153 adrl lr, dvmAsmInstructionStart + (237 * 64) 15154 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15155 cmp r3, #0 15156 bxeq lr @ nothing to do - jump to real handler 15157 EXPORT_PC() 15158 mov r0, rPC @ arg0 15159 mov r1, rFP @ arg1 15160 mov r2, rSELF @ arg2 15161 b dvmCheckBefore @ (dPC,dFP,self) tail call 15162 15163 /* ------------------------------ */ 15164 .balign 64 15165 .L_ALT_OP_EXECUTE_INLINE: /* 0xee */ 15166 /* File: armv5te/alt_stub.S */ 15167 /* 15168 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15169 * any interesting requests and then jump to the real instruction 15170 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15171 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15172 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15173 * bail to the real handler if breakFlags==0. 15174 */ 15175 ldrb r3, [rSELF, #offThread_breakFlags] 15176 adrl lr, dvmAsmInstructionStart + (238 * 64) 15177 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15178 cmp r3, #0 15179 bxeq lr @ nothing to do - jump to real handler 15180 EXPORT_PC() 15181 mov r0, rPC @ arg0 15182 mov r1, rFP @ arg1 15183 mov r2, rSELF @ arg2 15184 b dvmCheckBefore @ (dPC,dFP,self) tail call 15185 15186 /* ------------------------------ */ 15187 .balign 64 15188 .L_ALT_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 15189 /* File: armv5te/alt_stub.S */ 15190 /* 15191 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15192 * any interesting requests and then jump to the real instruction 15193 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15194 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15195 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15196 * bail to the real handler if breakFlags==0. 15197 */ 15198 ldrb r3, [rSELF, #offThread_breakFlags] 15199 adrl lr, dvmAsmInstructionStart + (239 * 64) 15200 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15201 cmp r3, #0 15202 bxeq lr @ nothing to do - jump to real handler 15203 EXPORT_PC() 15204 mov r0, rPC @ arg0 15205 mov r1, rFP @ arg1 15206 mov r2, rSELF @ arg2 15207 b dvmCheckBefore @ (dPC,dFP,self) tail call 15208 15209 /* ------------------------------ */ 15210 .balign 64 15211 .L_ALT_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */ 15212 /* File: armv5te/alt_stub.S */ 15213 /* 15214 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15215 * any interesting requests and then jump to the real instruction 15216 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15217 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15218 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15219 * bail to the real handler if breakFlags==0. 15220 */ 15221 ldrb r3, [rSELF, #offThread_breakFlags] 15222 adrl lr, dvmAsmInstructionStart + (240 * 64) 15223 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15224 cmp r3, #0 15225 bxeq lr @ nothing to do - jump to real handler 15226 EXPORT_PC() 15227 mov r0, rPC @ arg0 15228 mov r1, rFP @ arg1 15229 mov r2, rSELF @ arg2 15230 b dvmCheckBefore @ (dPC,dFP,self) tail call 15231 15232 /* ------------------------------ */ 15233 .balign 64 15234 .L_ALT_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 15235 /* File: armv5te/alt_stub.S */ 15236 /* 15237 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15238 * any interesting requests and then jump to the real instruction 15239 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15240 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15241 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15242 * bail to the real handler if breakFlags==0. 15243 */ 15244 ldrb r3, [rSELF, #offThread_breakFlags] 15245 adrl lr, dvmAsmInstructionStart + (241 * 64) 15246 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15247 cmp r3, #0 15248 bxeq lr @ nothing to do - jump to real handler 15249 EXPORT_PC() 15250 mov r0, rPC @ arg0 15251 mov r1, rFP @ arg1 15252 mov r2, rSELF @ arg2 15253 b dvmCheckBefore @ (dPC,dFP,self) tail call 15254 15255 /* ------------------------------ */ 15256 .balign 64 15257 .L_ALT_OP_IGET_QUICK: /* 0xf2 */ 15258 /* File: armv5te/alt_stub.S */ 15259 /* 15260 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15261 * any interesting requests and then jump to the real instruction 15262 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15263 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15264 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15265 * bail to the real handler if breakFlags==0. 15266 */ 15267 ldrb r3, [rSELF, #offThread_breakFlags] 15268 adrl lr, dvmAsmInstructionStart + (242 * 64) 15269 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15270 cmp r3, #0 15271 bxeq lr @ nothing to do - jump to real handler 15272 EXPORT_PC() 15273 mov r0, rPC @ arg0 15274 mov r1, rFP @ arg1 15275 mov r2, rSELF @ arg2 15276 b dvmCheckBefore @ (dPC,dFP,self) tail call 15277 15278 /* ------------------------------ */ 15279 .balign 64 15280 .L_ALT_OP_IGET_WIDE_QUICK: /* 0xf3 */ 15281 /* File: armv5te/alt_stub.S */ 15282 /* 15283 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15284 * any interesting requests and then jump to the real instruction 15285 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15286 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15287 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15288 * bail to the real handler if breakFlags==0. 15289 */ 15290 ldrb r3, [rSELF, #offThread_breakFlags] 15291 adrl lr, dvmAsmInstructionStart + (243 * 64) 15292 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15293 cmp r3, #0 15294 bxeq lr @ nothing to do - jump to real handler 15295 EXPORT_PC() 15296 mov r0, rPC @ arg0 15297 mov r1, rFP @ arg1 15298 mov r2, rSELF @ arg2 15299 b dvmCheckBefore @ (dPC,dFP,self) tail call 15300 15301 /* ------------------------------ */ 15302 .balign 64 15303 .L_ALT_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 15304 /* File: armv5te/alt_stub.S */ 15305 /* 15306 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15307 * any interesting requests and then jump to the real instruction 15308 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15309 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15310 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15311 * bail to the real handler if breakFlags==0. 15312 */ 15313 ldrb r3, [rSELF, #offThread_breakFlags] 15314 adrl lr, dvmAsmInstructionStart + (244 * 64) 15315 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15316 cmp r3, #0 15317 bxeq lr @ nothing to do - jump to real handler 15318 EXPORT_PC() 15319 mov r0, rPC @ arg0 15320 mov r1, rFP @ arg1 15321 mov r2, rSELF @ arg2 15322 b dvmCheckBefore @ (dPC,dFP,self) tail call 15323 15324 /* ------------------------------ */ 15325 .balign 64 15326 .L_ALT_OP_IPUT_QUICK: /* 0xf5 */ 15327 /* File: armv5te/alt_stub.S */ 15328 /* 15329 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15330 * any interesting requests and then jump to the real instruction 15331 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15332 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15333 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15334 * bail to the real handler if breakFlags==0. 15335 */ 15336 ldrb r3, [rSELF, #offThread_breakFlags] 15337 adrl lr, dvmAsmInstructionStart + (245 * 64) 15338 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15339 cmp r3, #0 15340 bxeq lr @ nothing to do - jump to real handler 15341 EXPORT_PC() 15342 mov r0, rPC @ arg0 15343 mov r1, rFP @ arg1 15344 mov r2, rSELF @ arg2 15345 b dvmCheckBefore @ (dPC,dFP,self) tail call 15346 15347 /* ------------------------------ */ 15348 .balign 64 15349 .L_ALT_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 15350 /* File: armv5te/alt_stub.S */ 15351 /* 15352 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15353 * any interesting requests and then jump to the real instruction 15354 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15355 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15356 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15357 * bail to the real handler if breakFlags==0. 15358 */ 15359 ldrb r3, [rSELF, #offThread_breakFlags] 15360 adrl lr, dvmAsmInstructionStart + (246 * 64) 15361 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15362 cmp r3, #0 15363 bxeq lr @ nothing to do - jump to real handler 15364 EXPORT_PC() 15365 mov r0, rPC @ arg0 15366 mov r1, rFP @ arg1 15367 mov r2, rSELF @ arg2 15368 b dvmCheckBefore @ (dPC,dFP,self) tail call 15369 15370 /* ------------------------------ */ 15371 .balign 64 15372 .L_ALT_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 15373 /* File: armv5te/alt_stub.S */ 15374 /* 15375 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15376 * any interesting requests and then jump to the real instruction 15377 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15378 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15379 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15380 * bail to the real handler if breakFlags==0. 15381 */ 15382 ldrb r3, [rSELF, #offThread_breakFlags] 15383 adrl lr, dvmAsmInstructionStart + (247 * 64) 15384 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15385 cmp r3, #0 15386 bxeq lr @ nothing to do - jump to real handler 15387 EXPORT_PC() 15388 mov r0, rPC @ arg0 15389 mov r1, rFP @ arg1 15390 mov r2, rSELF @ arg2 15391 b dvmCheckBefore @ (dPC,dFP,self) tail call 15392 15393 /* ------------------------------ */ 15394 .balign 64 15395 .L_ALT_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 15396 /* File: armv5te/alt_stub.S */ 15397 /* 15398 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15399 * any interesting requests and then jump to the real instruction 15400 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15401 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15402 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15403 * bail to the real handler if breakFlags==0. 15404 */ 15405 ldrb r3, [rSELF, #offThread_breakFlags] 15406 adrl lr, dvmAsmInstructionStart + (248 * 64) 15407 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15408 cmp r3, #0 15409 bxeq lr @ nothing to do - jump to real handler 15410 EXPORT_PC() 15411 mov r0, rPC @ arg0 15412 mov r1, rFP @ arg1 15413 mov r2, rSELF @ arg2 15414 b dvmCheckBefore @ (dPC,dFP,self) tail call 15415 15416 /* ------------------------------ */ 15417 .balign 64 15418 .L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 15419 /* File: armv5te/alt_stub.S */ 15420 /* 15421 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15422 * any interesting requests and then jump to the real instruction 15423 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15424 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15425 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15426 * bail to the real handler if breakFlags==0. 15427 */ 15428 ldrb r3, [rSELF, #offThread_breakFlags] 15429 adrl lr, dvmAsmInstructionStart + (249 * 64) 15430 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15431 cmp r3, #0 15432 bxeq lr @ nothing to do - jump to real handler 15433 EXPORT_PC() 15434 mov r0, rPC @ arg0 15435 mov r1, rFP @ arg1 15436 mov r2, rSELF @ arg2 15437 b dvmCheckBefore @ (dPC,dFP,self) tail call 15438 15439 /* ------------------------------ */ 15440 .balign 64 15441 .L_ALT_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 15442 /* File: armv5te/alt_stub.S */ 15443 /* 15444 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15445 * any interesting requests and then jump to the real instruction 15446 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15447 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15448 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15449 * bail to the real handler if breakFlags==0. 15450 */ 15451 ldrb r3, [rSELF, #offThread_breakFlags] 15452 adrl lr, dvmAsmInstructionStart + (250 * 64) 15453 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15454 cmp r3, #0 15455 bxeq lr @ nothing to do - jump to real handler 15456 EXPORT_PC() 15457 mov r0, rPC @ arg0 15458 mov r1, rFP @ arg1 15459 mov r2, rSELF @ arg2 15460 b dvmCheckBefore @ (dPC,dFP,self) tail call 15461 15462 /* ------------------------------ */ 15463 .balign 64 15464 .L_ALT_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 15465 /* File: armv5te/alt_stub.S */ 15466 /* 15467 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15468 * any interesting requests and then jump to the real instruction 15469 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15470 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15471 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15472 * bail to the real handler if breakFlags==0. 15473 */ 15474 ldrb r3, [rSELF, #offThread_breakFlags] 15475 adrl lr, dvmAsmInstructionStart + (251 * 64) 15476 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15477 cmp r3, #0 15478 bxeq lr @ nothing to do - jump to real handler 15479 EXPORT_PC() 15480 mov r0, rPC @ arg0 15481 mov r1, rFP @ arg1 15482 mov r2, rSELF @ arg2 15483 b dvmCheckBefore @ (dPC,dFP,self) tail call 15484 15485 /* ------------------------------ */ 15486 .balign 64 15487 .L_ALT_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 15488 /* File: armv5te/alt_stub.S */ 15489 /* 15490 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15491 * any interesting requests and then jump to the real instruction 15492 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15493 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15494 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15495 * bail to the real handler if breakFlags==0. 15496 */ 15497 ldrb r3, [rSELF, #offThread_breakFlags] 15498 adrl lr, dvmAsmInstructionStart + (252 * 64) 15499 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15500 cmp r3, #0 15501 bxeq lr @ nothing to do - jump to real handler 15502 EXPORT_PC() 15503 mov r0, rPC @ arg0 15504 mov r1, rFP @ arg1 15505 mov r2, rSELF @ arg2 15506 b dvmCheckBefore @ (dPC,dFP,self) tail call 15507 15508 /* ------------------------------ */ 15509 .balign 64 15510 .L_ALT_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 15511 /* File: armv5te/alt_stub.S */ 15512 /* 15513 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15514 * any interesting requests and then jump to the real instruction 15515 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15516 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15517 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15518 * bail to the real handler if breakFlags==0. 15519 */ 15520 ldrb r3, [rSELF, #offThread_breakFlags] 15521 adrl lr, dvmAsmInstructionStart + (253 * 64) 15522 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15523 cmp r3, #0 15524 bxeq lr @ nothing to do - jump to real handler 15525 EXPORT_PC() 15526 mov r0, rPC @ arg0 15527 mov r1, rFP @ arg1 15528 mov r2, rSELF @ arg2 15529 b dvmCheckBefore @ (dPC,dFP,self) tail call 15530 15531 /* ------------------------------ */ 15532 .balign 64 15533 .L_ALT_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 15534 /* File: armv5te/alt_stub.S */ 15535 /* 15536 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15537 * any interesting requests and then jump to the real instruction 15538 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15539 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15540 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15541 * bail to the real handler if breakFlags==0. 15542 */ 15543 ldrb r3, [rSELF, #offThread_breakFlags] 15544 adrl lr, dvmAsmInstructionStart + (254 * 64) 15545 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15546 cmp r3, #0 15547 bxeq lr @ nothing to do - jump to real handler 15548 EXPORT_PC() 15549 mov r0, rPC @ arg0 15550 mov r1, rFP @ arg1 15551 mov r2, rSELF @ arg2 15552 b dvmCheckBefore @ (dPC,dFP,self) tail call 15553 15554 /* ------------------------------ */ 15555 .balign 64 15556 .L_ALT_OP_UNUSED_FF: /* 0xff */ 15557 /* File: armv5te/alt_stub.S */ 15558 /* 15559 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15560 * any interesting requests and then jump to the real instruction 15561 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15562 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15563 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15564 * bail to the real handler if breakFlags==0. 15565 */ 15566 ldrb r3, [rSELF, #offThread_breakFlags] 15567 adrl lr, dvmAsmInstructionStart + (255 * 64) 15568 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15569 cmp r3, #0 15570 bxeq lr @ nothing to do - jump to real handler 15571 EXPORT_PC() 15572 mov r0, rPC @ arg0 15573 mov r1, rFP @ arg1 15574 mov r2, rSELF @ arg2 15575 b dvmCheckBefore @ (dPC,dFP,self) tail call 15576 15577 .balign 64 15578 .size dvmAsmAltInstructionStart, .-dvmAsmAltInstructionStart 15579 .global dvmAsmAltInstructionEnd 15580 dvmAsmAltInstructionEnd: 15581 /* File: armv5te/footer.S */ 15582 /* 15583 * =========================================================================== 15584 * Common subroutines and data 15585 * =========================================================================== 15586 */ 15587 15588 .text 15589 .align 2 15590 15591 #if defined(WITH_JIT) 15592 15593 #if defined(WITH_SELF_VERIFICATION) 15594 /* 15595 * "longjmp" to a translation after single-stepping. Before returning 15596 * to translation, must save state for self-verification. 15597 */ 15598 .global dvmJitResumeTranslation @ (Thread* self, u4* dFP) 15599 dvmJitResumeTranslation: 15600 mov rSELF, r0 @ restore self 15601 mov rPC, r1 @ restore Dalvik pc 15602 mov rFP, r2 @ restore Dalvik fp 15603 ldr r10, [rSELF,#offThread_jitResumeNPC] @ resume address 15604 mov r2, #0 15605 str r2, [rSELF,#offThread_jitResumeNPC] @ reset resume address 15606 ldr sp, [rSELF,#offThread_jitResumeNSP] @ cut back native stack 15607 b jitSVShadowRunStart @ resume as if cache hit 15608 @ expects resume addr in r10 15609 15610 .global dvmJitToInterpPunt 15611 dvmJitToInterpPunt: 15612 mov r2,#kSVSPunt @ r2<- interpreter entry point 15613 mov r3, #0 15614 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15615 b jitSVShadowRunEnd @ doesn't return 15616 15617 .global dvmJitToInterpSingleStep 15618 dvmJitToInterpSingleStep: 15619 mov rPC, r0 @ set up dalvik pc 15620 EXPORT_PC() 15621 str lr, [rSELF,#offThread_jitResumeNPC] 15622 str sp, [rSELF,#offThread_jitResumeNSP] 15623 str r1, [rSELF,#offThread_jitResumeDPC] 15624 mov r2,#kSVSSingleStep @ r2<- interpreter entry point 15625 b jitSVShadowRunEnd @ doesn't return 15626 15627 15628 .global dvmJitToInterpNoChainNoProfile 15629 dvmJitToInterpNoChainNoProfile: 15630 mov r0,rPC @ pass our target PC 15631 mov r2,#kSVSNoProfile @ r2<- interpreter entry point 15632 mov r3, #0 @ 0 means !inJitCodeCache 15633 str r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 15634 b jitSVShadowRunEnd @ doesn't return 15635 15636 .global dvmJitToInterpTraceSelectNoChain 15637 dvmJitToInterpTraceSelectNoChain: 15638 mov r0,rPC @ pass our target PC 15639 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 15640 mov r3, #0 @ 0 means !inJitCodeCache 15641 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15642 b jitSVShadowRunEnd @ doesn't return 15643 15644 .global dvmJitToInterpTraceSelect 15645 dvmJitToInterpTraceSelect: 15646 ldr r0,[lr, #-1] @ pass our target PC 15647 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 15648 mov r3, #0 @ 0 means !inJitCodeCache 15649 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15650 b jitSVShadowRunEnd @ doesn't return 15651 15652 .global dvmJitToInterpBackwardBranch 15653 dvmJitToInterpBackwardBranch: 15654 ldr r0,[lr, #-1] @ pass our target PC 15655 mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point 15656 mov r3, #0 @ 0 means !inJitCodeCache 15657 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15658 b jitSVShadowRunEnd @ doesn't return 15659 15660 .global dvmJitToInterpNormal 15661 dvmJitToInterpNormal: 15662 ldr r0,[lr, #-1] @ pass our target PC 15663 mov r2,#kSVSNormal @ r2<- interpreter entry point 15664 mov r3, #0 @ 0 means !inJitCodeCache 15665 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15666 b jitSVShadowRunEnd @ doesn't return 15667 15668 .global dvmJitToInterpNoChain 15669 dvmJitToInterpNoChain: 15670 mov r0,rPC @ pass our target PC 15671 mov r2,#kSVSNoChain @ r2<- interpreter entry point 15672 mov r3, #0 @ 0 means !inJitCodeCache 15673 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15674 b jitSVShadowRunEnd @ doesn't return 15675 #else 15676 15677 /* 15678 * "longjmp" to a translation after single-stepping. 15679 */ 15680 .global dvmJitResumeTranslation @ (Thread* self, u4* dFP) 15681 dvmJitResumeTranslation: 15682 mov rSELF, r0 @ restore self 15683 mov rPC, r1 @ restore Dalvik pc 15684 mov rFP, r2 @ restore Dalvik fp 15685 ldr r0, [rSELF,#offThread_jitResumeNPC] 15686 mov r2, #0 15687 str r2, [rSELF,#offThread_jitResumeNPC] @ reset resume address 15688 ldr sp, [rSELF,#offThread_jitResumeNSP] @ cut back native stack 15689 bx r0 @ resume translation 15690 15691 /* 15692 * Return from the translation cache to the interpreter when the compiler is 15693 * having issues translating/executing a Dalvik instruction. We have to skip 15694 * the code cache lookup otherwise it is possible to indefinitely bouce 15695 * between the interpreter and the code cache if the instruction that fails 15696 * to be compiled happens to be at a trace start. 15697 */ 15698 .global dvmJitToInterpPunt 15699 dvmJitToInterpPunt: 15700 mov rPC, r0 15701 #if defined(WITH_JIT_TUNING) 15702 mov r0,lr 15703 bl dvmBumpPunt; 15704 #endif 15705 EXPORT_PC() 15706 mov r0, #0 15707 str r0, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15708 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15709 FETCH_INST() 15710 GET_INST_OPCODE(ip) 15711 GOTO_OPCODE(ip) 15712 15713 /* 15714 * Return to the interpreter to handle a single instruction. 15715 * We'll use the normal single-stepping mechanism via interpBreak, 15716 * but also save the native pc of the resume point in the translation 15717 * and the native sp so that we can later do the equivalent of a 15718 * longjmp() to resume. 15719 * On entry: 15720 * dPC <= Dalvik PC of instrucion to interpret 15721 * lr <= resume point in translation 15722 * r1 <= Dalvik PC of next instruction 15723 */ 15724 .global dvmJitToInterpSingleStep 15725 dvmJitToInterpSingleStep: 15726 mov rPC, r0 @ set up dalvik pc 15727 EXPORT_PC() 15728 str lr, [rSELF,#offThread_jitResumeNPC] 15729 str sp, [rSELF,#offThread_jitResumeNSP] 15730 str r1, [rSELF,#offThread_jitResumeDPC] 15731 mov r1, #1 15732 str r1, [rSELF,#offThread_singleStepCount] @ just step once 15733 mov r0, rSELF 15734 mov r1, #kSubModeCountedStep 15735 bl dvmEnableSubMode @ (self, newMode) 15736 ldr rIBASE, [rSELF,#offThread_curHandlerTable] 15737 FETCH_INST() 15738 GET_INST_OPCODE(ip) 15739 GOTO_OPCODE(ip) 15740 15741 /* 15742 * Return from the translation cache and immediately request 15743 * a translation for the exit target. Commonly used for callees. 15744 */ 15745 .global dvmJitToInterpTraceSelectNoChain 15746 dvmJitToInterpTraceSelectNoChain: 15747 #if defined(WITH_JIT_TUNING) 15748 bl dvmBumpNoChain 15749 #endif 15750 mov r0,rPC 15751 mov r1,rSELF 15752 bl dvmJitGetTraceAddrThread @ (pc, self) 15753 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15754 mov r1, rPC @ arg1 of translation may need this 15755 mov lr, #0 @ in case target is HANDLER_INTERPRET 15756 cmp r0,#0 @ !0 means translation exists 15757 bxne r0 @ continue native execution if so 15758 b 2f @ branch over to use the interpreter 15759 15760 /* 15761 * Return from the translation cache and immediately request 15762 * a translation for the exit target. Commonly used following 15763 * invokes. 15764 */ 15765 .global dvmJitToInterpTraceSelect 15766 dvmJitToInterpTraceSelect: 15767 ldr rPC,[lr, #-1] @ get our target PC 15768 add rINST,lr,#-5 @ save start of chain branch 15769 add rINST, #-4 @ .. which is 9 bytes back 15770 mov r0,rPC 15771 mov r1,rSELF 15772 bl dvmJitGetTraceAddrThread @ (pc, self) 15773 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15774 cmp r0,#0 15775 beq 2f 15776 mov r1,rINST 15777 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 15778 mov r1, rPC @ arg1 of translation may need this 15779 mov lr, #0 @ in case target is HANDLER_INTERPRET 15780 cmp r0,#0 @ successful chain? 15781 bxne r0 @ continue native execution 15782 b toInterpreter @ didn't chain - resume with interpreter 15783 15784 /* No translation, so request one if profiling isn't disabled*/ 15785 2: 15786 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15787 ldr r0, [rSELF, #offThread_pJitProfTable] 15788 FETCH_INST() 15789 cmp r0, #0 15790 movne r2,#kJitTSelectRequestHot @ ask for trace selection 15791 bne common_selectTrace 15792 GET_INST_OPCODE(ip) 15793 GOTO_OPCODE(ip) 15794 15795 /* 15796 * Return from the translation cache to the interpreter. 15797 * The return was done with a BLX from thumb mode, and 15798 * the following 32-bit word contains the target rPC value. 15799 * Note that lr (r14) will have its low-order bit set to denote 15800 * its thumb-mode origin. 15801 * 15802 * We'll need to stash our lr origin away, recover the new 15803 * target and then check to see if there is a translation available 15804 * for our new target. If so, we do a translation chain and 15805 * go back to native execution. Otherwise, it's back to the 15806 * interpreter (after treating this entry as a potential 15807 * trace start). 15808 */ 15809 .global dvmJitToInterpNormal 15810 dvmJitToInterpNormal: 15811 ldr rPC,[lr, #-1] @ get our target PC 15812 add rINST,lr,#-5 @ save start of chain branch 15813 add rINST,#-4 @ .. which is 9 bytes back 15814 #if defined(WITH_JIT_TUNING) 15815 bl dvmBumpNormal 15816 #endif 15817 mov r0,rPC 15818 mov r1,rSELF 15819 bl dvmJitGetTraceAddrThread @ (pc, self) 15820 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15821 cmp r0,#0 15822 beq toInterpreter @ go if not, otherwise do chain 15823 mov r1,rINST 15824 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 15825 mov r1, rPC @ arg1 of translation may need this 15826 mov lr, #0 @ in case target is HANDLER_INTERPRET 15827 cmp r0,#0 @ successful chain? 15828 bxne r0 @ continue native execution 15829 b toInterpreter @ didn't chain - resume with interpreter 15830 15831 /* 15832 * Return from the translation cache to the interpreter to do method invocation. 15833 * Check if translation exists for the callee, but don't chain to it. 15834 */ 15835 .global dvmJitToInterpNoChainNoProfile 15836 dvmJitToInterpNoChainNoProfile: 15837 #if defined(WITH_JIT_TUNING) 15838 bl dvmBumpNoChain 15839 #endif 15840 mov r0,rPC 15841 mov r1,rSELF 15842 bl dvmJitGetTraceAddrThread @ (pc, self) 15843 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15844 mov r1, rPC @ arg1 of translation may need this 15845 mov lr, #0 @ in case target is HANDLER_INTERPRET 15846 cmp r0,#0 15847 bxne r0 @ continue native execution if so 15848 EXPORT_PC() 15849 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15850 FETCH_INST() 15851 GET_INST_OPCODE(ip) @ extract opcode from rINST 15852 GOTO_OPCODE(ip) @ jump to next instruction 15853 15854 /* 15855 * Return from the translation cache to the interpreter to do method invocation. 15856 * Check if translation exists for the callee, but don't chain to it. 15857 */ 15858 .global dvmJitToInterpNoChain 15859 dvmJitToInterpNoChain: 15860 #if defined(WITH_JIT_TUNING) 15861 bl dvmBumpNoChain 15862 #endif 15863 mov r0,rPC 15864 mov r1,rSELF 15865 bl dvmJitGetTraceAddrThread @ (pc, self) 15866 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15867 mov r1, rPC @ arg1 of translation may need this 15868 mov lr, #0 @ in case target is HANDLER_INTERPRET 15869 cmp r0,#0 15870 bxne r0 @ continue native execution if so 15871 #endif 15872 15873 /* 15874 * No translation, restore interpreter regs and start interpreting. 15875 * rSELF & rFP were preserved in the translated code, and rPC has 15876 * already been restored by the time we get here. We'll need to set 15877 * up rIBASE & rINST, and load the address of the JitTable into r0. 15878 */ 15879 toInterpreter: 15880 EXPORT_PC() 15881 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15882 FETCH_INST() 15883 ldr r0, [rSELF, #offThread_pJitProfTable] 15884 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15885 @ NOTE: intended fallthrough 15886 15887 /* 15888 * Similar to common_updateProfile, but tests for null pJitProfTable 15889 * r0 holds pJifProfTAble, rINST is loaded, rPC is current and 15890 * rIBASE has been recently refreshed. 15891 */ 15892 common_testUpdateProfile: 15893 cmp r0, #0 @ JIT switched off? 15894 beq 4f @ return to interp if so 15895 15896 /* 15897 * Common code to update potential trace start counter, and initiate 15898 * a trace-build if appropriate. 15899 * On entry here: 15900 * r0 <= pJitProfTable (verified non-NULL) 15901 * rPC <= Dalvik PC 15902 * rINST <= next instruction 15903 */ 15904 common_updateProfile: 15905 eor r3,rPC,rPC,lsr #12 @ cheap, but fast hash function 15906 lsl r3,r3,#(32 - JIT_PROF_SIZE_LOG_2) @ shift out excess bits 15907 ldrb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter 15908 GET_INST_OPCODE(ip) 15909 subs r1,r1,#1 @ decrement counter 15910 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it 15911 GOTO_OPCODE_IFNE(ip) @ if not threshold, fallthrough otherwise */ 15912 15913 /* Looks good, reset the counter */ 15914 ldr r1, [rSELF, #offThread_jitThreshold] 15915 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter 15916 EXPORT_PC() 15917 mov r0,rPC 15918 mov r1,rSELF 15919 bl dvmJitGetTraceAddrThread @ (pc, self) 15920 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15921 mov r1, rPC @ arg1 of translation may need this 15922 mov lr, #0 @ in case target is HANDLER_INTERPRET 15923 cmp r0,#0 15924 #if !defined(WITH_SELF_VERIFICATION) 15925 bxne r0 @ jump to the translation 15926 mov r2,#kJitTSelectRequest @ ask for trace selection 15927 @ fall-through to common_selectTrace 15928 #else 15929 moveq r2,#kJitTSelectRequest @ ask for trace selection 15930 beq common_selectTrace 15931 /* 15932 * At this point, we have a target translation. However, if 15933 * that translation is actually the interpret-only pseudo-translation 15934 * we want to treat it the same as no translation. 15935 */ 15936 mov r10, r0 @ save target 15937 bl dvmCompilerGetInterpretTemplate 15938 cmp r0, r10 @ special case? 15939 bne jitSVShadowRunStart @ set up self verification shadow space 15940 @ Need to clear the inJitCodeCache flag 15941 mov r3, #0 @ 0 means not in the JIT code cache 15942 str r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 15943 GET_INST_OPCODE(ip) 15944 GOTO_OPCODE(ip) 15945 /* no return */ 15946 #endif 15947 15948 /* 15949 * On entry: 15950 * r2 is jit state. 15951 */ 15952 common_selectTrace: 15953 ldrh r0,[rSELF,#offThread_subMode] 15954 ands r0, #(kSubModeJitTraceBuild | kSubModeJitSV) 15955 bne 3f @ already doing JIT work, continue 15956 str r2,[rSELF,#offThread_jitState] 15957 mov r0, rSELF 15958 /* 15959 * Call out to validate trace-building request. If successful, 15960 * rIBASE will be swapped to to send us into single-stepping trace 15961 * building mode, so we need to refresh before we continue. 15962 */ 15963 EXPORT_PC() 15964 SAVE_PC_FP_TO_SELF() @ copy of pc/fp to Thread 15965 bl dvmJitCheckTraceRequest 15966 3: 15967 FETCH_INST() 15968 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15969 4: 15970 GET_INST_OPCODE(ip) @ extract opcode from rINST 15971 GOTO_OPCODE(ip) 15972 /* no return */ 15973 #endif 15974 15975 #if defined(WITH_SELF_VERIFICATION) 15976 /* 15977 * Save PC and registers to shadow memory for self verification mode 15978 * before jumping to native translation. 15979 * On entry: 15980 * rPC, rFP, rSELF: the values that they should contain 15981 * r10: the address of the target translation. 15982 */ 15983 jitSVShadowRunStart: 15984 mov r0,rPC @ r0<- program counter 15985 mov r1,rFP @ r1<- frame pointer 15986 mov r2,rSELF @ r2<- self (Thread) pointer 15987 mov r3,r10 @ r3<- target translation 15988 bl dvmSelfVerificationSaveState @ save registers to shadow space 15989 ldr rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space 15990 bx r10 @ jump to the translation 15991 15992 /* 15993 * Restore PC, registers, and interpreter state to original values 15994 * before jumping back to the interpreter. 15995 * On entry: 15996 * r0: dPC 15997 * r2: self verification state 15998 */ 15999 jitSVShadowRunEnd: 16000 mov r1,rFP @ pass ending fp 16001 mov r3,rSELF @ pass self ptr for convenience 16002 bl dvmSelfVerificationRestoreState @ restore pc and fp values 16003 LOAD_PC_FP_FROM_SELF() @ restore pc, fp 16004 ldr r1,[r0,#offShadowSpace_svState] @ get self verification state 16005 cmp r1,#0 @ check for punt condition 16006 beq 1f 16007 @ Set up SV single-stepping 16008 mov r0, rSELF 16009 mov r1, #kSubModeJitSV 16010 bl dvmEnableSubMode @ (self, subMode) 16011 mov r2,#kJitSelfVerification @ ask for self verification 16012 str r2,[rSELF,#offThread_jitState] 16013 @ intentional fallthrough 16014 1: @ exit to interpreter without check 16015 EXPORT_PC() 16016 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16017 FETCH_INST() 16018 GET_INST_OPCODE(ip) 16019 GOTO_OPCODE(ip) 16020 #endif 16021 16022 /* 16023 * The equivalent of "goto bail", this calls through the "bail handler". 16024 * It will end this interpreter activation, and return to the caller 16025 * of dvmMterpStdRun. 16026 * 16027 * State registers will be saved to the "thread" area before bailing 16028 * debugging purposes 16029 */ 16030 common_gotoBail: 16031 SAVE_PC_FP_TO_SELF() @ export state to "thread" 16032 mov r0, rSELF @ r0<- self ptr 16033 b dvmMterpStdBail @ call(self, changeInterp) 16034 16035 /* 16036 * The JIT's invoke method needs to remember the callsite class and 16037 * target pair. Save them here so that they are available to 16038 * dvmCheckJit following the interpretation of this invoke. 16039 */ 16040 #if defined(WITH_JIT) 16041 save_callsiteinfo: 16042 cmp r9, #0 16043 ldrne r9, [r9, #offObject_clazz] 16044 str r0, [rSELF, #offThread_methodToCall] 16045 str r9, [rSELF, #offThread_callsiteClass] 16046 bx lr 16047 #endif 16048 16049 /* 16050 * Common code for method invocation with range. 16051 * 16052 * On entry: 16053 * r0 is "Method* methodToCall", r9 is "this" 16054 */ 16055 common_invokeMethodRange: 16056 .LinvokeNewRange: 16057 #if defined(WITH_JIT) 16058 ldrh r1, [rSELF, #offThread_subMode] 16059 ands r1, #kSubModeJitTraceBuild 16060 blne save_callsiteinfo 16061 #endif 16062 @ prepare to copy args to "outs" area of current frame 16063 movs r2, rINST, lsr #8 @ r2<- AA (arg count) -- test for zero 16064 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 16065 beq .LinvokeArgsDone @ if no args, skip the rest 16066 FETCH(r1, 2) @ r1<- CCCC 16067 16068 .LinvokeRangeArgs: 16069 @ r0=methodToCall, r1=CCCC, r2=count, r10=outs 16070 @ (very few methods have > 10 args; could unroll for common cases) 16071 add r3, rFP, r1, lsl #2 @ r3<- &fp[CCCC] 16072 sub r10, r10, r2, lsl #2 @ r10<- "outs" area, for call args 16073 1: ldr r1, [r3], #4 @ val = *fp++ 16074 subs r2, r2, #1 @ count-- 16075 str r1, [r10], #4 @ *outs++ = val 16076 bne 1b @ ...while count != 0 16077 b .LinvokeArgsDone 16078 16079 /* 16080 * Common code for method invocation without range. 16081 * 16082 * On entry: 16083 * r0 is "Method* methodToCall", r9 is "this" 16084 */ 16085 common_invokeMethodNoRange: 16086 .LinvokeNewNoRange: 16087 #if defined(WITH_JIT) 16088 ldrh r1, [rSELF, #offThread_subMode] 16089 ands r1, #kSubModeJitTraceBuild 16090 blne save_callsiteinfo 16091 #endif 16092 @ prepare to copy args to "outs" area of current frame 16093 movs r2, rINST, lsr #12 @ r2<- B (arg count) -- test for zero 16094 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 16095 FETCH(r1, 2) @ r1<- GFED (load here to hide latency) 16096 beq .LinvokeArgsDone 16097 16098 @ r0=methodToCall, r1=GFED, r2=count, r10=outs 16099 .LinvokeNonRange: 16100 rsb r2, r2, #5 @ r2<- 5-r2 16101 add pc, pc, r2, lsl #4 @ computed goto, 4 instrs each 16102 bl common_abort @ (skipped due to ARM prefetch) 16103 5: and ip, rINST, #0x0f00 @ isolate A 16104 ldr r2, [rFP, ip, lsr #6] @ r2<- vA (shift right 8, left 2) 16105 mov r0, r0 @ nop 16106 str r2, [r10, #-4]! @ *--outs = vA 16107 4: and ip, r1, #0xf000 @ isolate G 16108 ldr r2, [rFP, ip, lsr #10] @ r2<- vG (shift right 12, left 2) 16109 mov r0, r0 @ nop 16110 str r2, [r10, #-4]! @ *--outs = vG 16111 3: and ip, r1, #0x0f00 @ isolate F 16112 ldr r2, [rFP, ip, lsr #6] @ r2<- vF 16113 mov r0, r0 @ nop 16114 str r2, [r10, #-4]! @ *--outs = vF 16115 2: and ip, r1, #0x00f0 @ isolate E 16116 ldr r2, [rFP, ip, lsr #2] @ r2<- vE 16117 mov r0, r0 @ nop 16118 str r2, [r10, #-4]! @ *--outs = vE 16119 1: and ip, r1, #0x000f @ isolate D 16120 ldr r2, [rFP, ip, lsl #2] @ r2<- vD 16121 mov r0, r0 @ nop 16122 str r2, [r10, #-4]! @ *--outs = vD 16123 0: @ fall through to .LinvokeArgsDone 16124 16125 .LinvokeArgsDone: @ r0=methodToCall 16126 ldrh r9, [r0, #offMethod_registersSize] @ r9<- methodToCall->regsSize 16127 ldrh r3, [r0, #offMethod_outsSize] @ r3<- methodToCall->outsSize 16128 ldr r2, [r0, #offMethod_insns] @ r2<- method->insns 16129 ldr rINST, [r0, #offMethod_clazz] @ rINST<- method->clazz 16130 @ find space for the new stack frame, check for overflow 16131 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area 16132 sub r1, r1, r9, lsl #2 @ r1<- newFp (old savearea - regsSize) 16133 SAVEAREA_FROM_FP(r10, r1) @ r10<- newSaveArea 16134 @ bl common_dumpRegs 16135 ldr r9, [rSELF, #offThread_interpStackEnd] @ r9<- interpStackEnd 16136 sub r3, r10, r3, lsl #2 @ r3<- bottom (newsave - outsSize) 16137 cmp r3, r9 @ bottom < interpStackEnd? 16138 ldrh lr, [rSELF, #offThread_subMode] 16139 ldr r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags 16140 blo .LstackOverflow @ yes, this frame will overflow stack 16141 16142 @ set up newSaveArea 16143 #ifdef EASY_GDB 16144 SAVEAREA_FROM_FP(ip, rFP) @ ip<- stack save area 16145 str ip, [r10, #offStackSaveArea_prevSave] 16146 #endif 16147 str rFP, [r10, #offStackSaveArea_prevFrame] 16148 str rPC, [r10, #offStackSaveArea_savedPc] 16149 #if defined(WITH_JIT) 16150 mov r9, #0 16151 str r9, [r10, #offStackSaveArea_returnAddr] 16152 #endif 16153 str r0, [r10, #offStackSaveArea_method] 16154 16155 @ Profiling? 16156 cmp lr, #0 @ any special modes happening? 16157 bne 2f @ go if so 16158 1: 16159 tst r3, #ACC_NATIVE 16160 bne .LinvokeNative 16161 16162 /* 16163 stmfd sp!, {r0-r3} 16164 bl common_printNewline 16165 mov r0, rFP 16166 mov r1, #0 16167 bl dvmDumpFp 16168 ldmfd sp!, {r0-r3} 16169 stmfd sp!, {r0-r3} 16170 mov r0, r1 16171 mov r1, r10 16172 bl dvmDumpFp 16173 bl common_printNewline 16174 ldmfd sp!, {r0-r3} 16175 */ 16176 16177 ldrh r9, [r2] @ r9 <- load INST from new PC 16178 ldr r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex 16179 mov rPC, r2 @ publish new rPC 16180 16181 @ Update state values for the new method 16182 @ r0=methodToCall, r1=newFp, r3=newMethodClass, r9=newINST 16183 str r0, [rSELF, #offThread_method] @ self->method = methodToCall 16184 str r3, [rSELF, #offThread_methodClassDex] @ self->methodClassDex = ... 16185 mov r2, #1 16186 str r2, [rSELF, #offThread_debugIsMethodEntry] 16187 #if defined(WITH_JIT) 16188 ldr r0, [rSELF, #offThread_pJitProfTable] 16189 mov rFP, r1 @ fp = newFp 16190 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 16191 mov rINST, r9 @ publish new rINST 16192 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16193 cmp r0,#0 16194 bne common_updateProfile 16195 GOTO_OPCODE(ip) @ jump to next instruction 16196 #else 16197 mov rFP, r1 @ fp = newFp 16198 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 16199 mov rINST, r9 @ publish new rINST 16200 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16201 GOTO_OPCODE(ip) @ jump to next instruction 16202 #endif 16203 16204 2: 16205 @ Profiling - record method entry. r0: methodToCall 16206 stmfd sp!, {r0-r3} @ preserve r0-r3 16207 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16208 mov r1, r0 16209 mov r0, rSELF 16210 bl dvmReportInvoke @ (self, method) 16211 ldmfd sp!, {r0-r3} @ restore r0-r3 16212 b 1b 16213 16214 .LinvokeNative: 16215 @ Prep for the native call 16216 @ r0=methodToCall, r1=newFp, r10=newSaveArea 16217 ldrh lr, [rSELF, #offThread_subMode] 16218 ldr r9, [rSELF, #offThread_jniLocal_topCookie]@r9<-thread->localRef->... 16219 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16220 str r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top 16221 mov r2, r0 @ r2<- methodToCall 16222 mov r0, r1 @ r0<- newFp (points to args) 16223 add r1, rSELF, #offThread_retval @ r1<- &retval 16224 mov r3, rSELF @ arg3<- self 16225 16226 #ifdef ASSIST_DEBUGGER 16227 /* insert fake function header to help gdb find the stack frame */ 16228 b .Lskip 16229 .type dalvik_mterp, %function 16230 dalvik_mterp: 16231 .fnstart 16232 MTERP_ENTRY1 16233 MTERP_ENTRY2 16234 .Lskip: 16235 #endif 16236 16237 cmp lr, #0 @ any special SubModes active? 16238 bne 11f @ go handle them if so 16239 ldr ip, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 16240 blx ip 16241 7: 16242 16243 @ native return; r10=newSaveArea 16244 @ equivalent to dvmPopJniLocals 16245 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top 16246 ldr r1, [rSELF, #offThread_exception] @ check for exception 16247 str rFP, [rSELF, #offThread_curFrame] @ curFrame = fp 16248 cmp r1, #0 @ null? 16249 str r0, [rSELF, #offThread_jniLocal_topCookie] @ new top <- old top 16250 bne common_exceptionThrown @ no, handle exception 16251 16252 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 16253 GET_INST_OPCODE(ip) @ extract opcode from rINST 16254 GOTO_OPCODE(ip) @ jump to next instruction 16255 16256 11: 16257 @ r0=newFp, r1=&retval, r2=methodToCall, r3=self, lr=subModes 16258 stmfd sp!, {r0-r3} @ save all but subModes 16259 mov r0, r2 @ r0<- methodToCall 16260 mov r1, rSELF 16261 mov r2, rFP 16262 bl dvmReportPreNativeInvoke @ (methodToCall, self, fp) 16263 ldmfd sp, {r0-r3} @ refresh. NOTE: no sp autoincrement 16264 16265 @ Call the native method 16266 ldr ip, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 16267 blx ip 16268 16269 @ Restore the pre-call arguments 16270 ldmfd sp!, {r0-r3} @ r2<- methodToCall (others unneeded) 16271 16272 @ Finish up any post-invoke subMode requirements 16273 mov r0, r2 @ r0<- methodToCall 16274 mov r1, rSELF 16275 mov r2, rFP 16276 bl dvmReportPostNativeInvoke @ (methodToCall, self, fp) 16277 b 7b @ resume 16278 16279 .LstackOverflow: @ r0=methodToCall 16280 mov r1, r0 @ r1<- methodToCall 16281 mov r0, rSELF @ r0<- self 16282 bl dvmHandleStackOverflow 16283 b common_exceptionThrown 16284 #ifdef ASSIST_DEBUGGER 16285 .fnend 16286 .size dalvik_mterp, .-dalvik_mterp 16287 #endif 16288 16289 16290 /* 16291 * Common code for method invocation, calling through "glue code". 16292 * 16293 * TODO: now that we have range and non-range invoke handlers, this 16294 * needs to be split into two. Maybe just create entry points 16295 * that set r9 and jump here? 16296 * 16297 * On entry: 16298 * r0 is "Method* methodToCall", the method we're trying to call 16299 * r9 is "bool methodCallRange", indicating if this is a /range variant 16300 */ 16301 .if 0 16302 .LinvokeOld: 16303 sub sp, sp, #8 @ space for args + pad 16304 FETCH(ip, 2) @ ip<- FEDC or CCCC 16305 mov r2, r0 @ A2<- methodToCall 16306 mov r0, rSELF @ A0<- self 16307 SAVE_PC_FP_TO_SELF() @ export state to "self" 16308 mov r1, r9 @ A1<- methodCallRange 16309 mov r3, rINST, lsr #8 @ A3<- AA 16310 str ip, [sp, #0] @ A4<- ip 16311 bl dvmMterp_invokeMethod @ call the C invokeMethod 16312 add sp, sp, #8 @ remove arg area 16313 b common_resumeAfterGlueCall @ continue to next instruction 16314 .endif 16315 16316 16317 16318 /* 16319 * Common code for handling a return instruction. 16320 * 16321 * This does not return. 16322 */ 16323 common_returnFromMethod: 16324 .LreturnNew: 16325 ldrh lr, [rSELF, #offThread_subMode] 16326 SAVEAREA_FROM_FP(r0, rFP) 16327 ldr r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc 16328 cmp lr, #0 @ any special subMode handling needed? 16329 bne 19f 16330 14: 16331 ldr rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame 16332 ldr r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)] 16333 @ r2<- method we're returning to 16334 cmp r2, #0 @ is this a break frame? 16335 #if defined(WORKAROUND_CORTEX_A9_745320) 16336 /* Don't use conditional loads if the HW defect exists */ 16337 beq 15f 16338 ldr r10, [r2, #offMethod_clazz] @ r10<- method->clazz 16339 15: 16340 #else 16341 ldrne r10, [r2, #offMethod_clazz] @ r10<- method->clazz 16342 #endif 16343 beq common_gotoBail @ break frame, bail out completely 16344 16345 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 16346 PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST 16347 str r2, [rSELF, #offThread_method]@ self->method = newSave->method 16348 ldr r1, [r10, #offClassObject_pDvmDex] @ r1<- method->clazz->pDvmDex 16349 str rFP, [rSELF, #offThread_curFrame] @ curFrame = fp 16350 #if defined(WITH_JIT) 16351 ldr r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr 16352 mov rPC, r9 @ publish new rPC 16353 str r1, [rSELF, #offThread_methodClassDex] 16354 str r10, [rSELF, #offThread_inJitCodeCache] @ may return to JIT'ed land 16355 cmp r10, #0 @ caller is compiled code 16356 blxne r10 16357 GET_INST_OPCODE(ip) @ extract opcode from rINST 16358 GOTO_OPCODE(ip) @ jump to next instruction 16359 #else 16360 GET_INST_OPCODE(ip) @ extract opcode from rINST 16361 mov rPC, r9 @ publish new rPC 16362 str r1, [rSELF, #offThread_methodClassDex] 16363 GOTO_OPCODE(ip) @ jump to next instruction 16364 #endif 16365 16366 19: 16367 @ Handle special actions 16368 @ On entry, r0: StackSaveArea 16369 ldr r1, [r0, #offStackSaveArea_prevFrame] @ r2<- prevFP 16370 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16371 str r1, [rSELF, #offThread_curFrame] @ update interpSave.curFrame 16372 mov r0, rSELF 16373 bl dvmReportReturn @ (self) 16374 SAVEAREA_FROM_FP(r0, rFP) @ restore StackSaveArea 16375 b 14b @ continue 16376 16377 /* 16378 * Return handling, calls through "glue code". 16379 */ 16380 .if 0 16381 .LreturnOld: 16382 SAVE_PC_FP_TO_SELF() @ export state 16383 mov r0, rSELF @ arg to function 16384 bl dvmMterp_returnFromMethod 16385 b common_resumeAfterGlueCall 16386 .endif 16387 16388 16389 /* 16390 * Somebody has thrown an exception. Handle it. 16391 * 16392 * If the exception processing code returns to us (instead of falling 16393 * out of the interpreter), continue with whatever the next instruction 16394 * now happens to be. 16395 * 16396 * This does not return. 16397 */ 16398 .global dvmMterpCommonExceptionThrown 16399 dvmMterpCommonExceptionThrown: 16400 common_exceptionThrown: 16401 .LexceptionNew: 16402 16403 EXPORT_PC() 16404 16405 mov r0, rSELF 16406 bl dvmCheckSuspendPending 16407 16408 ldr r9, [rSELF, #offThread_exception] @ r9<- self->exception 16409 mov r1, rSELF @ r1<- self 16410 mov r0, r9 @ r0<- exception 16411 bl dvmAddTrackedAlloc @ don't let the exception be GCed 16412 ldrh r2, [rSELF, #offThread_subMode] @ get subMode flags 16413 mov r3, #0 @ r3<- NULL 16414 str r3, [rSELF, #offThread_exception] @ self->exception = NULL 16415 16416 @ Special subMode? 16417 cmp r2, #0 @ any special subMode handling needed? 16418 bne 7f @ go if so 16419 8: 16420 /* set up args and a local for "&fp" */ 16421 /* (str sp, [sp, #-4]! would be perfect here, but is discouraged) */ 16422 str rFP, [sp, #-4]! @ *--sp = fp 16423 mov ip, sp @ ip<- &fp 16424 mov r3, #0 @ r3<- false 16425 str ip, [sp, #-4]! @ *--sp = &fp 16426 ldr r1, [rSELF, #offThread_method] @ r1<- self->method 16427 mov r0, rSELF @ r0<- self 16428 ldr r1, [r1, #offMethod_insns] @ r1<- method->insns 16429 mov r2, r9 @ r2<- exception 16430 sub r1, rPC, r1 @ r1<- pc - method->insns 16431 mov r1, r1, asr #1 @ r1<- offset in code units 16432 16433 /* call, r0 gets catchRelPc (a code-unit offset) */ 16434 bl dvmFindCatchBlock @ call(self, relPc, exc, scan?, &fp) 16435 16436 /* fix earlier stack overflow if necessary; may trash rFP */ 16437 ldrb r1, [rSELF, #offThread_stackOverflowed] 16438 cmp r1, #0 @ did we overflow earlier? 16439 beq 1f @ no, skip ahead 16440 mov rFP, r0 @ save relPc result in rFP 16441 mov r0, rSELF @ r0<- self 16442 mov r1, r9 @ r1<- exception 16443 bl dvmCleanupStackOverflow @ call(self) 16444 mov r0, rFP @ restore result 16445 1: 16446 16447 /* update frame pointer and check result from dvmFindCatchBlock */ 16448 ldr rFP, [sp, #4] @ retrieve the updated rFP 16449 cmp r0, #0 @ is catchRelPc < 0? 16450 add sp, sp, #8 @ restore stack 16451 bmi .LnotCaughtLocally 16452 16453 /* adjust locals to match self->interpSave.curFrame and updated PC */ 16454 SAVEAREA_FROM_FP(r1, rFP) @ r1<- new save area 16455 ldr r1, [r1, #offStackSaveArea_method] @ r1<- new method 16456 str r1, [rSELF, #offThread_method] @ self->method = new method 16457 ldr r2, [r1, #offMethod_clazz] @ r2<- method->clazz 16458 ldr r3, [r1, #offMethod_insns] @ r3<- method->insns 16459 ldr r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex 16460 add rPC, r3, r0, asl #1 @ rPC<- method->insns + catchRelPc 16461 str r2, [rSELF, #offThread_methodClassDex] @ self->pDvmDex = meth... 16462 16463 /* release the tracked alloc on the exception */ 16464 mov r0, r9 @ r0<- exception 16465 mov r1, rSELF @ r1<- self 16466 bl dvmReleaseTrackedAlloc @ release the exception 16467 16468 /* restore the exception if the handler wants it */ 16469 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 16470 FETCH_INST() @ load rINST from rPC 16471 GET_INST_OPCODE(ip) @ extract opcode from rINST 16472 cmp ip, #OP_MOVE_EXCEPTION @ is it "move-exception"? 16473 streq r9, [rSELF, #offThread_exception] @ yes, restore the exception 16474 GOTO_OPCODE(ip) @ jump to next instruction 16475 16476 @ Manage debugger bookkeeping 16477 7: 16478 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16479 str rFP, [rSELF, #offThread_curFrame] @ update interpSave.curFrame 16480 mov r0, rSELF @ arg0<- self 16481 mov r1, r9 @ arg1<- exception 16482 bl dvmReportExceptionThrow @ (self, exception) 16483 b 8b @ resume with normal handling 16484 16485 .LnotCaughtLocally: @ r9=exception 16486 /* fix stack overflow if necessary */ 16487 ldrb r1, [rSELF, #offThread_stackOverflowed] 16488 cmp r1, #0 @ did we overflow earlier? 16489 movne r0, rSELF @ if yes: r0<- self 16490 movne r1, r9 @ if yes: r1<- exception 16491 blne dvmCleanupStackOverflow @ if yes: call(self) 16492 16493 @ may want to show "not caught locally" debug messages here 16494 #if DVM_SHOW_EXCEPTION >= 2 16495 /* call __android_log_print(prio, tag, format, ...) */ 16496 /* "Exception %s from %s:%d not caught locally" */ 16497 @ dvmLineNumFromPC(method, pc - method->insns) 16498 ldr r0, [rSELF, #offThread_method] 16499 ldr r1, [r0, #offMethod_insns] 16500 sub r1, rPC, r1 16501 asr r1, r1, #1 16502 bl dvmLineNumFromPC 16503 str r0, [sp, #-4]! 16504 @ dvmGetMethodSourceFile(method) 16505 ldr r0, [rSELF, #offThread_method] 16506 bl dvmGetMethodSourceFile 16507 str r0, [sp, #-4]! 16508 @ exception->clazz->descriptor 16509 ldr r3, [r9, #offObject_clazz] 16510 ldr r3, [r3, #offClassObject_descriptor] 16511 @ 16512 ldr r2, strExceptionNotCaughtLocally 16513 0: add r2, pc 16514 ldr r1, strLogTag 16515 1: add r1, pc 16516 mov r0, #3 @ LOG_DEBUG 16517 bl __android_log_print 16518 #endif 16519 str r9, [rSELF, #offThread_exception] @ restore exception 16520 mov r0, r9 @ r0<- exception 16521 mov r1, rSELF @ r1<- self 16522 bl dvmReleaseTrackedAlloc @ release the exception 16523 b common_gotoBail @ bail out 16524 16525 strExceptionNotCaughtLocally: 16526 .word PCREL_REF(.LstrExceptionNotCaughtLocally,0b) 16527 strLogTag: 16528 .word PCREL_REF(.LstrLogTag,1b) 16529 16530 /* 16531 * Exception handling, calls through "glue code". 16532 */ 16533 .if 0 16534 .LexceptionOld: 16535 SAVE_PC_FP_TO_SELF() @ export state 16536 mov r0, rSELF @ arg to function 16537 bl dvmMterp_exceptionThrown 16538 b common_resumeAfterGlueCall 16539 .endif 16540 16541 #if defined(WITH_JIT) 16542 /* 16543 * If the JIT is actively building a trace we need to make sure 16544 * that the field is fully resolved before including the current 16545 * instruction. 16546 * 16547 * On entry: 16548 * r10: &dvmDex->pResFields[field] 16549 * r0: field pointer (must preserve) 16550 */ 16551 common_verifyField: 16552 ldrh r3, [rSELF, #offThread_subMode] @ r3 <- submode byte 16553 ands r3, #kSubModeJitTraceBuild 16554 bxeq lr @ Not building trace, continue 16555 ldr r1, [r10] @ r1<- reload resolved StaticField ptr 16556 cmp r1, #0 @ resolution complete? 16557 bxne lr @ yes, continue 16558 stmfd sp!, {r0-r2,lr} @ save regs 16559 mov r0, rSELF 16560 mov r1, rPC 16561 bl dvmJitEndTraceSelect @ (self,pc) end trace before this inst 16562 ldmfd sp!, {r0-r2, lr} 16563 bx lr @ return 16564 #endif 16565 16566 /* 16567 * After returning from a "glued" function, pull out the updated 16568 * values and start executing at the next instruction. 16569 */ 16570 common_resumeAfterGlueCall: 16571 LOAD_PC_FP_FROM_SELF() @ pull rPC and rFP out of thread 16572 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh 16573 FETCH_INST() @ load rINST from rPC 16574 GET_INST_OPCODE(ip) @ extract opcode from rINST 16575 GOTO_OPCODE(ip) @ jump to next instruction 16576 16577 /* 16578 * Invalid array index. Note that our calling convention is strange; we use r1 16579 * and r3 because those just happen to be the registers all our callers are 16580 * using. We move r3 before calling the C function, but r1 happens to match. 16581 * r1: index 16582 * r3: size 16583 */ 16584 common_errArrayIndex: 16585 EXPORT_PC() 16586 mov r0, r3 16587 bl dvmThrowArrayIndexOutOfBoundsException 16588 b common_exceptionThrown 16589 16590 /* 16591 * Integer divide or mod by zero. 16592 */ 16593 common_errDivideByZero: 16594 EXPORT_PC() 16595 ldr r0, strDivideByZero 16596 0: add r0, pc 16597 bl dvmThrowArithmeticException 16598 b common_exceptionThrown 16599 16600 strDivideByZero: 16601 .word PCREL_REF(.LstrDivideByZero,0b) 16602 16603 /* 16604 * Attempt to allocate an array with a negative size. 16605 * On entry: length in r1 16606 */ 16607 common_errNegativeArraySize: 16608 EXPORT_PC() 16609 mov r0, r1 @ arg0 <- len 16610 bl dvmThrowNegativeArraySizeException @ (len) 16611 b common_exceptionThrown 16612 16613 /* 16614 * Invocation of a non-existent method. 16615 * On entry: method name in r1 16616 */ 16617 common_errNoSuchMethod: 16618 EXPORT_PC() 16619 mov r0, r1 16620 bl dvmThrowNoSuchMethodError 16621 b common_exceptionThrown 16622 16623 /* 16624 * We encountered a null object when we weren't expecting one. We 16625 * export the PC, throw a NullPointerException, and goto the exception 16626 * processing code. 16627 */ 16628 common_errNullObject: 16629 EXPORT_PC() 16630 mov r0, #0 16631 bl dvmThrowNullPointerException 16632 b common_exceptionThrown 16633 16634 /* 16635 * For debugging, cause an immediate fault. The source address will 16636 * be in lr (use a bl instruction to jump here). 16637 */ 16638 common_abort: 16639 ldr pc, .LdeadFood 16640 .LdeadFood: 16641 .word 0xdeadf00d 16642 16643 /* 16644 * Spit out a "we were here", preserving all registers. (The attempt 16645 * to save ip won't work, but we need to save an even number of 16646 * registers for EABI 64-bit stack alignment.) 16647 */ 16648 .macro SQUEAK num 16649 common_squeak\num: 16650 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16651 ldr r0, strSqueak\num 16652 0: add r0, pc 16653 mov r1, #\num 16654 bl printf 16655 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16656 bx lr 16657 16658 strSqueak\num: 16659 .word PCREL_REF(.LstrSqueak,0b) 16660 .endm 16661 16662 SQUEAK 0 16663 SQUEAK 1 16664 SQUEAK 2 16665 SQUEAK 3 16666 SQUEAK 4 16667 SQUEAK 5 16668 16669 /* 16670 * Spit out the number in r0, preserving registers. 16671 */ 16672 common_printNum: 16673 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16674 mov r1, r0 16675 ldr r0, strSqueak 16676 0: add r0, pc 16677 bl printf 16678 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16679 bx lr 16680 16681 strSqueak: 16682 .word PCREL_REF(.LstrSqueak,0b) 16683 16684 /* 16685 * Print a newline, preserving registers. 16686 */ 16687 common_printNewline: 16688 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16689 ldr r0, strNewline 16690 0: add r0, pc 16691 bl printf 16692 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16693 bx lr 16694 16695 strNewline: 16696 .word PCREL_REF(.LstrNewline,0b) 16697 16698 /* 16699 * Print the 32-bit quantity in r0 as a hex value, preserving registers. 16700 */ 16701 common_printHex: 16702 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16703 mov r1, r0 16704 ldr r0, strPrintHex 16705 0: add r0, pc 16706 bl printf 16707 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16708 bx lr 16709 16710 strPrintHex: 16711 .word PCREL_REF(.LstrPrintHex,0b) 16712 16713 /* 16714 * Print the 64-bit quantity in r0-r1, preserving registers. 16715 */ 16716 common_printLong: 16717 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16718 mov r3, r1 16719 mov r2, r0 16720 ldr r0, strPrintLong 16721 0: add r0, pc 16722 bl printf 16723 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16724 bx lr 16725 16726 strPrintLong: 16727 .word PCREL_REF(.LstrPrintLong,0b) 16728 16729 /* 16730 * Print full method info. Pass the Method* in r0. Preserves regs. 16731 */ 16732 common_printMethod: 16733 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16734 bl dvmMterpPrintMethod 16735 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16736 bx lr 16737 16738 /* 16739 * Call a C helper function that dumps regs and possibly some 16740 * additional info. Requires the C function to be compiled in. 16741 */ 16742 .if 0 16743 common_dumpRegs: 16744 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16745 bl dvmMterpDumpArmRegs 16746 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16747 bx lr 16748 .endif 16749 16750 #if 0 16751 /* 16752 * Experiment on VFP mode. 16753 * 16754 * uint32_t setFPSCR(uint32_t val, uint32_t mask) 16755 * 16756 * Updates the bits specified by "mask", setting them to the values in "val". 16757 */ 16758 setFPSCR: 16759 and r0, r0, r1 @ make sure no stray bits are set 16760 fmrx r2, fpscr @ get VFP reg 16761 mvn r1, r1 @ bit-invert mask 16762 and r2, r2, r1 @ clear masked bits 16763 orr r2, r2, r0 @ set specified bits 16764 fmxr fpscr, r2 @ set VFP reg 16765 mov r0, r2 @ return new value 16766 bx lr 16767 16768 .align 2 16769 .global dvmConfigureFP 16770 .type dvmConfigureFP, %function 16771 dvmConfigureFP: 16772 stmfd sp!, {ip, lr} 16773 /* 0x03000000 sets DN/FZ */ 16774 /* 0x00009f00 clears the six exception enable flags */ 16775 bl common_squeak0 16776 mov r0, #0x03000000 @ r0<- 0x03000000 16777 add r1, r0, #0x9f00 @ r1<- 0x03009f00 16778 bl setFPSCR 16779 ldmfd sp!, {ip, pc} 16780 #endif 16781 16782 16783 16784 /* 16785 * Zero-terminated ASCII string data. 16786 * 16787 * On ARM we have two choices: do like gcc does, and LDR from a .word 16788 * with the address, or use an ADR pseudo-op to get the address 16789 * directly. ADR saves 4 bytes and an indirection, but it's using a 16790 * PC-relative addressing mode and hence has a limited range, which 16791 * makes it not work well with mergeable string sections. 16792 */ 16793 .section .rodata.str1.4,"aMS",%progbits,1 16794 16795 .LstrBadEntryPoint: 16796 .asciz "Bad entry point %d\n" 16797 .LstrFilledNewArrayNotImpl: 16798 .asciz "filled-new-array only implemented for objects and 'int'" 16799 .LstrDivideByZero: 16800 .asciz "divide by zero" 16801 .LstrLogTag: 16802 .asciz "mterp" 16803 .LstrExceptionNotCaughtLocally: 16804 .asciz "Exception %s from %s:%d not caught locally\n" 16805 16806 .LstrNewline: 16807 .asciz "\n" 16808 .LstrSqueak: 16809 .asciz "<%d>" 16810 .LstrPrintHex: 16811 .asciz "<%#x>" 16812 .LstrPrintLong: 16813 .asciz "<%lld>" 16814 16815