1 /* 2 * This file was generated automatically by gen-mterp.py for 'armv5te'. 3 * 4 * --> DO NOT EDIT <-- 5 */ 6 7 /* File: armv5te/header.S */ 8 /* 9 * Copyright (C) 2008 The Android Open Source Project 10 * 11 * Licensed under the Apache License, Version 2.0 (the "License"); 12 * you may not use this file except in compliance with the License. 13 * You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, software 18 * distributed under the License is distributed on an "AS IS" BASIS, 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 * See the License for the specific language governing permissions and 21 * limitations under the License. 22 */ 23 24 /* 25 * ARMv5 definitions and declarations. 26 */ 27 28 /* 29 ARM EABI general notes: 30 31 r0-r3 hold first 4 args to a method; they are not preserved across method calls 32 r4-r8 are available for general use 33 r9 is given special treatment in some situations, but not for us 34 r10 (sl) seems to be generally available 35 r11 (fp) is used by gcc (unless -fomit-frame-pointer is set) 36 r12 (ip) is scratch -- not preserved across method calls 37 r13 (sp) should be managed carefully in case a signal arrives 38 r14 (lr) must be preserved 39 r15 (pc) can be tinkered with directly 40 41 r0 holds returns of <= 4 bytes 42 r0-r1 hold returns of 8 bytes, low word in r0 43 44 Callee must save/restore r4+ (except r12) if it modifies them. If VFP 45 is present, registers s16-s31 (a/k/a d8-d15, a/k/a q4-q7) must be preserved, 46 s0-s15 (d0-d7, q0-a3) do not need to be. 47 48 Stack is "full descending". Only the arguments that don't fit in the first 4 49 registers are placed on the stack. "sp" points at the first stacked argument 50 (i.e. the 5th arg). 51 52 VFP: single-precision results in s0, double-precision results in d0. 53 54 In the EABI, "sp" must be 64-bit aligned on entry to a function, and any 55 64-bit quantities (long long, double) must be 64-bit aligned. 56 */ 57 58 /* 59 Mterp and ARM notes: 60 61 The following registers have fixed assignments: 62 63 reg nick purpose 64 r4 rPC interpreted program counter, used for fetching instructions 65 r5 rFP interpreted frame pointer, used for accessing locals and args 66 r6 rSELF self (Thread) pointer 67 r7 rINST first 16-bit code unit of current instruction 68 r8 rIBASE interpreted instruction base pointer, used for computed goto 69 70 Macros are provided for common operations. Each macro MUST emit only 71 one instruction to make instruction-counting easier. They MUST NOT alter 72 unspecified registers or condition codes. 73 */ 74 75 /* single-purpose registers, given names for clarity */ 76 #define rPC r4 77 #define rFP r5 78 #define rSELF r6 79 #define rINST r7 80 #define rIBASE r8 81 82 /* save/restore the PC and/or FP from the thread struct */ 83 #define LOAD_PC_FROM_SELF() ldr rPC, [rSELF, #offThread_pc] 84 #define SAVE_PC_TO_SELF() str rPC, [rSELF, #offThread_pc] 85 #define LOAD_FP_FROM_SELF() ldr rFP, [rSELF, #offThread_curFrame] 86 #define SAVE_FP_TO_SELF() str rFP, [rSELF, #offThread_curFrame] 87 #define LOAD_PC_FP_FROM_SELF() ldmia rSELF, {rPC, rFP} 88 #define SAVE_PC_FP_TO_SELF() stmia rSELF, {rPC, rFP} 89 90 /* 91 * "export" the PC to the stack frame, f/b/o future exception objects. Must 92 * be done *before* something throws. 93 * 94 * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e. 95 * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc) 96 * 97 * It's okay to do this more than once. 98 */ 99 #define EXPORT_PC() \ 100 str rPC, [rFP, #(-sizeofStackSaveArea + offStackSaveArea_currentPc)] 101 102 /* 103 * Given a frame pointer, find the stack save area. 104 * 105 * In C this is "((StackSaveArea*)(_fp) -1)". 106 */ 107 #define SAVEAREA_FROM_FP(_reg, _fpreg) \ 108 sub _reg, _fpreg, #sizeofStackSaveArea 109 110 /* 111 * Fetch the next instruction from rPC into rINST. Does not advance rPC. 112 */ 113 #define FETCH_INST() ldrh rINST, [rPC] 114 115 /* 116 * Fetch the next instruction from the specified offset. Advances rPC 117 * to point to the next instruction. "_count" is in 16-bit code units. 118 * 119 * Because of the limited size of immediate constants on ARM, this is only 120 * suitable for small forward movements (i.e. don't try to implement "goto" 121 * with this). 122 * 123 * This must come AFTER anything that can throw an exception, or the 124 * exception catch may miss. (This also implies that it must come after 125 * EXPORT_PC().) 126 */ 127 #define FETCH_ADVANCE_INST(_count) ldrh rINST, [rPC, #((_count)*2)]! 128 129 /* 130 * The operation performed here is similar to FETCH_ADVANCE_INST, except the 131 * src and dest registers are parameterized (not hard-wired to rPC and rINST). 132 */ 133 #define PREFETCH_ADVANCE_INST(_dreg, _sreg, _count) \ 134 ldrh _dreg, [_sreg, #((_count)*2)]! 135 136 /* 137 * Fetch the next instruction from an offset specified by _reg. Updates 138 * rPC to point to the next instruction. "_reg" must specify the distance 139 * in bytes, *not* 16-bit code units, and may be a signed value. 140 * 141 * We want to write "ldrh rINST, [rPC, _reg, lsl #1]!", but some of the 142 * bits that hold the shift distance are used for the half/byte/sign flags. 143 * In some cases we can pre-double _reg for free, so we require a byte offset 144 * here. 145 */ 146 #define FETCH_ADVANCE_INST_RB(_reg) ldrh rINST, [rPC, _reg]! 147 148 /* 149 * Fetch a half-word code unit from an offset past the current PC. The 150 * "_count" value is in 16-bit code units. Does not advance rPC. 151 * 152 * The "_S" variant works the same but treats the value as signed. 153 */ 154 #define FETCH(_reg, _count) ldrh _reg, [rPC, #((_count)*2)] 155 #define FETCH_S(_reg, _count) ldrsh _reg, [rPC, #((_count)*2)] 156 157 /* 158 * Fetch one byte from an offset past the current PC. Pass in the same 159 * "_count" as you would for FETCH, and an additional 0/1 indicating which 160 * byte of the halfword you want (lo/hi). 161 */ 162 #define FETCH_B(_reg, _count, _byte) ldrb _reg, [rPC, #((_count)*2+(_byte))] 163 164 /* 165 * Put the instruction's opcode field into the specified register. 166 */ 167 #define GET_INST_OPCODE(_reg) and _reg, rINST, #255 168 169 /* 170 * Put the prefetched instruction's opcode field into the specified register. 171 */ 172 #define GET_PREFETCHED_OPCODE(_oreg, _ireg) and _oreg, _ireg, #255 173 174 /* 175 * Begin executing the opcode in _reg. Because this only jumps within the 176 * interpreter, we don't have to worry about pre-ARMv5 THUMB interwork. 177 */ 178 #define GOTO_OPCODE(_reg) add pc, rIBASE, _reg, lsl #6 179 #define GOTO_OPCODE_BASE(_base,_reg) add pc, _base, _reg, lsl #6 180 #define GOTO_OPCODE_IFEQ(_reg) addeq pc, rIBASE, _reg, lsl #6 181 #define GOTO_OPCODE_IFNE(_reg) addne pc, rIBASE, _reg, lsl #6 182 183 /* 184 * Get/set the 32-bit value from a Dalvik register. 185 */ 186 #define GET_VREG(_reg, _vreg) ldr _reg, [rFP, _vreg, lsl #2] 187 #define SET_VREG(_reg, _vreg) str _reg, [rFP, _vreg, lsl #2] 188 189 /* 190 * Convert a virtual register index into an address. 191 */ 192 #define VREG_INDEX_TO_ADDR(_reg, _vreg) \ 193 add _reg, rFP, _vreg, lsl #2 194 195 /* 196 * This is a #include, not a %include, because we want the C pre-processor 197 * to expand the macros into assembler assignment statements. 198 */ 199 #include "../common/asm-constants.h" 200 201 #if defined(WITH_JIT) 202 #include "../common/jit-config.h" 203 #endif 204 205 /* File: armv5te/platform.S */ 206 /* 207 * =========================================================================== 208 * CPU-version-specific defines 209 * =========================================================================== 210 */ 211 212 /* 213 * Macro for data memory barrier; not meaningful pre-ARMv6K. 214 */ 215 .macro SMP_DMB 216 .endm 217 218 /* 219 * Macro for data memory barrier; not meaningful pre-ARMv6K. 220 */ 221 .macro SMP_DMB_ST 222 .endm 223 224 /* File: armv5te/entry.S */ 225 /* 226 * Copyright (C) 2008 The Android Open Source Project 227 * 228 * Licensed under the Apache License, Version 2.0 (the "License"); 229 * you may not use this file except in compliance with the License. 230 * You may obtain a copy of the License at 231 * 232 * http://www.apache.org/licenses/LICENSE-2.0 233 * 234 * Unless required by applicable law or agreed to in writing, software 235 * distributed under the License is distributed on an "AS IS" BASIS, 236 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 237 * See the License for the specific language governing permissions and 238 * limitations under the License. 239 */ 240 /* 241 * Interpreter entry point. 242 */ 243 244 /* 245 * We don't have formal stack frames, so gdb scans upward in the code 246 * to find the start of the function (a label with the %function type), 247 * and then looks at the next few instructions to figure out what 248 * got pushed onto the stack. From this it figures out how to restore 249 * the registers, including PC, for the previous stack frame. If gdb 250 * sees a non-function label, it stops scanning, so either we need to 251 * have nothing but assembler-local labels between the entry point and 252 * the break, or we need to fake it out. 253 * 254 * When this is defined, we add some stuff to make gdb less confused. 255 */ 256 #define ASSIST_DEBUGGER 1 257 258 .text 259 .align 2 260 .global dvmMterpStdRun 261 .type dvmMterpStdRun, %function 262 263 /* 264 * On entry: 265 * r0 Thread* self 266 * 267 * The return comes via a call to dvmMterpStdBail(). 268 */ 269 dvmMterpStdRun: 270 #define MTERP_ENTRY1 \ 271 .save {r4-r10,fp,lr}; \ 272 stmfd sp!, {r4-r10,fp,lr} @ save 9 regs 273 #define MTERP_ENTRY2 \ 274 .pad #4; \ 275 sub sp, sp, #4 @ align 64 276 277 .fnstart 278 MTERP_ENTRY1 279 MTERP_ENTRY2 280 281 /* save stack pointer, add magic word for debuggerd */ 282 str sp, [r0, #offThread_bailPtr] @ save SP for eventual return 283 284 /* set up "named" registers, figure out entry point */ 285 mov rSELF, r0 @ set rSELF 286 LOAD_PC_FP_FROM_SELF() @ load rPC and rFP from "thread" 287 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ set rIBASE 288 289 #if defined(WITH_JIT) 290 .LentryInstr: 291 /* Entry is always a possible trace start */ 292 ldr r0, [rSELF, #offThread_pJitProfTable] 293 FETCH_INST() 294 mov r1, #0 @ prepare the value for the new state 295 str r1, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 296 cmp r0,#0 @ is profiling disabled? 297 #if !defined(WITH_SELF_VERIFICATION) 298 bne common_updateProfile @ profiling is enabled 299 #else 300 ldr r2, [rSELF, #offThread_shadowSpace] @ to find out the jit exit state 301 beq 1f @ profiling is disabled 302 ldr r3, [r2, #offShadowSpace_jitExitState] @ jit exit state 303 cmp r3, #kSVSTraceSelect @ hot trace following? 304 moveq r2,#kJitTSelectRequestHot @ ask for trace selection 305 beq common_selectTrace @ go build the trace 306 cmp r3, #kSVSNoProfile @ don't profile the next instruction? 307 beq 1f @ intrepret the next instruction 308 b common_updateProfile @ collect profiles 309 #endif 310 1: 311 GET_INST_OPCODE(ip) 312 GOTO_OPCODE(ip) 313 #else 314 /* start executing the instruction at rPC */ 315 FETCH_INST() @ load rINST from rPC 316 GET_INST_OPCODE(ip) @ extract opcode from rINST 317 GOTO_OPCODE(ip) @ jump to next instruction 318 #endif 319 320 .Lbad_arg: 321 ldr r0, strBadEntryPoint 322 0: add r0, pc 323 @ r1 holds value of entryPoint 324 bl printf 325 bl dvmAbort 326 .fnend 327 .size dvmMterpStdRun, .-dvmMterpStdRun 328 329 strBadEntryPoint: 330 .word PCREL_REF(.LstrBadEntryPoint,0b) 331 332 .global dvmMterpStdBail 333 .type dvmMterpStdBail, %function 334 335 /* 336 * Restore the stack pointer and PC from the save point established on entry. 337 * This is essentially the same as a longjmp, but should be cheaper. The 338 * last instruction causes us to return to whoever called dvmMterpStdRun. 339 * 340 * We pushed some registers on the stack in dvmMterpStdRun, then saved 341 * SP and LR. Here we restore SP, restore the registers, and then restore 342 * LR to PC. 343 * 344 * On entry: 345 * r0 Thread* self 346 */ 347 dvmMterpStdBail: 348 ldr sp, [r0, #offThread_bailPtr] @ sp<- saved SP 349 add sp, sp, #4 @ un-align 64 350 ldmfd sp!, {r4-r10,fp,pc} @ restore 9 regs and return 351 352 353 354 .global dvmAsmInstructionStart 355 .type dvmAsmInstructionStart, %function 356 dvmAsmInstructionStart = .L_OP_NOP 357 .text 358 359 /* ------------------------------ */ 360 .balign 64 361 .L_OP_NOP: /* 0x00 */ 362 /* File: armv5te/OP_NOP.S */ 363 FETCH_ADVANCE_INST(1) @ advance to next instr, load rINST 364 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 365 GOTO_OPCODE(ip) @ execute it 366 367 #ifdef ASSIST_DEBUGGER 368 /* insert fake function header to help gdb find the stack frame */ 369 .type dalvik_inst, %function 370 dalvik_inst: 371 .fnstart 372 MTERP_ENTRY1 373 MTERP_ENTRY2 374 .fnend 375 #endif 376 377 /* ------------------------------ */ 378 .balign 64 379 .L_OP_MOVE: /* 0x01 */ 380 /* File: armv5te/OP_MOVE.S */ 381 /* for move, move-object, long-to-int */ 382 /* op vA, vB */ 383 mov r1, rINST, lsr #12 @ r1<- B from 15:12 384 mov r0, rINST, lsr #8 @ r0<- A from 11:8 385 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 386 GET_VREG(r2, r1) @ r2<- fp[B] 387 and r0, r0, #15 388 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 389 SET_VREG(r2, r0) @ fp[A]<- r2 390 GOTO_OPCODE(ip) @ execute next instruction 391 392 /* ------------------------------ */ 393 .balign 64 394 .L_OP_MOVE_FROM16: /* 0x02 */ 395 /* File: armv5te/OP_MOVE_FROM16.S */ 396 /* for: move/from16, move-object/from16 */ 397 /* op vAA, vBBBB */ 398 FETCH(r1, 1) @ r1<- BBBB 399 mov r0, rINST, lsr #8 @ r0<- AA 400 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 401 GET_VREG(r2, r1) @ r2<- fp[BBBB] 402 GET_INST_OPCODE(ip) @ extract opcode from rINST 403 SET_VREG(r2, r0) @ fp[AA]<- r2 404 GOTO_OPCODE(ip) @ jump to next instruction 405 406 /* ------------------------------ */ 407 .balign 64 408 .L_OP_MOVE_16: /* 0x03 */ 409 /* File: armv5te/OP_MOVE_16.S */ 410 /* for: move/16, move-object/16 */ 411 /* op vAAAA, vBBBB */ 412 FETCH(r1, 2) @ r1<- BBBB 413 FETCH(r0, 1) @ r0<- AAAA 414 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 415 GET_VREG(r2, r1) @ r2<- fp[BBBB] 416 GET_INST_OPCODE(ip) @ extract opcode from rINST 417 SET_VREG(r2, r0) @ fp[AAAA]<- r2 418 GOTO_OPCODE(ip) @ jump to next instruction 419 420 /* ------------------------------ */ 421 .balign 64 422 .L_OP_MOVE_WIDE: /* 0x04 */ 423 /* File: armv5te/OP_MOVE_WIDE.S */ 424 /* move-wide vA, vB */ 425 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 426 mov r2, rINST, lsr #8 @ r2<- A(+) 427 mov r3, rINST, lsr #12 @ r3<- B 428 and r2, r2, #15 429 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 430 add r2, rFP, r2, lsl #2 @ r2<- &fp[A] 431 ldmia r3, {r0-r1} @ r0/r1<- fp[B] 432 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 433 stmia r2, {r0-r1} @ fp[A]<- r0/r1 434 GET_INST_OPCODE(ip) @ extract opcode from rINST 435 GOTO_OPCODE(ip) @ jump to next instruction 436 437 /* ------------------------------ */ 438 .balign 64 439 .L_OP_MOVE_WIDE_FROM16: /* 0x05 */ 440 /* File: armv5te/OP_MOVE_WIDE_FROM16.S */ 441 /* move-wide/from16 vAA, vBBBB */ 442 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 443 FETCH(r3, 1) @ r3<- BBBB 444 mov r2, rINST, lsr #8 @ r2<- AA 445 add r3, rFP, r3, lsl #2 @ r3<- &fp[BBBB] 446 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 447 ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB] 448 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 449 GET_INST_OPCODE(ip) @ extract opcode from rINST 450 stmia r2, {r0-r1} @ fp[AA]<- r0/r1 451 GOTO_OPCODE(ip) @ jump to next instruction 452 453 /* ------------------------------ */ 454 .balign 64 455 .L_OP_MOVE_WIDE_16: /* 0x06 */ 456 /* File: armv5te/OP_MOVE_WIDE_16.S */ 457 /* move-wide/16 vAAAA, vBBBB */ 458 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 459 FETCH(r3, 2) @ r3<- BBBB 460 FETCH(r2, 1) @ r2<- AAAA 461 add r3, rFP, r3, lsl #2 @ r3<- &fp[BBBB] 462 add r2, rFP, r2, lsl #2 @ r2<- &fp[AAAA] 463 ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB] 464 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 465 stmia r2, {r0-r1} @ fp[AAAA]<- r0/r1 466 GET_INST_OPCODE(ip) @ extract opcode from rINST 467 GOTO_OPCODE(ip) @ jump to next instruction 468 469 /* ------------------------------ */ 470 .balign 64 471 .L_OP_MOVE_OBJECT: /* 0x07 */ 472 /* File: armv5te/OP_MOVE_OBJECT.S */ 473 /* File: armv5te/OP_MOVE.S */ 474 /* for move, move-object, long-to-int */ 475 /* op vA, vB */ 476 mov r1, rINST, lsr #12 @ r1<- B from 15:12 477 mov r0, rINST, lsr #8 @ r0<- A from 11:8 478 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 479 GET_VREG(r2, r1) @ r2<- fp[B] 480 and r0, r0, #15 481 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 482 SET_VREG(r2, r0) @ fp[A]<- r2 483 GOTO_OPCODE(ip) @ execute next instruction 484 485 486 /* ------------------------------ */ 487 .balign 64 488 .L_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 489 /* File: armv5te/OP_MOVE_OBJECT_FROM16.S */ 490 /* File: armv5te/OP_MOVE_FROM16.S */ 491 /* for: move/from16, move-object/from16 */ 492 /* op vAA, vBBBB */ 493 FETCH(r1, 1) @ r1<- BBBB 494 mov r0, rINST, lsr #8 @ r0<- AA 495 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 496 GET_VREG(r2, r1) @ r2<- fp[BBBB] 497 GET_INST_OPCODE(ip) @ extract opcode from rINST 498 SET_VREG(r2, r0) @ fp[AA]<- r2 499 GOTO_OPCODE(ip) @ jump to next instruction 500 501 502 /* ------------------------------ */ 503 .balign 64 504 .L_OP_MOVE_OBJECT_16: /* 0x09 */ 505 /* File: armv5te/OP_MOVE_OBJECT_16.S */ 506 /* File: armv5te/OP_MOVE_16.S */ 507 /* for: move/16, move-object/16 */ 508 /* op vAAAA, vBBBB */ 509 FETCH(r1, 2) @ r1<- BBBB 510 FETCH(r0, 1) @ r0<- AAAA 511 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 512 GET_VREG(r2, r1) @ r2<- fp[BBBB] 513 GET_INST_OPCODE(ip) @ extract opcode from rINST 514 SET_VREG(r2, r0) @ fp[AAAA]<- r2 515 GOTO_OPCODE(ip) @ jump to next instruction 516 517 518 /* ------------------------------ */ 519 .balign 64 520 .L_OP_MOVE_RESULT: /* 0x0a */ 521 /* File: armv5te/OP_MOVE_RESULT.S */ 522 /* for: move-result, move-result-object */ 523 /* op vAA */ 524 mov r2, rINST, lsr #8 @ r2<- AA 525 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 526 ldr r0, [rSELF, #offThread_retval] @ r0<- self->retval.i 527 GET_INST_OPCODE(ip) @ extract opcode from rINST 528 SET_VREG(r0, r2) @ fp[AA]<- r0 529 GOTO_OPCODE(ip) @ jump to next instruction 530 531 /* ------------------------------ */ 532 .balign 64 533 .L_OP_MOVE_RESULT_WIDE: /* 0x0b */ 534 /* File: armv5te/OP_MOVE_RESULT_WIDE.S */ 535 /* move-result-wide vAA */ 536 mov r2, rINST, lsr #8 @ r2<- AA 537 add r3, rSELF, #offThread_retval @ r3<- &self->retval 538 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 539 ldmia r3, {r0-r1} @ r0/r1<- retval.j 540 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 541 stmia r2, {r0-r1} @ fp[AA]<- r0/r1 542 GET_INST_OPCODE(ip) @ extract opcode from rINST 543 GOTO_OPCODE(ip) @ jump to next instruction 544 545 /* ------------------------------ */ 546 .balign 64 547 .L_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 548 /* File: armv5te/OP_MOVE_RESULT_OBJECT.S */ 549 /* File: armv5te/OP_MOVE_RESULT.S */ 550 /* for: move-result, move-result-object */ 551 /* op vAA */ 552 mov r2, rINST, lsr #8 @ r2<- AA 553 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 554 ldr r0, [rSELF, #offThread_retval] @ r0<- self->retval.i 555 GET_INST_OPCODE(ip) @ extract opcode from rINST 556 SET_VREG(r0, r2) @ fp[AA]<- r0 557 GOTO_OPCODE(ip) @ jump to next instruction 558 559 560 /* ------------------------------ */ 561 .balign 64 562 .L_OP_MOVE_EXCEPTION: /* 0x0d */ 563 /* File: armv5te/OP_MOVE_EXCEPTION.S */ 564 /* move-exception vAA */ 565 mov r2, rINST, lsr #8 @ r2<- AA 566 ldr r3, [rSELF, #offThread_exception] @ r3<- dvmGetException bypass 567 mov r1, #0 @ r1<- 0 568 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 569 SET_VREG(r3, r2) @ fp[AA]<- exception obj 570 GET_INST_OPCODE(ip) @ extract opcode from rINST 571 str r1, [rSELF, #offThread_exception] @ dvmClearException bypass 572 GOTO_OPCODE(ip) @ jump to next instruction 573 574 /* ------------------------------ */ 575 .balign 64 576 .L_OP_RETURN_VOID: /* 0x0e */ 577 /* File: armv5te/OP_RETURN_VOID.S */ 578 b common_returnFromMethod 579 580 /* ------------------------------ */ 581 .balign 64 582 .L_OP_RETURN: /* 0x0f */ 583 /* File: armv5te/OP_RETURN.S */ 584 /* 585 * Return a 32-bit value. Copies the return value into the "thread" 586 * structure, then jumps to the return handler. 587 * 588 * for: return, return-object 589 */ 590 /* op vAA */ 591 mov r2, rINST, lsr #8 @ r2<- AA 592 GET_VREG(r0, r2) @ r0<- vAA 593 str r0, [rSELF, #offThread_retval] @ retval.i <- vAA 594 b common_returnFromMethod 595 596 /* ------------------------------ */ 597 .balign 64 598 .L_OP_RETURN_WIDE: /* 0x10 */ 599 /* File: armv5te/OP_RETURN_WIDE.S */ 600 /* 601 * Return a 64-bit value. Copies the return value into the "thread" 602 * structure, then jumps to the return handler. 603 */ 604 /* return-wide vAA */ 605 mov r2, rINST, lsr #8 @ r2<- AA 606 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 607 add r3, rSELF, #offThread_retval @ r3<- &self->retval 608 ldmia r2, {r0-r1} @ r0/r1 <- vAA/vAA+1 609 stmia r3, {r0-r1} @ retval<- r0/r1 610 b common_returnFromMethod 611 612 /* ------------------------------ */ 613 .balign 64 614 .L_OP_RETURN_OBJECT: /* 0x11 */ 615 /* File: armv5te/OP_RETURN_OBJECT.S */ 616 /* File: armv5te/OP_RETURN.S */ 617 /* 618 * Return a 32-bit value. Copies the return value into the "thread" 619 * structure, then jumps to the return handler. 620 * 621 * for: return, return-object 622 */ 623 /* op vAA */ 624 mov r2, rINST, lsr #8 @ r2<- AA 625 GET_VREG(r0, r2) @ r0<- vAA 626 str r0, [rSELF, #offThread_retval] @ retval.i <- vAA 627 b common_returnFromMethod 628 629 630 /* ------------------------------ */ 631 .balign 64 632 .L_OP_CONST_4: /* 0x12 */ 633 /* File: armv5te/OP_CONST_4.S */ 634 /* const/4 vA, #+B */ 635 mov r1, rINST, lsl #16 @ r1<- Bxxx0000 636 mov r0, rINST, lsr #8 @ r0<- A+ 637 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 638 mov r1, r1, asr #28 @ r1<- sssssssB (sign-extended) 639 and r0, r0, #15 640 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 641 SET_VREG(r1, r0) @ fp[A]<- r1 642 GOTO_OPCODE(ip) @ execute next instruction 643 644 /* ------------------------------ */ 645 .balign 64 646 .L_OP_CONST_16: /* 0x13 */ 647 /* File: armv5te/OP_CONST_16.S */ 648 /* const/16 vAA, #+BBBB */ 649 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 650 mov r3, rINST, lsr #8 @ r3<- AA 651 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 652 SET_VREG(r0, r3) @ vAA<- r0 653 GET_INST_OPCODE(ip) @ extract opcode from rINST 654 GOTO_OPCODE(ip) @ jump to next instruction 655 656 /* ------------------------------ */ 657 .balign 64 658 .L_OP_CONST: /* 0x14 */ 659 /* File: armv5te/OP_CONST.S */ 660 /* const vAA, #+BBBBbbbb */ 661 mov r3, rINST, lsr #8 @ r3<- AA 662 FETCH(r0, 1) @ r0<- bbbb (low) 663 FETCH(r1, 2) @ r1<- BBBB (high) 664 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 665 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 666 GET_INST_OPCODE(ip) @ extract opcode from rINST 667 SET_VREG(r0, r3) @ vAA<- r0 668 GOTO_OPCODE(ip) @ jump to next instruction 669 670 /* ------------------------------ */ 671 .balign 64 672 .L_OP_CONST_HIGH16: /* 0x15 */ 673 /* File: armv5te/OP_CONST_HIGH16.S */ 674 /* const/high16 vAA, #+BBBB0000 */ 675 FETCH(r0, 1) @ r0<- 0000BBBB (zero-extended) 676 mov r3, rINST, lsr #8 @ r3<- AA 677 mov r0, r0, lsl #16 @ r0<- BBBB0000 678 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 679 SET_VREG(r0, r3) @ vAA<- r0 680 GET_INST_OPCODE(ip) @ extract opcode from rINST 681 GOTO_OPCODE(ip) @ jump to next instruction 682 683 /* ------------------------------ */ 684 .balign 64 685 .L_OP_CONST_WIDE_16: /* 0x16 */ 686 /* File: armv5te/OP_CONST_WIDE_16.S */ 687 /* const-wide/16 vAA, #+BBBB */ 688 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 689 mov r3, rINST, lsr #8 @ r3<- AA 690 mov r1, r0, asr #31 @ r1<- ssssssss 691 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 692 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 693 GET_INST_OPCODE(ip) @ extract opcode from rINST 694 stmia r3, {r0-r1} @ vAA<- r0/r1 695 GOTO_OPCODE(ip) @ jump to next instruction 696 697 /* ------------------------------ */ 698 .balign 64 699 .L_OP_CONST_WIDE_32: /* 0x17 */ 700 /* File: armv5te/OP_CONST_WIDE_32.S */ 701 /* const-wide/32 vAA, #+BBBBbbbb */ 702 FETCH(r0, 1) @ r0<- 0000bbbb (low) 703 mov r3, rINST, lsr #8 @ r3<- AA 704 FETCH_S(r2, 2) @ r2<- ssssBBBB (high) 705 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 706 orr r0, r0, r2, lsl #16 @ r0<- BBBBbbbb 707 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 708 mov r1, r0, asr #31 @ r1<- ssssssss 709 GET_INST_OPCODE(ip) @ extract opcode from rINST 710 stmia r3, {r0-r1} @ vAA<- r0/r1 711 GOTO_OPCODE(ip) @ jump to next instruction 712 713 /* ------------------------------ */ 714 .balign 64 715 .L_OP_CONST_WIDE: /* 0x18 */ 716 /* File: armv5te/OP_CONST_WIDE.S */ 717 /* const-wide vAA, #+HHHHhhhhBBBBbbbb */ 718 FETCH(r0, 1) @ r0<- bbbb (low) 719 FETCH(r1, 2) @ r1<- BBBB (low middle) 720 FETCH(r2, 3) @ r2<- hhhh (high middle) 721 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb (low word) 722 FETCH(r3, 4) @ r3<- HHHH (high) 723 mov r9, rINST, lsr #8 @ r9<- AA 724 orr r1, r2, r3, lsl #16 @ r1<- HHHHhhhh (high word) 725 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 726 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 727 GET_INST_OPCODE(ip) @ extract opcode from rINST 728 stmia r9, {r0-r1} @ vAA<- r0/r1 729 GOTO_OPCODE(ip) @ jump to next instruction 730 731 /* ------------------------------ */ 732 .balign 64 733 .L_OP_CONST_WIDE_HIGH16: /* 0x19 */ 734 /* File: armv5te/OP_CONST_WIDE_HIGH16.S */ 735 /* const-wide/high16 vAA, #+BBBB000000000000 */ 736 FETCH(r1, 1) @ r1<- 0000BBBB (zero-extended) 737 mov r3, rINST, lsr #8 @ r3<- AA 738 mov r0, #0 @ r0<- 00000000 739 mov r1, r1, lsl #16 @ r1<- BBBB0000 740 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 741 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 742 GET_INST_OPCODE(ip) @ extract opcode from rINST 743 stmia r3, {r0-r1} @ vAA<- r0/r1 744 GOTO_OPCODE(ip) @ jump to next instruction 745 746 /* ------------------------------ */ 747 .balign 64 748 .L_OP_CONST_STRING: /* 0x1a */ 749 /* File: armv5te/OP_CONST_STRING.S */ 750 /* const/string vAA, String@BBBB */ 751 FETCH(r1, 1) @ r1<- BBBB 752 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 753 mov r9, rINST, lsr #8 @ r9<- AA 754 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 755 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 756 cmp r0, #0 @ not yet resolved? 757 beq .LOP_CONST_STRING_resolve 758 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 759 SET_VREG(r0, r9) @ vAA<- r0 760 GET_INST_OPCODE(ip) @ extract opcode from rINST 761 GOTO_OPCODE(ip) @ jump to next instruction 762 763 /* ------------------------------ */ 764 .balign 64 765 .L_OP_CONST_STRING_JUMBO: /* 0x1b */ 766 /* File: armv5te/OP_CONST_STRING_JUMBO.S */ 767 /* const/string vAA, String@BBBBBBBB */ 768 FETCH(r0, 1) @ r0<- bbbb (low) 769 FETCH(r1, 2) @ r1<- BBBB (high) 770 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 771 mov r9, rINST, lsr #8 @ r9<- AA 772 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 773 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 774 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 775 cmp r0, #0 776 beq .LOP_CONST_STRING_JUMBO_resolve 777 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 778 SET_VREG(r0, r9) @ vAA<- r0 779 GET_INST_OPCODE(ip) @ extract opcode from rINST 780 GOTO_OPCODE(ip) @ jump to next instruction 781 782 /* ------------------------------ */ 783 .balign 64 784 .L_OP_CONST_CLASS: /* 0x1c */ 785 /* File: armv5te/OP_CONST_CLASS.S */ 786 /* const/class vAA, Class@BBBB */ 787 FETCH(r1, 1) @ r1<- BBBB 788 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 789 mov r9, rINST, lsr #8 @ r9<- AA 790 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- dvmDex->pResClasses 791 ldr r0, [r2, r1, lsl #2] @ r0<- pResClasses[BBBB] 792 cmp r0, #0 @ not yet resolved? 793 beq .LOP_CONST_CLASS_resolve 794 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 795 SET_VREG(r0, r9) @ vAA<- r0 796 GET_INST_OPCODE(ip) @ extract opcode from rINST 797 GOTO_OPCODE(ip) @ jump to next instruction 798 799 /* ------------------------------ */ 800 .balign 64 801 .L_OP_MONITOR_ENTER: /* 0x1d */ 802 /* File: armv5te/OP_MONITOR_ENTER.S */ 803 /* 804 * Synchronize on an object. 805 */ 806 /* monitor-enter vAA */ 807 mov r2, rINST, lsr #8 @ r2<- AA 808 GET_VREG(r1, r2) @ r1<- vAA (object) 809 mov r0, rSELF @ r0<- self 810 cmp r1, #0 @ null object? 811 EXPORT_PC() @ need for precise GC 812 beq common_errNullObject @ null object, throw an exception 813 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 814 bl dvmLockObject @ call(self, obj) 815 GET_INST_OPCODE(ip) @ extract opcode from rINST 816 GOTO_OPCODE(ip) @ jump to next instruction 817 818 /* ------------------------------ */ 819 .balign 64 820 .L_OP_MONITOR_EXIT: /* 0x1e */ 821 /* File: armv5te/OP_MONITOR_EXIT.S */ 822 /* 823 * Unlock an object. 824 * 825 * Exceptions that occur when unlocking a monitor need to appear as 826 * if they happened at the following instruction. See the Dalvik 827 * instruction spec. 828 */ 829 /* monitor-exit vAA */ 830 mov r2, rINST, lsr #8 @ r2<- AA 831 EXPORT_PC() @ before fetch: export the PC 832 GET_VREG(r1, r2) @ r1<- vAA (object) 833 cmp r1, #0 @ null object? 834 beq 1f @ yes 835 mov r0, rSELF @ r0<- self 836 bl dvmUnlockObject @ r0<- success for unlock(self, obj) 837 cmp r0, #0 @ failed? 838 FETCH_ADVANCE_INST(1) @ before throw: advance rPC, load rINST 839 beq common_exceptionThrown @ yes, exception is pending 840 GET_INST_OPCODE(ip) @ extract opcode from rINST 841 GOTO_OPCODE(ip) @ jump to next instruction 842 1: 843 FETCH_ADVANCE_INST(1) @ advance before throw 844 b common_errNullObject 845 846 /* ------------------------------ */ 847 .balign 64 848 .L_OP_CHECK_CAST: /* 0x1f */ 849 /* File: armv5te/OP_CHECK_CAST.S */ 850 /* 851 * Check to see if a cast from one class to another is allowed. 852 */ 853 /* check-cast vAA, class@BBBB */ 854 mov r3, rINST, lsr #8 @ r3<- AA 855 FETCH(r2, 1) @ r2<- BBBB 856 GET_VREG(r9, r3) @ r9<- object 857 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- pDvmDex 858 cmp r9, #0 @ is object null? 859 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 860 beq .LOP_CHECK_CAST_okay @ null obj, cast always succeeds 861 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 862 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 863 cmp r1, #0 @ have we resolved this before? 864 beq .LOP_CHECK_CAST_resolve @ not resolved, do it now 865 .LOP_CHECK_CAST_resolved: 866 cmp r0, r1 @ same class (trivial success)? 867 bne .LOP_CHECK_CAST_fullcheck @ no, do full check 868 .LOP_CHECK_CAST_okay: 869 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 870 GET_INST_OPCODE(ip) @ extract opcode from rINST 871 GOTO_OPCODE(ip) @ jump to next instruction 872 873 /* ------------------------------ */ 874 .balign 64 875 .L_OP_INSTANCE_OF: /* 0x20 */ 876 /* File: armv5te/OP_INSTANCE_OF.S */ 877 /* 878 * Check to see if an object reference is an instance of a class. 879 * 880 * Most common situation is a non-null object, being compared against 881 * an already-resolved class. 882 */ 883 /* instance-of vA, vB, class@CCCC */ 884 mov r3, rINST, lsr #12 @ r3<- B 885 mov r9, rINST, lsr #8 @ r9<- A+ 886 GET_VREG(r0, r3) @ r0<- vB (object) 887 and r9, r9, #15 @ r9<- A 888 cmp r0, #0 @ is object null? 889 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- pDvmDex 890 beq .LOP_INSTANCE_OF_store @ null obj, not an instance, store r0 891 FETCH(r3, 1) @ r3<- CCCC 892 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 893 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 894 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 895 cmp r1, #0 @ have we resolved this before? 896 beq .LOP_INSTANCE_OF_resolve @ not resolved, do it now 897 .LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class 898 cmp r0, r1 @ same class (trivial success)? 899 beq .LOP_INSTANCE_OF_trivial @ yes, trivial finish 900 b .LOP_INSTANCE_OF_fullcheck @ no, do full check 901 902 /* ------------------------------ */ 903 .balign 64 904 .L_OP_ARRAY_LENGTH: /* 0x21 */ 905 /* File: armv5te/OP_ARRAY_LENGTH.S */ 906 /* 907 * Return the length of an array. 908 */ 909 mov r1, rINST, lsr #12 @ r1<- B 910 mov r2, rINST, lsr #8 @ r2<- A+ 911 GET_VREG(r0, r1) @ r0<- vB (object ref) 912 and r2, r2, #15 @ r2<- A 913 cmp r0, #0 @ is object null? 914 beq common_errNullObject @ yup, fail 915 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 916 ldr r3, [r0, #offArrayObject_length] @ r3<- array length 917 GET_INST_OPCODE(ip) @ extract opcode from rINST 918 SET_VREG(r3, r2) @ vB<- length 919 GOTO_OPCODE(ip) @ jump to next instruction 920 921 /* ------------------------------ */ 922 .balign 64 923 .L_OP_NEW_INSTANCE: /* 0x22 */ 924 /* File: armv5te/OP_NEW_INSTANCE.S */ 925 /* 926 * Create a new instance of a class. 927 */ 928 /* new-instance vAA, class@BBBB */ 929 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 930 FETCH(r1, 1) @ r1<- BBBB 931 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 932 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 933 #if defined(WITH_JIT) 934 add r10, r3, r1, lsl #2 @ r10<- &resolved_class 935 #endif 936 EXPORT_PC() @ req'd for init, resolve, alloc 937 cmp r0, #0 @ already resolved? 938 beq .LOP_NEW_INSTANCE_resolve @ no, resolve it now 939 .LOP_NEW_INSTANCE_resolved: @ r0=class 940 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 941 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 942 bne .LOP_NEW_INSTANCE_needinit @ no, init class now 943 .LOP_NEW_INSTANCE_initialized: @ r0=class 944 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 945 bl dvmAllocObject @ r0<- new object 946 b .LOP_NEW_INSTANCE_finish @ continue 947 948 /* ------------------------------ */ 949 .balign 64 950 .L_OP_NEW_ARRAY: /* 0x23 */ 951 /* File: armv5te/OP_NEW_ARRAY.S */ 952 /* 953 * Allocate an array of objects, specified with the array class 954 * and a count. 955 * 956 * The verifier guarantees that this is an array class, so we don't 957 * check for it here. 958 */ 959 /* new-array vA, vB, class@CCCC */ 960 mov r0, rINST, lsr #12 @ r0<- B 961 FETCH(r2, 1) @ r2<- CCCC 962 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 963 GET_VREG(r1, r0) @ r1<- vB (array length) 964 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 965 cmp r1, #0 @ check length 966 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 967 bmi common_errNegativeArraySize @ negative length, bail - len in r1 968 cmp r0, #0 @ already resolved? 969 EXPORT_PC() @ req'd for resolve, alloc 970 bne .LOP_NEW_ARRAY_finish @ resolved, continue 971 b .LOP_NEW_ARRAY_resolve @ do resolve now 972 973 /* ------------------------------ */ 974 .balign 64 975 .L_OP_FILLED_NEW_ARRAY: /* 0x24 */ 976 /* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 977 /* 978 * Create a new array with elements filled from registers. 979 * 980 * for: filled-new-array, filled-new-array/range 981 */ 982 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 983 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 984 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 985 FETCH(r1, 1) @ r1<- BBBB 986 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 987 EXPORT_PC() @ need for resolve and alloc 988 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 989 mov r10, rINST, lsr #8 @ r10<- AA or BA 990 cmp r0, #0 @ already resolved? 991 bne .LOP_FILLED_NEW_ARRAY_continue @ yes, continue on 992 8: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 993 mov r2, #0 @ r2<- false 994 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 995 bl dvmResolveClass @ r0<- call(clazz, ref) 996 cmp r0, #0 @ got null? 997 beq common_exceptionThrown @ yes, handle exception 998 b .LOP_FILLED_NEW_ARRAY_continue 999 1000 /* ------------------------------ */ 1001 .balign 64 1002 .L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 1003 /* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */ 1004 /* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1005 /* 1006 * Create a new array with elements filled from registers. 1007 * 1008 * for: filled-new-array, filled-new-array/range 1009 */ 1010 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1011 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1012 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 1013 FETCH(r1, 1) @ r1<- BBBB 1014 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1015 EXPORT_PC() @ need for resolve and alloc 1016 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1017 mov r10, rINST, lsr #8 @ r10<- AA or BA 1018 cmp r0, #0 @ already resolved? 1019 bne .LOP_FILLED_NEW_ARRAY_RANGE_continue @ yes, continue on 1020 8: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 1021 mov r2, #0 @ r2<- false 1022 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1023 bl dvmResolveClass @ r0<- call(clazz, ref) 1024 cmp r0, #0 @ got null? 1025 beq common_exceptionThrown @ yes, handle exception 1026 b .LOP_FILLED_NEW_ARRAY_RANGE_continue 1027 1028 1029 /* ------------------------------ */ 1030 .balign 64 1031 .L_OP_FILL_ARRAY_DATA: /* 0x26 */ 1032 /* File: armv5te/OP_FILL_ARRAY_DATA.S */ 1033 /* fill-array-data vAA, +BBBBBBBB */ 1034 FETCH(r0, 1) @ r0<- bbbb (lo) 1035 FETCH(r1, 2) @ r1<- BBBB (hi) 1036 mov r3, rINST, lsr #8 @ r3<- AA 1037 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 1038 GET_VREG(r0, r3) @ r0<- vAA (array object) 1039 add r1, rPC, r1, lsl #1 @ r1<- PC + BBBBbbbb*2 (array data off.) 1040 EXPORT_PC(); 1041 bl dvmInterpHandleFillArrayData@ fill the array with predefined data 1042 cmp r0, #0 @ 0 means an exception is thrown 1043 beq common_exceptionThrown @ has exception 1044 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 1045 GET_INST_OPCODE(ip) @ extract opcode from rINST 1046 GOTO_OPCODE(ip) @ jump to next instruction 1047 1048 /* ------------------------------ */ 1049 .balign 64 1050 .L_OP_THROW: /* 0x27 */ 1051 /* File: armv5te/OP_THROW.S */ 1052 /* 1053 * Throw an exception object in the current thread. 1054 */ 1055 /* throw vAA */ 1056 mov r2, rINST, lsr #8 @ r2<- AA 1057 GET_VREG(r1, r2) @ r1<- vAA (exception object) 1058 EXPORT_PC() @ exception handler can throw 1059 cmp r1, #0 @ null object? 1060 beq common_errNullObject @ yes, throw an NPE instead 1061 @ bypass dvmSetException, just store it 1062 str r1, [rSELF, #offThread_exception] @ thread->exception<- obj 1063 b common_exceptionThrown 1064 1065 /* ------------------------------ */ 1066 .balign 64 1067 .L_OP_GOTO: /* 0x28 */ 1068 /* File: armv5te/OP_GOTO.S */ 1069 /* 1070 * Unconditional branch, 8-bit offset. 1071 * 1072 * The branch distance is a signed code-unit offset, which we need to 1073 * double to get a byte offset. 1074 */ 1075 /* goto +AA */ 1076 /* tuning: use sbfx for 6t2+ targets */ 1077 mov r0, rINST, lsl #16 @ r0<- AAxx0000 1078 movs r1, r0, asr #24 @ r1<- ssssssAA (sign-extended) 1079 add r2, r1, r1 @ r2<- byte offset, set flags 1080 @ If backwards branch refresh rIBASE 1081 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1082 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1083 #if defined(WITH_JIT) 1084 ldr r0, [rSELF, #offThread_pJitProfTable] 1085 bmi common_testUpdateProfile @ (r0) check for trace hotness 1086 #endif 1087 GET_INST_OPCODE(ip) @ extract opcode from rINST 1088 GOTO_OPCODE(ip) @ jump to next instruction 1089 1090 /* ------------------------------ */ 1091 .balign 64 1092 .L_OP_GOTO_16: /* 0x29 */ 1093 /* File: armv5te/OP_GOTO_16.S */ 1094 /* 1095 * Unconditional branch, 16-bit offset. 1096 * 1097 * The branch distance is a signed code-unit offset, which we need to 1098 * double to get a byte offset. 1099 */ 1100 /* goto/16 +AAAA */ 1101 FETCH_S(r0, 1) @ r0<- ssssAAAA (sign-extended) 1102 adds r1, r0, r0 @ r1<- byte offset, flags set 1103 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1104 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1105 #if defined(WITH_JIT) 1106 ldr r0, [rSELF, #offThread_pJitProfTable] 1107 bmi common_testUpdateProfile @ (r0) hot trace head? 1108 #endif 1109 GET_INST_OPCODE(ip) @ extract opcode from rINST 1110 GOTO_OPCODE(ip) @ jump to next instruction 1111 1112 /* ------------------------------ */ 1113 .balign 64 1114 .L_OP_GOTO_32: /* 0x2a */ 1115 /* File: armv5te/OP_GOTO_32.S */ 1116 /* 1117 * Unconditional branch, 32-bit offset. 1118 * 1119 * The branch distance is a signed code-unit offset, which we need to 1120 * double to get a byte offset. 1121 * 1122 * Unlike most opcodes, this one is allowed to branch to itself, so 1123 * our "backward branch" test must be "<=0" instead of "<0". Because 1124 * we need the V bit set, we'll use an adds to convert from Dalvik 1125 * offset to byte offset. 1126 */ 1127 /* goto/32 +AAAAAAAA */ 1128 FETCH(r0, 1) @ r0<- aaaa (lo) 1129 FETCH(r1, 2) @ r1<- AAAA (hi) 1130 orr r0, r0, r1, lsl #16 @ r0<- AAAAaaaa 1131 adds r1, r0, r0 @ r1<- byte offset 1132 #if defined(WITH_JIT) 1133 ldr r0, [rSELF, #offThread_pJitProfTable] 1134 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1135 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1136 ble common_testUpdateProfile @ (r0) hot trace head? 1137 #else 1138 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1139 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1140 #endif 1141 GET_INST_OPCODE(ip) @ extract opcode from rINST 1142 GOTO_OPCODE(ip) @ jump to next instruction 1143 1144 /* ------------------------------ */ 1145 .balign 64 1146 .L_OP_PACKED_SWITCH: /* 0x2b */ 1147 /* File: armv5te/OP_PACKED_SWITCH.S */ 1148 /* 1149 * Handle a packed-switch or sparse-switch instruction. In both cases 1150 * we decode it and hand it off to a helper function. 1151 * 1152 * We don't really expect backward branches in a switch statement, but 1153 * they're perfectly legal, so we check for them here. 1154 * 1155 * When the JIT is present, all targets are considered treated as 1156 * a potential trace heads regardless of branch direction. 1157 * 1158 * for: packed-switch, sparse-switch 1159 */ 1160 /* op vAA, +BBBB */ 1161 FETCH(r0, 1) @ r0<- bbbb (lo) 1162 FETCH(r1, 2) @ r1<- BBBB (hi) 1163 mov r3, rINST, lsr #8 @ r3<- AA 1164 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1165 GET_VREG(r1, r3) @ r1<- vAA 1166 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1167 bl dvmInterpHandlePackedSwitch @ r0<- code-unit branch offset 1168 adds r1, r0, r0 @ r1<- byte offset; clear V 1169 #if defined(WITH_JIT) 1170 ldr r0, [rSELF, #offThread_pJitProfTable] 1171 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1172 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1173 cmp r0, #0 1174 bne common_updateProfile 1175 #else 1176 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1177 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1178 #endif 1179 GET_INST_OPCODE(ip) @ extract opcode from rINST 1180 GOTO_OPCODE(ip) @ jump to next instruction 1181 1182 /* ------------------------------ */ 1183 .balign 64 1184 .L_OP_SPARSE_SWITCH: /* 0x2c */ 1185 /* File: armv5te/OP_SPARSE_SWITCH.S */ 1186 /* File: armv5te/OP_PACKED_SWITCH.S */ 1187 /* 1188 * Handle a packed-switch or sparse-switch instruction. In both cases 1189 * we decode it and hand it off to a helper function. 1190 * 1191 * We don't really expect backward branches in a switch statement, but 1192 * they're perfectly legal, so we check for them here. 1193 * 1194 * When the JIT is present, all targets are considered treated as 1195 * a potential trace heads regardless of branch direction. 1196 * 1197 * for: packed-switch, sparse-switch 1198 */ 1199 /* op vAA, +BBBB */ 1200 FETCH(r0, 1) @ r0<- bbbb (lo) 1201 FETCH(r1, 2) @ r1<- BBBB (hi) 1202 mov r3, rINST, lsr #8 @ r3<- AA 1203 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1204 GET_VREG(r1, r3) @ r1<- vAA 1205 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1206 bl dvmInterpHandleSparseSwitch @ r0<- code-unit branch offset 1207 adds r1, r0, r0 @ r1<- byte offset; clear V 1208 #if defined(WITH_JIT) 1209 ldr r0, [rSELF, #offThread_pJitProfTable] 1210 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1211 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1212 cmp r0, #0 1213 bne common_updateProfile 1214 #else 1215 ldrle rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base 1216 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1217 #endif 1218 GET_INST_OPCODE(ip) @ extract opcode from rINST 1219 GOTO_OPCODE(ip) @ jump to next instruction 1220 1221 1222 /* ------------------------------ */ 1223 .balign 64 1224 .L_OP_CMPL_FLOAT: /* 0x2d */ 1225 /* File: armv5te/OP_CMPL_FLOAT.S */ 1226 /* 1227 * Compare two floating-point values. Puts 0, 1, or -1 into the 1228 * destination register based on the results of the comparison. 1229 * 1230 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending 1231 * on what value we'd like to return when one of the operands is NaN. 1232 * 1233 * The operation we're implementing is: 1234 * if (x == y) 1235 * return 0; 1236 * else if (x < y) 1237 * return -1; 1238 * else if (x > y) 1239 * return 1; 1240 * else 1241 * return {-1,1}; // one or both operands was NaN 1242 * 1243 * The straightforward implementation requires 3 calls to functions 1244 * that return a result in r0. We can do it with two calls if our 1245 * EABI library supports __aeabi_cfcmple (only one if we want to check 1246 * for NaN directly): 1247 * check x <= y 1248 * if <, return -1 1249 * if ==, return 0 1250 * check y <= x 1251 * if <, return 1 1252 * return {-1,1} 1253 * 1254 * for: cmpl-float, cmpg-float 1255 */ 1256 /* op vAA, vBB, vCC */ 1257 FETCH(r0, 1) @ r0<- CCBB 1258 and r2, r0, #255 @ r2<- BB 1259 mov r3, r0, lsr #8 @ r3<- CC 1260 GET_VREG(r9, r2) @ r9<- vBB 1261 GET_VREG(r10, r3) @ r10<- vCC 1262 mov r0, r9 @ copy to arg registers 1263 mov r1, r10 1264 bl __aeabi_cfcmple @ cmp <=: C clear if <, Z set if eq 1265 bhi .LOP_CMPL_FLOAT_gt_or_nan @ C set and Z clear, disambiguate 1266 mvncc r1, #0 @ (less than) r1<- -1 1267 moveq r1, #0 @ (equal) r1<- 0, trumps less than 1268 .LOP_CMPL_FLOAT_finish: 1269 mov r3, rINST, lsr #8 @ r3<- AA 1270 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1271 SET_VREG(r1, r3) @ vAA<- r1 1272 GET_INST_OPCODE(ip) @ extract opcode from rINST 1273 GOTO_OPCODE(ip) @ jump to next instruction 1274 1275 /* ------------------------------ */ 1276 .balign 64 1277 .L_OP_CMPG_FLOAT: /* 0x2e */ 1278 /* File: armv5te/OP_CMPG_FLOAT.S */ 1279 /* File: armv5te/OP_CMPL_FLOAT.S */ 1280 /* 1281 * Compare two floating-point values. Puts 0, 1, or -1 into the 1282 * destination register based on the results of the comparison. 1283 * 1284 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending 1285 * on what value we'd like to return when one of the operands is NaN. 1286 * 1287 * The operation we're implementing is: 1288 * if (x == y) 1289 * return 0; 1290 * else if (x < y) 1291 * return -1; 1292 * else if (x > y) 1293 * return 1; 1294 * else 1295 * return {-1,1}; // one or both operands was NaN 1296 * 1297 * The straightforward implementation requires 3 calls to functions 1298 * that return a result in r0. We can do it with two calls if our 1299 * EABI library supports __aeabi_cfcmple (only one if we want to check 1300 * for NaN directly): 1301 * check x <= y 1302 * if <, return -1 1303 * if ==, return 0 1304 * check y <= x 1305 * if <, return 1 1306 * return {-1,1} 1307 * 1308 * for: cmpl-float, cmpg-float 1309 */ 1310 /* op vAA, vBB, vCC */ 1311 FETCH(r0, 1) @ r0<- CCBB 1312 and r2, r0, #255 @ r2<- BB 1313 mov r3, r0, lsr #8 @ r3<- CC 1314 GET_VREG(r9, r2) @ r9<- vBB 1315 GET_VREG(r10, r3) @ r10<- vCC 1316 mov r0, r9 @ copy to arg registers 1317 mov r1, r10 1318 bl __aeabi_cfcmple @ cmp <=: C clear if <, Z set if eq 1319 bhi .LOP_CMPG_FLOAT_gt_or_nan @ C set and Z clear, disambiguate 1320 mvncc r1, #0 @ (less than) r1<- -1 1321 moveq r1, #0 @ (equal) r1<- 0, trumps less than 1322 .LOP_CMPG_FLOAT_finish: 1323 mov r3, rINST, lsr #8 @ r3<- AA 1324 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1325 SET_VREG(r1, r3) @ vAA<- r1 1326 GET_INST_OPCODE(ip) @ extract opcode from rINST 1327 GOTO_OPCODE(ip) @ jump to next instruction 1328 1329 1330 /* ------------------------------ */ 1331 .balign 64 1332 .L_OP_CMPL_DOUBLE: /* 0x2f */ 1333 /* File: armv5te/OP_CMPL_DOUBLE.S */ 1334 /* 1335 * Compare two floating-point values. Puts 0, 1, or -1 into the 1336 * destination register based on the results of the comparison. 1337 * 1338 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending 1339 * on what value we'd like to return when one of the operands is NaN. 1340 * 1341 * See OP_CMPL_FLOAT for an explanation. 1342 * 1343 * For: cmpl-double, cmpg-double 1344 */ 1345 /* op vAA, vBB, vCC */ 1346 FETCH(r0, 1) @ r0<- CCBB 1347 and r9, r0, #255 @ r9<- BB 1348 mov r10, r0, lsr #8 @ r10<- CC 1349 add r9, rFP, r9, lsl #2 @ r9<- &fp[BB] 1350 add r10, rFP, r10, lsl #2 @ r10<- &fp[CC] 1351 ldmia r9, {r0-r1} @ r0/r1<- vBB/vBB+1 1352 ldmia r10, {r2-r3} @ r2/r3<- vCC/vCC+1 1353 bl __aeabi_cdcmple @ cmp <=: C clear if <, Z set if eq 1354 bhi .LOP_CMPL_DOUBLE_gt_or_nan @ C set and Z clear, disambiguate 1355 mvncc r1, #0 @ (less than) r1<- -1 1356 moveq r1, #0 @ (equal) r1<- 0, trumps less than 1357 .LOP_CMPL_DOUBLE_finish: 1358 mov r3, rINST, lsr #8 @ r3<- AA 1359 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1360 SET_VREG(r1, r3) @ vAA<- r1 1361 GET_INST_OPCODE(ip) @ extract opcode from rINST 1362 GOTO_OPCODE(ip) @ jump to next instruction 1363 1364 /* ------------------------------ */ 1365 .balign 64 1366 .L_OP_CMPG_DOUBLE: /* 0x30 */ 1367 /* File: armv5te/OP_CMPG_DOUBLE.S */ 1368 /* File: armv5te/OP_CMPL_DOUBLE.S */ 1369 /* 1370 * Compare two floating-point values. Puts 0, 1, or -1 into the 1371 * destination register based on the results of the comparison. 1372 * 1373 * Provide a "naninst" instruction that puts 1 or -1 into r1 depending 1374 * on what value we'd like to return when one of the operands is NaN. 1375 * 1376 * See OP_CMPL_FLOAT for an explanation. 1377 * 1378 * For: cmpl-double, cmpg-double 1379 */ 1380 /* op vAA, vBB, vCC */ 1381 FETCH(r0, 1) @ r0<- CCBB 1382 and r9, r0, #255 @ r9<- BB 1383 mov r10, r0, lsr #8 @ r10<- CC 1384 add r9, rFP, r9, lsl #2 @ r9<- &fp[BB] 1385 add r10, rFP, r10, lsl #2 @ r10<- &fp[CC] 1386 ldmia r9, {r0-r1} @ r0/r1<- vBB/vBB+1 1387 ldmia r10, {r2-r3} @ r2/r3<- vCC/vCC+1 1388 bl __aeabi_cdcmple @ cmp <=: C clear if <, Z set if eq 1389 bhi .LOP_CMPG_DOUBLE_gt_or_nan @ C set and Z clear, disambiguate 1390 mvncc r1, #0 @ (less than) r1<- -1 1391 moveq r1, #0 @ (equal) r1<- 0, trumps less than 1392 .LOP_CMPG_DOUBLE_finish: 1393 mov r3, rINST, lsr #8 @ r3<- AA 1394 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1395 SET_VREG(r1, r3) @ vAA<- r1 1396 GET_INST_OPCODE(ip) @ extract opcode from rINST 1397 GOTO_OPCODE(ip) @ jump to next instruction 1398 1399 1400 /* ------------------------------ */ 1401 .balign 64 1402 .L_OP_CMP_LONG: /* 0x31 */ 1403 /* File: armv5te/OP_CMP_LONG.S */ 1404 /* 1405 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 1406 * register based on the results of the comparison. 1407 * 1408 * We load the full values with LDM, but in practice many values could 1409 * be resolved by only looking at the high word. This could be made 1410 * faster or slower by splitting the LDM into a pair of LDRs. 1411 * 1412 * If we just wanted to set condition flags, we could do this: 1413 * subs ip, r0, r2 1414 * sbcs ip, r1, r3 1415 * subeqs ip, r0, r2 1416 * Leaving { <0, 0, >0 } in ip. However, we have to set it to a specific 1417 * integer value, which we can do with 2 conditional mov/mvn instructions 1418 * (set 1, set -1; if they're equal we already have 0 in ip), giving 1419 * us a constant 5-cycle path plus a branch at the end to the 1420 * instruction epilogue code. The multi-compare approach below needs 1421 * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch 1422 * in the worst case (the 64-bit values are equal). 1423 */ 1424 /* cmp-long vAA, vBB, vCC */ 1425 FETCH(r0, 1) @ r0<- CCBB 1426 mov r9, rINST, lsr #8 @ r9<- AA 1427 and r2, r0, #255 @ r2<- BB 1428 mov r3, r0, lsr #8 @ r3<- CC 1429 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 1430 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 1431 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 1432 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 1433 cmp r1, r3 @ compare (vBB+1, vCC+1) 1434 blt .LOP_CMP_LONG_less @ signed compare on high part 1435 bgt .LOP_CMP_LONG_greater 1436 subs r1, r0, r2 @ r1<- r0 - r2 1437 bhi .LOP_CMP_LONG_greater @ unsigned compare on low part 1438 bne .LOP_CMP_LONG_less 1439 b .LOP_CMP_LONG_finish @ equal; r1 already holds 0 1440 1441 /* ------------------------------ */ 1442 .balign 64 1443 .L_OP_IF_EQ: /* 0x32 */ 1444 /* File: armv5te/OP_IF_EQ.S */ 1445 /* File: armv5te/bincmp.S */ 1446 /* 1447 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1448 * fragment that specifies the *reverse* comparison to perform, e.g. 1449 * for "if-le" you would use "gt". 1450 * 1451 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1452 */ 1453 /* if-cmp vA, vB, +CCCC */ 1454 mov r0, rINST, lsr #8 @ r0<- A+ 1455 mov r1, rINST, lsr #12 @ r1<- B 1456 and r0, r0, #15 1457 GET_VREG(r3, r1) @ r3<- vB 1458 GET_VREG(r2, r0) @ r2<- vA 1459 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1460 cmp r2, r3 @ compare (vA, vB) 1461 movne r1, #2 @ r1<- BYTE branch dist for not-taken 1462 adds r2, r1, r1 @ convert to bytes, check sign 1463 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1464 #if defined(WITH_JIT) 1465 ldr r0, [rSELF, #offThread_pJitProfTable] 1466 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1467 cmp r0,#0 1468 bne common_updateProfile 1469 #else 1470 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1471 #endif 1472 GET_INST_OPCODE(ip) @ extract opcode from rINST 1473 GOTO_OPCODE(ip) @ jump to next instruction 1474 1475 1476 /* ------------------------------ */ 1477 .balign 64 1478 .L_OP_IF_NE: /* 0x33 */ 1479 /* File: armv5te/OP_IF_NE.S */ 1480 /* File: armv5te/bincmp.S */ 1481 /* 1482 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1483 * fragment that specifies the *reverse* comparison to perform, e.g. 1484 * for "if-le" you would use "gt". 1485 * 1486 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1487 */ 1488 /* if-cmp vA, vB, +CCCC */ 1489 mov r0, rINST, lsr #8 @ r0<- A+ 1490 mov r1, rINST, lsr #12 @ r1<- B 1491 and r0, r0, #15 1492 GET_VREG(r3, r1) @ r3<- vB 1493 GET_VREG(r2, r0) @ r2<- vA 1494 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1495 cmp r2, r3 @ compare (vA, vB) 1496 moveq r1, #2 @ r1<- BYTE branch dist for not-taken 1497 adds r2, r1, r1 @ convert to bytes, check sign 1498 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1499 #if defined(WITH_JIT) 1500 ldr r0, [rSELF, #offThread_pJitProfTable] 1501 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1502 cmp r0,#0 1503 bne common_updateProfile 1504 #else 1505 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1506 #endif 1507 GET_INST_OPCODE(ip) @ extract opcode from rINST 1508 GOTO_OPCODE(ip) @ jump to next instruction 1509 1510 1511 /* ------------------------------ */ 1512 .balign 64 1513 .L_OP_IF_LT: /* 0x34 */ 1514 /* File: armv5te/OP_IF_LT.S */ 1515 /* File: armv5te/bincmp.S */ 1516 /* 1517 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1518 * fragment that specifies the *reverse* comparison to perform, e.g. 1519 * for "if-le" you would use "gt". 1520 * 1521 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1522 */ 1523 /* if-cmp vA, vB, +CCCC */ 1524 mov r0, rINST, lsr #8 @ r0<- A+ 1525 mov r1, rINST, lsr #12 @ r1<- B 1526 and r0, r0, #15 1527 GET_VREG(r3, r1) @ r3<- vB 1528 GET_VREG(r2, r0) @ r2<- vA 1529 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1530 cmp r2, r3 @ compare (vA, vB) 1531 movge r1, #2 @ r1<- BYTE branch dist for not-taken 1532 adds r2, r1, r1 @ convert to bytes, check sign 1533 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1534 #if defined(WITH_JIT) 1535 ldr r0, [rSELF, #offThread_pJitProfTable] 1536 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1537 cmp r0,#0 1538 bne common_updateProfile 1539 #else 1540 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1541 #endif 1542 GET_INST_OPCODE(ip) @ extract opcode from rINST 1543 GOTO_OPCODE(ip) @ jump to next instruction 1544 1545 1546 /* ------------------------------ */ 1547 .balign 64 1548 .L_OP_IF_GE: /* 0x35 */ 1549 /* File: armv5te/OP_IF_GE.S */ 1550 /* File: armv5te/bincmp.S */ 1551 /* 1552 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1553 * fragment that specifies the *reverse* comparison to perform, e.g. 1554 * for "if-le" you would use "gt". 1555 * 1556 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1557 */ 1558 /* if-cmp vA, vB, +CCCC */ 1559 mov r0, rINST, lsr #8 @ r0<- A+ 1560 mov r1, rINST, lsr #12 @ r1<- B 1561 and r0, r0, #15 1562 GET_VREG(r3, r1) @ r3<- vB 1563 GET_VREG(r2, r0) @ r2<- vA 1564 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1565 cmp r2, r3 @ compare (vA, vB) 1566 movlt r1, #2 @ r1<- BYTE branch dist for not-taken 1567 adds r2, r1, r1 @ convert to bytes, check sign 1568 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1569 #if defined(WITH_JIT) 1570 ldr r0, [rSELF, #offThread_pJitProfTable] 1571 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1572 cmp r0,#0 1573 bne common_updateProfile 1574 #else 1575 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1576 #endif 1577 GET_INST_OPCODE(ip) @ extract opcode from rINST 1578 GOTO_OPCODE(ip) @ jump to next instruction 1579 1580 1581 /* ------------------------------ */ 1582 .balign 64 1583 .L_OP_IF_GT: /* 0x36 */ 1584 /* File: armv5te/OP_IF_GT.S */ 1585 /* File: armv5te/bincmp.S */ 1586 /* 1587 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1588 * fragment that specifies the *reverse* comparison to perform, e.g. 1589 * for "if-le" you would use "gt". 1590 * 1591 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1592 */ 1593 /* if-cmp vA, vB, +CCCC */ 1594 mov r0, rINST, lsr #8 @ r0<- A+ 1595 mov r1, rINST, lsr #12 @ r1<- B 1596 and r0, r0, #15 1597 GET_VREG(r3, r1) @ r3<- vB 1598 GET_VREG(r2, r0) @ r2<- vA 1599 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1600 cmp r2, r3 @ compare (vA, vB) 1601 movle r1, #2 @ r1<- BYTE branch dist for not-taken 1602 adds r2, r1, r1 @ convert to bytes, check sign 1603 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1604 #if defined(WITH_JIT) 1605 ldr r0, [rSELF, #offThread_pJitProfTable] 1606 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1607 cmp r0,#0 1608 bne common_updateProfile 1609 #else 1610 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1611 #endif 1612 GET_INST_OPCODE(ip) @ extract opcode from rINST 1613 GOTO_OPCODE(ip) @ jump to next instruction 1614 1615 1616 /* ------------------------------ */ 1617 .balign 64 1618 .L_OP_IF_LE: /* 0x37 */ 1619 /* File: armv5te/OP_IF_LE.S */ 1620 /* File: armv5te/bincmp.S */ 1621 /* 1622 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1623 * fragment that specifies the *reverse* comparison to perform, e.g. 1624 * for "if-le" you would use "gt". 1625 * 1626 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1627 */ 1628 /* if-cmp vA, vB, +CCCC */ 1629 mov r0, rINST, lsr #8 @ r0<- A+ 1630 mov r1, rINST, lsr #12 @ r1<- B 1631 and r0, r0, #15 1632 GET_VREG(r3, r1) @ r3<- vB 1633 GET_VREG(r2, r0) @ r2<- vA 1634 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1635 cmp r2, r3 @ compare (vA, vB) 1636 movgt r1, #2 @ r1<- BYTE branch dist for not-taken 1637 adds r2, r1, r1 @ convert to bytes, check sign 1638 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1639 #if defined(WITH_JIT) 1640 ldr r0, [rSELF, #offThread_pJitProfTable] 1641 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1642 cmp r0,#0 1643 bne common_updateProfile 1644 #else 1645 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1646 #endif 1647 GET_INST_OPCODE(ip) @ extract opcode from rINST 1648 GOTO_OPCODE(ip) @ jump to next instruction 1649 1650 1651 /* ------------------------------ */ 1652 .balign 64 1653 .L_OP_IF_EQZ: /* 0x38 */ 1654 /* File: armv5te/OP_IF_EQZ.S */ 1655 /* File: armv5te/zcmp.S */ 1656 /* 1657 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1658 * fragment that specifies the *reverse* comparison to perform, e.g. 1659 * for "if-le" you would use "gt". 1660 * 1661 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1662 */ 1663 /* if-cmp vAA, +BBBB */ 1664 mov r0, rINST, lsr #8 @ r0<- AA 1665 GET_VREG(r2, r0) @ r2<- vAA 1666 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1667 cmp r2, #0 @ compare (vA, 0) 1668 movne r1, #2 @ r1<- inst branch dist for not-taken 1669 adds r1, r1, r1 @ convert to bytes & set flags 1670 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1671 #if defined(WITH_JIT) 1672 ldr r0, [rSELF, #offThread_pJitProfTable] 1673 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1674 cmp r0,#0 1675 bne common_updateProfile @ test for JIT off at target 1676 #else 1677 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1678 #endif 1679 GET_INST_OPCODE(ip) @ extract opcode from rINST 1680 GOTO_OPCODE(ip) @ jump to next instruction 1681 1682 1683 /* ------------------------------ */ 1684 .balign 64 1685 .L_OP_IF_NEZ: /* 0x39 */ 1686 /* File: armv5te/OP_IF_NEZ.S */ 1687 /* File: armv5te/zcmp.S */ 1688 /* 1689 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1690 * fragment that specifies the *reverse* comparison to perform, e.g. 1691 * for "if-le" you would use "gt". 1692 * 1693 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1694 */ 1695 /* if-cmp vAA, +BBBB */ 1696 mov r0, rINST, lsr #8 @ r0<- AA 1697 GET_VREG(r2, r0) @ r2<- vAA 1698 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1699 cmp r2, #0 @ compare (vA, 0) 1700 moveq r1, #2 @ r1<- inst branch dist for not-taken 1701 adds r1, r1, r1 @ convert to bytes & set flags 1702 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1703 #if defined(WITH_JIT) 1704 ldr r0, [rSELF, #offThread_pJitProfTable] 1705 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1706 cmp r0,#0 1707 bne common_updateProfile @ test for JIT off at target 1708 #else 1709 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1710 #endif 1711 GET_INST_OPCODE(ip) @ extract opcode from rINST 1712 GOTO_OPCODE(ip) @ jump to next instruction 1713 1714 1715 /* ------------------------------ */ 1716 .balign 64 1717 .L_OP_IF_LTZ: /* 0x3a */ 1718 /* File: armv5te/OP_IF_LTZ.S */ 1719 /* File: armv5te/zcmp.S */ 1720 /* 1721 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1722 * fragment that specifies the *reverse* comparison to perform, e.g. 1723 * for "if-le" you would use "gt". 1724 * 1725 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1726 */ 1727 /* if-cmp vAA, +BBBB */ 1728 mov r0, rINST, lsr #8 @ r0<- AA 1729 GET_VREG(r2, r0) @ r2<- vAA 1730 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1731 cmp r2, #0 @ compare (vA, 0) 1732 movge r1, #2 @ r1<- inst branch dist for not-taken 1733 adds r1, r1, r1 @ convert to bytes & set flags 1734 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1735 #if defined(WITH_JIT) 1736 ldr r0, [rSELF, #offThread_pJitProfTable] 1737 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1738 cmp r0,#0 1739 bne common_updateProfile @ test for JIT off at target 1740 #else 1741 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1742 #endif 1743 GET_INST_OPCODE(ip) @ extract opcode from rINST 1744 GOTO_OPCODE(ip) @ jump to next instruction 1745 1746 1747 /* ------------------------------ */ 1748 .balign 64 1749 .L_OP_IF_GEZ: /* 0x3b */ 1750 /* File: armv5te/OP_IF_GEZ.S */ 1751 /* File: armv5te/zcmp.S */ 1752 /* 1753 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1754 * fragment that specifies the *reverse* comparison to perform, e.g. 1755 * for "if-le" you would use "gt". 1756 * 1757 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1758 */ 1759 /* if-cmp vAA, +BBBB */ 1760 mov r0, rINST, lsr #8 @ r0<- AA 1761 GET_VREG(r2, r0) @ r2<- vAA 1762 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1763 cmp r2, #0 @ compare (vA, 0) 1764 movlt r1, #2 @ r1<- inst branch dist for not-taken 1765 adds r1, r1, r1 @ convert to bytes & set flags 1766 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1767 #if defined(WITH_JIT) 1768 ldr r0, [rSELF, #offThread_pJitProfTable] 1769 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1770 cmp r0,#0 1771 bne common_updateProfile @ test for JIT off at target 1772 #else 1773 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1774 #endif 1775 GET_INST_OPCODE(ip) @ extract opcode from rINST 1776 GOTO_OPCODE(ip) @ jump to next instruction 1777 1778 1779 /* ------------------------------ */ 1780 .balign 64 1781 .L_OP_IF_GTZ: /* 0x3c */ 1782 /* File: armv5te/OP_IF_GTZ.S */ 1783 /* File: armv5te/zcmp.S */ 1784 /* 1785 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1786 * fragment that specifies the *reverse* comparison to perform, e.g. 1787 * for "if-le" you would use "gt". 1788 * 1789 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1790 */ 1791 /* if-cmp vAA, +BBBB */ 1792 mov r0, rINST, lsr #8 @ r0<- AA 1793 GET_VREG(r2, r0) @ r2<- vAA 1794 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1795 cmp r2, #0 @ compare (vA, 0) 1796 movle r1, #2 @ r1<- inst branch dist for not-taken 1797 adds r1, r1, r1 @ convert to bytes & set flags 1798 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1799 #if defined(WITH_JIT) 1800 ldr r0, [rSELF, #offThread_pJitProfTable] 1801 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1802 cmp r0,#0 1803 bne common_updateProfile @ test for JIT off at target 1804 #else 1805 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1806 #endif 1807 GET_INST_OPCODE(ip) @ extract opcode from rINST 1808 GOTO_OPCODE(ip) @ jump to next instruction 1809 1810 1811 /* ------------------------------ */ 1812 .balign 64 1813 .L_OP_IF_LEZ: /* 0x3d */ 1814 /* File: armv5te/OP_IF_LEZ.S */ 1815 /* File: armv5te/zcmp.S */ 1816 /* 1817 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1818 * fragment that specifies the *reverse* comparison to perform, e.g. 1819 * for "if-le" you would use "gt". 1820 * 1821 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1822 */ 1823 /* if-cmp vAA, +BBBB */ 1824 mov r0, rINST, lsr #8 @ r0<- AA 1825 GET_VREG(r2, r0) @ r2<- vAA 1826 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1827 cmp r2, #0 @ compare (vA, 0) 1828 movgt r1, #2 @ r1<- inst branch dist for not-taken 1829 adds r1, r1, r1 @ convert to bytes & set flags 1830 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1831 #if defined(WITH_JIT) 1832 ldr r0, [rSELF, #offThread_pJitProfTable] 1833 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1834 cmp r0,#0 1835 bne common_updateProfile @ test for JIT off at target 1836 #else 1837 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1838 #endif 1839 GET_INST_OPCODE(ip) @ extract opcode from rINST 1840 GOTO_OPCODE(ip) @ jump to next instruction 1841 1842 1843 /* ------------------------------ */ 1844 .balign 64 1845 .L_OP_UNUSED_3E: /* 0x3e */ 1846 /* File: armv5te/OP_UNUSED_3E.S */ 1847 /* File: armv5te/unused.S */ 1848 bl common_abort 1849 1850 1851 /* ------------------------------ */ 1852 .balign 64 1853 .L_OP_UNUSED_3F: /* 0x3f */ 1854 /* File: armv5te/OP_UNUSED_3F.S */ 1855 /* File: armv5te/unused.S */ 1856 bl common_abort 1857 1858 1859 /* ------------------------------ */ 1860 .balign 64 1861 .L_OP_UNUSED_40: /* 0x40 */ 1862 /* File: armv5te/OP_UNUSED_40.S */ 1863 /* File: armv5te/unused.S */ 1864 bl common_abort 1865 1866 1867 /* ------------------------------ */ 1868 .balign 64 1869 .L_OP_UNUSED_41: /* 0x41 */ 1870 /* File: armv5te/OP_UNUSED_41.S */ 1871 /* File: armv5te/unused.S */ 1872 bl common_abort 1873 1874 1875 /* ------------------------------ */ 1876 .balign 64 1877 .L_OP_UNUSED_42: /* 0x42 */ 1878 /* File: armv5te/OP_UNUSED_42.S */ 1879 /* File: armv5te/unused.S */ 1880 bl common_abort 1881 1882 1883 /* ------------------------------ */ 1884 .balign 64 1885 .L_OP_UNUSED_43: /* 0x43 */ 1886 /* File: armv5te/OP_UNUSED_43.S */ 1887 /* File: armv5te/unused.S */ 1888 bl common_abort 1889 1890 1891 /* ------------------------------ */ 1892 .balign 64 1893 .L_OP_AGET: /* 0x44 */ 1894 /* File: armv5te/OP_AGET.S */ 1895 /* 1896 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1897 * 1898 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1899 * instructions. We use a pair of FETCH_Bs instead. 1900 * 1901 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1902 */ 1903 /* op vAA, vBB, vCC */ 1904 FETCH_B(r2, 1, 0) @ r2<- BB 1905 mov r9, rINST, lsr #8 @ r9<- AA 1906 FETCH_B(r3, 1, 1) @ r3<- CC 1907 GET_VREG(r0, r2) @ r0<- vBB (array object) 1908 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1909 cmp r0, #0 @ null array object? 1910 beq common_errNullObject @ yes, bail 1911 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1912 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1913 cmp r1, r3 @ compare unsigned index, length 1914 bcs common_errArrayIndex @ index >= length, bail 1915 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1916 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1917 GET_INST_OPCODE(ip) @ extract opcode from rINST 1918 SET_VREG(r2, r9) @ vAA<- r2 1919 GOTO_OPCODE(ip) @ jump to next instruction 1920 1921 /* ------------------------------ */ 1922 .balign 64 1923 .L_OP_AGET_WIDE: /* 0x45 */ 1924 /* File: armv5te/OP_AGET_WIDE.S */ 1925 /* 1926 * Array get, 64 bits. vAA <- vBB[vCC]. 1927 * 1928 * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD. 1929 */ 1930 /* aget-wide vAA, vBB, vCC */ 1931 FETCH(r0, 1) @ r0<- CCBB 1932 mov r9, rINST, lsr #8 @ r9<- AA 1933 and r2, r0, #255 @ r2<- BB 1934 mov r3, r0, lsr #8 @ r3<- CC 1935 GET_VREG(r0, r2) @ r0<- vBB (array object) 1936 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1937 cmp r0, #0 @ null array object? 1938 beq common_errNullObject @ yes, bail 1939 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1940 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 1941 cmp r1, r3 @ compare unsigned index, length 1942 bcc .LOP_AGET_WIDE_finish @ okay, continue below 1943 b common_errArrayIndex @ index >= length, bail 1944 @ May want to swap the order of these two branches depending on how the 1945 @ branch prediction (if any) handles conditional forward branches vs. 1946 @ unconditional forward branches. 1947 1948 /* ------------------------------ */ 1949 .balign 64 1950 .L_OP_AGET_OBJECT: /* 0x46 */ 1951 /* File: armv5te/OP_AGET_OBJECT.S */ 1952 /* File: armv5te/OP_AGET.S */ 1953 /* 1954 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1955 * 1956 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1957 * instructions. We use a pair of FETCH_Bs instead. 1958 * 1959 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1960 */ 1961 /* op vAA, vBB, vCC */ 1962 FETCH_B(r2, 1, 0) @ r2<- BB 1963 mov r9, rINST, lsr #8 @ r9<- AA 1964 FETCH_B(r3, 1, 1) @ r3<- CC 1965 GET_VREG(r0, r2) @ r0<- vBB (array object) 1966 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1967 cmp r0, #0 @ null array object? 1968 beq common_errNullObject @ yes, bail 1969 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1970 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1971 cmp r1, r3 @ compare unsigned index, length 1972 bcs common_errArrayIndex @ index >= length, bail 1973 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1974 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1975 GET_INST_OPCODE(ip) @ extract opcode from rINST 1976 SET_VREG(r2, r9) @ vAA<- r2 1977 GOTO_OPCODE(ip) @ jump to next instruction 1978 1979 1980 /* ------------------------------ */ 1981 .balign 64 1982 .L_OP_AGET_BOOLEAN: /* 0x47 */ 1983 /* File: armv5te/OP_AGET_BOOLEAN.S */ 1984 /* File: armv5te/OP_AGET.S */ 1985 /* 1986 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1987 * 1988 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1989 * instructions. We use a pair of FETCH_Bs instead. 1990 * 1991 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1992 */ 1993 /* op vAA, vBB, vCC */ 1994 FETCH_B(r2, 1, 0) @ r2<- BB 1995 mov r9, rINST, lsr #8 @ r9<- AA 1996 FETCH_B(r3, 1, 1) @ r3<- CC 1997 GET_VREG(r0, r2) @ r0<- vBB (array object) 1998 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1999 cmp r0, #0 @ null array object? 2000 beq common_errNullObject @ yes, bail 2001 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2002 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2003 cmp r1, r3 @ compare unsigned index, length 2004 bcs common_errArrayIndex @ index >= length, bail 2005 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2006 ldrb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2007 GET_INST_OPCODE(ip) @ extract opcode from rINST 2008 SET_VREG(r2, r9) @ vAA<- r2 2009 GOTO_OPCODE(ip) @ jump to next instruction 2010 2011 2012 /* ------------------------------ */ 2013 .balign 64 2014 .L_OP_AGET_BYTE: /* 0x48 */ 2015 /* File: armv5te/OP_AGET_BYTE.S */ 2016 /* File: armv5te/OP_AGET.S */ 2017 /* 2018 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2019 * 2020 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2021 * instructions. We use a pair of FETCH_Bs instead. 2022 * 2023 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2024 */ 2025 /* op vAA, vBB, vCC */ 2026 FETCH_B(r2, 1, 0) @ r2<- BB 2027 mov r9, rINST, lsr #8 @ r9<- AA 2028 FETCH_B(r3, 1, 1) @ r3<- CC 2029 GET_VREG(r0, r2) @ r0<- vBB (array object) 2030 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2031 cmp r0, #0 @ null array object? 2032 beq common_errNullObject @ yes, bail 2033 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2034 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2035 cmp r1, r3 @ compare unsigned index, length 2036 bcs common_errArrayIndex @ index >= length, bail 2037 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2038 ldrsb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2039 GET_INST_OPCODE(ip) @ extract opcode from rINST 2040 SET_VREG(r2, r9) @ vAA<- r2 2041 GOTO_OPCODE(ip) @ jump to next instruction 2042 2043 2044 /* ------------------------------ */ 2045 .balign 64 2046 .L_OP_AGET_CHAR: /* 0x49 */ 2047 /* File: armv5te/OP_AGET_CHAR.S */ 2048 /* File: armv5te/OP_AGET.S */ 2049 /* 2050 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2051 * 2052 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2053 * instructions. We use a pair of FETCH_Bs instead. 2054 * 2055 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2056 */ 2057 /* op vAA, vBB, vCC */ 2058 FETCH_B(r2, 1, 0) @ r2<- BB 2059 mov r9, rINST, lsr #8 @ r9<- AA 2060 FETCH_B(r3, 1, 1) @ r3<- CC 2061 GET_VREG(r0, r2) @ r0<- vBB (array object) 2062 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2063 cmp r0, #0 @ null array object? 2064 beq common_errNullObject @ yes, bail 2065 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2066 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2067 cmp r1, r3 @ compare unsigned index, length 2068 bcs common_errArrayIndex @ index >= length, bail 2069 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2070 ldrh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2071 GET_INST_OPCODE(ip) @ extract opcode from rINST 2072 SET_VREG(r2, r9) @ vAA<- r2 2073 GOTO_OPCODE(ip) @ jump to next instruction 2074 2075 2076 /* ------------------------------ */ 2077 .balign 64 2078 .L_OP_AGET_SHORT: /* 0x4a */ 2079 /* File: armv5te/OP_AGET_SHORT.S */ 2080 /* File: armv5te/OP_AGET.S */ 2081 /* 2082 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2083 * 2084 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2085 * instructions. We use a pair of FETCH_Bs instead. 2086 * 2087 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2088 */ 2089 /* op vAA, vBB, vCC */ 2090 FETCH_B(r2, 1, 0) @ r2<- BB 2091 mov r9, rINST, lsr #8 @ r9<- AA 2092 FETCH_B(r3, 1, 1) @ r3<- CC 2093 GET_VREG(r0, r2) @ r0<- vBB (array object) 2094 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2095 cmp r0, #0 @ null array object? 2096 beq common_errNullObject @ yes, bail 2097 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2098 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2099 cmp r1, r3 @ compare unsigned index, length 2100 bcs common_errArrayIndex @ index >= length, bail 2101 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2102 ldrsh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2103 GET_INST_OPCODE(ip) @ extract opcode from rINST 2104 SET_VREG(r2, r9) @ vAA<- r2 2105 GOTO_OPCODE(ip) @ jump to next instruction 2106 2107 2108 /* ------------------------------ */ 2109 .balign 64 2110 .L_OP_APUT: /* 0x4b */ 2111 /* File: armv5te/OP_APUT.S */ 2112 /* 2113 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2114 * 2115 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2116 * instructions. We use a pair of FETCH_Bs instead. 2117 * 2118 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2119 */ 2120 /* op vAA, vBB, vCC */ 2121 FETCH_B(r2, 1, 0) @ r2<- BB 2122 mov r9, rINST, lsr #8 @ r9<- AA 2123 FETCH_B(r3, 1, 1) @ r3<- CC 2124 GET_VREG(r0, r2) @ r0<- vBB (array object) 2125 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2126 cmp r0, #0 @ null array object? 2127 beq common_errNullObject @ yes, bail 2128 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2129 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2130 cmp r1, r3 @ compare unsigned index, length 2131 bcs common_errArrayIndex @ index >= length, bail 2132 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2133 GET_VREG(r2, r9) @ r2<- vAA 2134 GET_INST_OPCODE(ip) @ extract opcode from rINST 2135 str r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2136 GOTO_OPCODE(ip) @ jump to next instruction 2137 2138 /* ------------------------------ */ 2139 .balign 64 2140 .L_OP_APUT_WIDE: /* 0x4c */ 2141 /* File: armv5te/OP_APUT_WIDE.S */ 2142 /* 2143 * Array put, 64 bits. vBB[vCC] <- vAA. 2144 * 2145 * Arrays of long/double are 64-bit aligned, so it's okay to use STRD. 2146 */ 2147 /* aput-wide vAA, vBB, vCC */ 2148 FETCH(r0, 1) @ r0<- CCBB 2149 mov r9, rINST, lsr #8 @ r9<- AA 2150 and r2, r0, #255 @ r2<- BB 2151 mov r3, r0, lsr #8 @ r3<- CC 2152 GET_VREG(r0, r2) @ r0<- vBB (array object) 2153 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2154 cmp r0, #0 @ null array object? 2155 beq common_errNullObject @ yes, bail 2156 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2157 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2158 cmp r1, r3 @ compare unsigned index, length 2159 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2160 bcc .LOP_APUT_WIDE_finish @ okay, continue below 2161 b common_errArrayIndex @ index >= length, bail 2162 @ May want to swap the order of these two branches depending on how the 2163 @ branch prediction (if any) handles conditional forward branches vs. 2164 @ unconditional forward branches. 2165 2166 /* ------------------------------ */ 2167 .balign 64 2168 .L_OP_APUT_OBJECT: /* 0x4d */ 2169 /* File: armv5te/OP_APUT_OBJECT.S */ 2170 /* 2171 * Store an object into an array. vBB[vCC] <- vAA. 2172 */ 2173 /* op vAA, vBB, vCC */ 2174 FETCH(r0, 1) @ r0<- CCBB 2175 mov r9, rINST, lsr #8 @ r9<- AA 2176 and r2, r0, #255 @ r2<- BB 2177 mov r3, r0, lsr #8 @ r3<- CC 2178 GET_VREG(rINST, r2) @ rINST<- vBB (array object) 2179 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2180 cmp rINST, #0 @ null array object? 2181 GET_VREG(r9, r9) @ r9<- vAA 2182 beq common_errNullObject @ yes, bail 2183 ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length 2184 add r10, rINST, r1, lsl #2 @ r10<- arrayObj + index*width 2185 cmp r1, r3 @ compare unsigned index, length 2186 bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on 2187 b common_errArrayIndex @ index >= length, bail 2188 2189 2190 /* ------------------------------ */ 2191 .balign 64 2192 .L_OP_APUT_BOOLEAN: /* 0x4e */ 2193 /* File: armv5te/OP_APUT_BOOLEAN.S */ 2194 /* File: armv5te/OP_APUT.S */ 2195 /* 2196 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2197 * 2198 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2199 * instructions. We use a pair of FETCH_Bs instead. 2200 * 2201 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2202 */ 2203 /* op vAA, vBB, vCC */ 2204 FETCH_B(r2, 1, 0) @ r2<- BB 2205 mov r9, rINST, lsr #8 @ r9<- AA 2206 FETCH_B(r3, 1, 1) @ r3<- CC 2207 GET_VREG(r0, r2) @ r0<- vBB (array object) 2208 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2209 cmp r0, #0 @ null array object? 2210 beq common_errNullObject @ yes, bail 2211 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2212 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2213 cmp r1, r3 @ compare unsigned index, length 2214 bcs common_errArrayIndex @ index >= length, bail 2215 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2216 GET_VREG(r2, r9) @ r2<- vAA 2217 GET_INST_OPCODE(ip) @ extract opcode from rINST 2218 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2219 GOTO_OPCODE(ip) @ jump to next instruction 2220 2221 2222 /* ------------------------------ */ 2223 .balign 64 2224 .L_OP_APUT_BYTE: /* 0x4f */ 2225 /* File: armv5te/OP_APUT_BYTE.S */ 2226 /* File: armv5te/OP_APUT.S */ 2227 /* 2228 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2229 * 2230 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2231 * instructions. We use a pair of FETCH_Bs instead. 2232 * 2233 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2234 */ 2235 /* op vAA, vBB, vCC */ 2236 FETCH_B(r2, 1, 0) @ r2<- BB 2237 mov r9, rINST, lsr #8 @ r9<- AA 2238 FETCH_B(r3, 1, 1) @ r3<- CC 2239 GET_VREG(r0, r2) @ r0<- vBB (array object) 2240 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2241 cmp r0, #0 @ null array object? 2242 beq common_errNullObject @ yes, bail 2243 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2244 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2245 cmp r1, r3 @ compare unsigned index, length 2246 bcs common_errArrayIndex @ index >= length, bail 2247 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2248 GET_VREG(r2, r9) @ r2<- vAA 2249 GET_INST_OPCODE(ip) @ extract opcode from rINST 2250 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2251 GOTO_OPCODE(ip) @ jump to next instruction 2252 2253 2254 /* ------------------------------ */ 2255 .balign 64 2256 .L_OP_APUT_CHAR: /* 0x50 */ 2257 /* File: armv5te/OP_APUT_CHAR.S */ 2258 /* File: armv5te/OP_APUT.S */ 2259 /* 2260 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2261 * 2262 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2263 * instructions. We use a pair of FETCH_Bs instead. 2264 * 2265 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2266 */ 2267 /* op vAA, vBB, vCC */ 2268 FETCH_B(r2, 1, 0) @ r2<- BB 2269 mov r9, rINST, lsr #8 @ r9<- AA 2270 FETCH_B(r3, 1, 1) @ r3<- CC 2271 GET_VREG(r0, r2) @ r0<- vBB (array object) 2272 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2273 cmp r0, #0 @ null array object? 2274 beq common_errNullObject @ yes, bail 2275 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2276 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2277 cmp r1, r3 @ compare unsigned index, length 2278 bcs common_errArrayIndex @ index >= length, bail 2279 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2280 GET_VREG(r2, r9) @ r2<- vAA 2281 GET_INST_OPCODE(ip) @ extract opcode from rINST 2282 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2283 GOTO_OPCODE(ip) @ jump to next instruction 2284 2285 2286 /* ------------------------------ */ 2287 .balign 64 2288 .L_OP_APUT_SHORT: /* 0x51 */ 2289 /* File: armv5te/OP_APUT_SHORT.S */ 2290 /* File: armv5te/OP_APUT.S */ 2291 /* 2292 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2293 * 2294 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2295 * instructions. We use a pair of FETCH_Bs instead. 2296 * 2297 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2298 */ 2299 /* op vAA, vBB, vCC */ 2300 FETCH_B(r2, 1, 0) @ r2<- BB 2301 mov r9, rINST, lsr #8 @ r9<- AA 2302 FETCH_B(r3, 1, 1) @ r3<- CC 2303 GET_VREG(r0, r2) @ r0<- vBB (array object) 2304 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2305 cmp r0, #0 @ null array object? 2306 beq common_errNullObject @ yes, bail 2307 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2308 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2309 cmp r1, r3 @ compare unsigned index, length 2310 bcs common_errArrayIndex @ index >= length, bail 2311 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2312 GET_VREG(r2, r9) @ r2<- vAA 2313 GET_INST_OPCODE(ip) @ extract opcode from rINST 2314 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2315 GOTO_OPCODE(ip) @ jump to next instruction 2316 2317 2318 /* ------------------------------ */ 2319 .balign 64 2320 .L_OP_IGET: /* 0x52 */ 2321 /* File: armv5te/OP_IGET.S */ 2322 /* 2323 * General 32-bit instance field get. 2324 * 2325 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2326 */ 2327 /* op vA, vB, field@CCCC */ 2328 mov r0, rINST, lsr #12 @ r0<- B 2329 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2330 FETCH(r1, 1) @ r1<- field ref CCCC 2331 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2332 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2333 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2334 cmp r0, #0 @ is resolved entry null? 2335 bne .LOP_IGET_finish @ no, already resolved 2336 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2337 EXPORT_PC() @ resolve() could throw 2338 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2339 bl dvmResolveInstField @ r0<- resolved InstField ptr 2340 cmp r0, #0 2341 bne .LOP_IGET_finish 2342 b common_exceptionThrown 2343 2344 /* ------------------------------ */ 2345 .balign 64 2346 .L_OP_IGET_WIDE: /* 0x53 */ 2347 /* File: armv5te/OP_IGET_WIDE.S */ 2348 /* 2349 * Wide 32-bit instance field get. 2350 */ 2351 /* iget-wide vA, vB, field@CCCC */ 2352 mov r0, rINST, lsr #12 @ r0<- B 2353 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2354 FETCH(r1, 1) @ r1<- field ref CCCC 2355 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2356 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2357 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2358 cmp r0, #0 @ is resolved entry null? 2359 bne .LOP_IGET_WIDE_finish @ no, already resolved 2360 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2361 EXPORT_PC() @ resolve() could throw 2362 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2363 bl dvmResolveInstField @ r0<- resolved InstField ptr 2364 cmp r0, #0 2365 bne .LOP_IGET_WIDE_finish 2366 b common_exceptionThrown 2367 2368 /* ------------------------------ */ 2369 .balign 64 2370 .L_OP_IGET_OBJECT: /* 0x54 */ 2371 /* File: armv5te/OP_IGET_OBJECT.S */ 2372 /* File: armv5te/OP_IGET.S */ 2373 /* 2374 * General 32-bit instance field get. 2375 * 2376 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2377 */ 2378 /* op vA, vB, field@CCCC */ 2379 mov r0, rINST, lsr #12 @ r0<- B 2380 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2381 FETCH(r1, 1) @ r1<- field ref CCCC 2382 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2383 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2384 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2385 cmp r0, #0 @ is resolved entry null? 2386 bne .LOP_IGET_OBJECT_finish @ no, already resolved 2387 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2388 EXPORT_PC() @ resolve() could throw 2389 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2390 bl dvmResolveInstField @ r0<- resolved InstField ptr 2391 cmp r0, #0 2392 bne .LOP_IGET_OBJECT_finish 2393 b common_exceptionThrown 2394 2395 2396 /* ------------------------------ */ 2397 .balign 64 2398 .L_OP_IGET_BOOLEAN: /* 0x55 */ 2399 /* File: armv5te/OP_IGET_BOOLEAN.S */ 2400 @include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" } 2401 /* File: armv5te/OP_IGET.S */ 2402 /* 2403 * General 32-bit instance field get. 2404 * 2405 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2406 */ 2407 /* op vA, vB, field@CCCC */ 2408 mov r0, rINST, lsr #12 @ r0<- B 2409 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2410 FETCH(r1, 1) @ r1<- field ref CCCC 2411 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2412 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2413 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2414 cmp r0, #0 @ is resolved entry null? 2415 bne .LOP_IGET_BOOLEAN_finish @ no, already resolved 2416 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2417 EXPORT_PC() @ resolve() could throw 2418 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2419 bl dvmResolveInstField @ r0<- resolved InstField ptr 2420 cmp r0, #0 2421 bne .LOP_IGET_BOOLEAN_finish 2422 b common_exceptionThrown 2423 2424 2425 /* ------------------------------ */ 2426 .balign 64 2427 .L_OP_IGET_BYTE: /* 0x56 */ 2428 /* File: armv5te/OP_IGET_BYTE.S */ 2429 @include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" } 2430 /* File: armv5te/OP_IGET.S */ 2431 /* 2432 * General 32-bit instance field get. 2433 * 2434 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2435 */ 2436 /* op vA, vB, field@CCCC */ 2437 mov r0, rINST, lsr #12 @ r0<- B 2438 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2439 FETCH(r1, 1) @ r1<- field ref CCCC 2440 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2441 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2442 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2443 cmp r0, #0 @ is resolved entry null? 2444 bne .LOP_IGET_BYTE_finish @ no, already resolved 2445 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2446 EXPORT_PC() @ resolve() could throw 2447 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2448 bl dvmResolveInstField @ r0<- resolved InstField ptr 2449 cmp r0, #0 2450 bne .LOP_IGET_BYTE_finish 2451 b common_exceptionThrown 2452 2453 2454 /* ------------------------------ */ 2455 .balign 64 2456 .L_OP_IGET_CHAR: /* 0x57 */ 2457 /* File: armv5te/OP_IGET_CHAR.S */ 2458 @include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" } 2459 /* File: armv5te/OP_IGET.S */ 2460 /* 2461 * General 32-bit instance field get. 2462 * 2463 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2464 */ 2465 /* op vA, vB, field@CCCC */ 2466 mov r0, rINST, lsr #12 @ r0<- B 2467 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2468 FETCH(r1, 1) @ r1<- field ref CCCC 2469 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2470 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2471 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2472 cmp r0, #0 @ is resolved entry null? 2473 bne .LOP_IGET_CHAR_finish @ no, already resolved 2474 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2475 EXPORT_PC() @ resolve() could throw 2476 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2477 bl dvmResolveInstField @ r0<- resolved InstField ptr 2478 cmp r0, #0 2479 bne .LOP_IGET_CHAR_finish 2480 b common_exceptionThrown 2481 2482 2483 /* ------------------------------ */ 2484 .balign 64 2485 .L_OP_IGET_SHORT: /* 0x58 */ 2486 /* File: armv5te/OP_IGET_SHORT.S */ 2487 @include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" } 2488 /* File: armv5te/OP_IGET.S */ 2489 /* 2490 * General 32-bit instance field get. 2491 * 2492 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2493 */ 2494 /* op vA, vB, field@CCCC */ 2495 mov r0, rINST, lsr #12 @ r0<- B 2496 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2497 FETCH(r1, 1) @ r1<- field ref CCCC 2498 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2499 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2500 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2501 cmp r0, #0 @ is resolved entry null? 2502 bne .LOP_IGET_SHORT_finish @ no, already resolved 2503 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2504 EXPORT_PC() @ resolve() could throw 2505 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2506 bl dvmResolveInstField @ r0<- resolved InstField ptr 2507 cmp r0, #0 2508 bne .LOP_IGET_SHORT_finish 2509 b common_exceptionThrown 2510 2511 2512 /* ------------------------------ */ 2513 .balign 64 2514 .L_OP_IPUT: /* 0x59 */ 2515 /* File: armv5te/OP_IPUT.S */ 2516 /* 2517 * General 32-bit instance field put. 2518 * 2519 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2520 */ 2521 /* op vA, vB, field@CCCC */ 2522 mov r0, rINST, lsr #12 @ r0<- B 2523 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2524 FETCH(r1, 1) @ r1<- field ref CCCC 2525 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2526 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2527 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2528 cmp r0, #0 @ is resolved entry null? 2529 bne .LOP_IPUT_finish @ no, already resolved 2530 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2531 EXPORT_PC() @ resolve() could throw 2532 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2533 bl dvmResolveInstField @ r0<- resolved InstField ptr 2534 cmp r0, #0 @ success? 2535 bne .LOP_IPUT_finish @ yes, finish up 2536 b common_exceptionThrown 2537 2538 /* ------------------------------ */ 2539 .balign 64 2540 .L_OP_IPUT_WIDE: /* 0x5a */ 2541 /* File: armv5te/OP_IPUT_WIDE.S */ 2542 /* iput-wide vA, vB, field@CCCC */ 2543 mov r0, rINST, lsr #12 @ r0<- B 2544 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2545 FETCH(r1, 1) @ r1<- field ref CCCC 2546 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2547 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2548 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2549 cmp r0, #0 @ is resolved entry null? 2550 bne .LOP_IPUT_WIDE_finish @ no, already resolved 2551 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2552 EXPORT_PC() @ resolve() could throw 2553 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2554 bl dvmResolveInstField @ r0<- resolved InstField ptr 2555 cmp r0, #0 @ success? 2556 bne .LOP_IPUT_WIDE_finish @ yes, finish up 2557 b common_exceptionThrown 2558 2559 /* ------------------------------ */ 2560 .balign 64 2561 .L_OP_IPUT_OBJECT: /* 0x5b */ 2562 /* File: armv5te/OP_IPUT_OBJECT.S */ 2563 /* 2564 * 32-bit instance field put. 2565 * 2566 * for: iput-object, iput-object-volatile 2567 */ 2568 /* op vA, vB, field@CCCC */ 2569 mov r0, rINST, lsr #12 @ r0<- B 2570 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2571 FETCH(r1, 1) @ r1<- field ref CCCC 2572 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2573 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2574 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2575 cmp r0, #0 @ is resolved entry null? 2576 bne .LOP_IPUT_OBJECT_finish @ no, already resolved 2577 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2578 EXPORT_PC() @ resolve() could throw 2579 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2580 bl dvmResolveInstField @ r0<- resolved InstField ptr 2581 cmp r0, #0 @ success? 2582 bne .LOP_IPUT_OBJECT_finish @ yes, finish up 2583 b common_exceptionThrown 2584 2585 /* ------------------------------ */ 2586 .balign 64 2587 .L_OP_IPUT_BOOLEAN: /* 0x5c */ 2588 /* File: armv5te/OP_IPUT_BOOLEAN.S */ 2589 @include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" } 2590 /* File: armv5te/OP_IPUT.S */ 2591 /* 2592 * General 32-bit instance field put. 2593 * 2594 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2595 */ 2596 /* op vA, vB, field@CCCC */ 2597 mov r0, rINST, lsr #12 @ r0<- B 2598 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2599 FETCH(r1, 1) @ r1<- field ref CCCC 2600 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2601 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2602 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2603 cmp r0, #0 @ is resolved entry null? 2604 bne .LOP_IPUT_BOOLEAN_finish @ no, already resolved 2605 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2606 EXPORT_PC() @ resolve() could throw 2607 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2608 bl dvmResolveInstField @ r0<- resolved InstField ptr 2609 cmp r0, #0 @ success? 2610 bne .LOP_IPUT_BOOLEAN_finish @ yes, finish up 2611 b common_exceptionThrown 2612 2613 2614 /* ------------------------------ */ 2615 .balign 64 2616 .L_OP_IPUT_BYTE: /* 0x5d */ 2617 /* File: armv5te/OP_IPUT_BYTE.S */ 2618 @include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" } 2619 /* File: armv5te/OP_IPUT.S */ 2620 /* 2621 * General 32-bit instance field put. 2622 * 2623 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2624 */ 2625 /* op vA, vB, field@CCCC */ 2626 mov r0, rINST, lsr #12 @ r0<- B 2627 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2628 FETCH(r1, 1) @ r1<- field ref CCCC 2629 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2630 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2631 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2632 cmp r0, #0 @ is resolved entry null? 2633 bne .LOP_IPUT_BYTE_finish @ no, already resolved 2634 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2635 EXPORT_PC() @ resolve() could throw 2636 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2637 bl dvmResolveInstField @ r0<- resolved InstField ptr 2638 cmp r0, #0 @ success? 2639 bne .LOP_IPUT_BYTE_finish @ yes, finish up 2640 b common_exceptionThrown 2641 2642 2643 /* ------------------------------ */ 2644 .balign 64 2645 .L_OP_IPUT_CHAR: /* 0x5e */ 2646 /* File: armv5te/OP_IPUT_CHAR.S */ 2647 @include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" } 2648 /* File: armv5te/OP_IPUT.S */ 2649 /* 2650 * General 32-bit instance field put. 2651 * 2652 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2653 */ 2654 /* op vA, vB, field@CCCC */ 2655 mov r0, rINST, lsr #12 @ r0<- B 2656 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2657 FETCH(r1, 1) @ r1<- field ref CCCC 2658 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2659 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2660 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2661 cmp r0, #0 @ is resolved entry null? 2662 bne .LOP_IPUT_CHAR_finish @ no, already resolved 2663 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2664 EXPORT_PC() @ resolve() could throw 2665 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2666 bl dvmResolveInstField @ r0<- resolved InstField ptr 2667 cmp r0, #0 @ success? 2668 bne .LOP_IPUT_CHAR_finish @ yes, finish up 2669 b common_exceptionThrown 2670 2671 2672 /* ------------------------------ */ 2673 .balign 64 2674 .L_OP_IPUT_SHORT: /* 0x5f */ 2675 /* File: armv5te/OP_IPUT_SHORT.S */ 2676 @include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" } 2677 /* File: armv5te/OP_IPUT.S */ 2678 /* 2679 * General 32-bit instance field put. 2680 * 2681 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2682 */ 2683 /* op vA, vB, field@CCCC */ 2684 mov r0, rINST, lsr #12 @ r0<- B 2685 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2686 FETCH(r1, 1) @ r1<- field ref CCCC 2687 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2688 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2689 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2690 cmp r0, #0 @ is resolved entry null? 2691 bne .LOP_IPUT_SHORT_finish @ no, already resolved 2692 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2693 EXPORT_PC() @ resolve() could throw 2694 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2695 bl dvmResolveInstField @ r0<- resolved InstField ptr 2696 cmp r0, #0 @ success? 2697 bne .LOP_IPUT_SHORT_finish @ yes, finish up 2698 b common_exceptionThrown 2699 2700 2701 /* ------------------------------ */ 2702 .balign 64 2703 .L_OP_SGET: /* 0x60 */ 2704 /* File: armv5te/OP_SGET.S */ 2705 /* 2706 * General 32-bit SGET handler. 2707 * 2708 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2709 */ 2710 /* op vAA, field@BBBB */ 2711 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2712 FETCH(r1, 1) @ r1<- field ref BBBB 2713 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2714 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2715 cmp r0, #0 @ is resolved entry null? 2716 beq .LOP_SGET_resolve @ yes, do resolve 2717 .LOP_SGET_finish: @ field ptr in r0 2718 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2719 @ no-op @ acquiring load 2720 mov r2, rINST, lsr #8 @ r2<- AA 2721 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2722 SET_VREG(r1, r2) @ fp[AA]<- r1 2723 GET_INST_OPCODE(ip) @ extract opcode from rINST 2724 GOTO_OPCODE(ip) @ jump to next instruction 2725 2726 /* ------------------------------ */ 2727 .balign 64 2728 .L_OP_SGET_WIDE: /* 0x61 */ 2729 /* File: armv5te/OP_SGET_WIDE.S */ 2730 /* 2731 * 64-bit SGET handler. 2732 */ 2733 /* sget-wide vAA, field@BBBB */ 2734 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2735 FETCH(r1, 1) @ r1<- field ref BBBB 2736 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2737 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2738 cmp r0, #0 @ is resolved entry null? 2739 beq .LOP_SGET_WIDE_resolve @ yes, do resolve 2740 .LOP_SGET_WIDE_finish: 2741 mov r9, rINST, lsr #8 @ r9<- AA 2742 .if 0 2743 add r0, r0, #offStaticField_value @ r0<- pointer to data 2744 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 2745 .else 2746 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 2747 .endif 2748 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2749 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2750 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 2751 GET_INST_OPCODE(ip) @ extract opcode from rINST 2752 GOTO_OPCODE(ip) @ jump to next instruction 2753 2754 /* ------------------------------ */ 2755 .balign 64 2756 .L_OP_SGET_OBJECT: /* 0x62 */ 2757 /* File: armv5te/OP_SGET_OBJECT.S */ 2758 /* File: armv5te/OP_SGET.S */ 2759 /* 2760 * General 32-bit SGET handler. 2761 * 2762 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2763 */ 2764 /* op vAA, field@BBBB */ 2765 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2766 FETCH(r1, 1) @ r1<- field ref BBBB 2767 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2768 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2769 cmp r0, #0 @ is resolved entry null? 2770 beq .LOP_SGET_OBJECT_resolve @ yes, do resolve 2771 .LOP_SGET_OBJECT_finish: @ field ptr in r0 2772 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2773 @ no-op @ acquiring load 2774 mov r2, rINST, lsr #8 @ r2<- AA 2775 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2776 SET_VREG(r1, r2) @ fp[AA]<- r1 2777 GET_INST_OPCODE(ip) @ extract opcode from rINST 2778 GOTO_OPCODE(ip) @ jump to next instruction 2779 2780 2781 /* ------------------------------ */ 2782 .balign 64 2783 .L_OP_SGET_BOOLEAN: /* 0x63 */ 2784 /* File: armv5te/OP_SGET_BOOLEAN.S */ 2785 /* File: armv5te/OP_SGET.S */ 2786 /* 2787 * General 32-bit SGET handler. 2788 * 2789 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2790 */ 2791 /* op vAA, field@BBBB */ 2792 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2793 FETCH(r1, 1) @ r1<- field ref BBBB 2794 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2795 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2796 cmp r0, #0 @ is resolved entry null? 2797 beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve 2798 .LOP_SGET_BOOLEAN_finish: @ field ptr in r0 2799 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2800 @ no-op @ acquiring load 2801 mov r2, rINST, lsr #8 @ r2<- AA 2802 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2803 SET_VREG(r1, r2) @ fp[AA]<- r1 2804 GET_INST_OPCODE(ip) @ extract opcode from rINST 2805 GOTO_OPCODE(ip) @ jump to next instruction 2806 2807 2808 /* ------------------------------ */ 2809 .balign 64 2810 .L_OP_SGET_BYTE: /* 0x64 */ 2811 /* File: armv5te/OP_SGET_BYTE.S */ 2812 /* File: armv5te/OP_SGET.S */ 2813 /* 2814 * General 32-bit SGET handler. 2815 * 2816 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2817 */ 2818 /* op vAA, field@BBBB */ 2819 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2820 FETCH(r1, 1) @ r1<- field ref BBBB 2821 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2822 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2823 cmp r0, #0 @ is resolved entry null? 2824 beq .LOP_SGET_BYTE_resolve @ yes, do resolve 2825 .LOP_SGET_BYTE_finish: @ field ptr in r0 2826 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2827 @ no-op @ acquiring load 2828 mov r2, rINST, lsr #8 @ r2<- AA 2829 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2830 SET_VREG(r1, r2) @ fp[AA]<- r1 2831 GET_INST_OPCODE(ip) @ extract opcode from rINST 2832 GOTO_OPCODE(ip) @ jump to next instruction 2833 2834 2835 /* ------------------------------ */ 2836 .balign 64 2837 .L_OP_SGET_CHAR: /* 0x65 */ 2838 /* File: armv5te/OP_SGET_CHAR.S */ 2839 /* File: armv5te/OP_SGET.S */ 2840 /* 2841 * General 32-bit SGET handler. 2842 * 2843 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2844 */ 2845 /* op vAA, field@BBBB */ 2846 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2847 FETCH(r1, 1) @ r1<- field ref BBBB 2848 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2849 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2850 cmp r0, #0 @ is resolved entry null? 2851 beq .LOP_SGET_CHAR_resolve @ yes, do resolve 2852 .LOP_SGET_CHAR_finish: @ field ptr in r0 2853 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2854 @ no-op @ acquiring load 2855 mov r2, rINST, lsr #8 @ r2<- AA 2856 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2857 SET_VREG(r1, r2) @ fp[AA]<- r1 2858 GET_INST_OPCODE(ip) @ extract opcode from rINST 2859 GOTO_OPCODE(ip) @ jump to next instruction 2860 2861 2862 /* ------------------------------ */ 2863 .balign 64 2864 .L_OP_SGET_SHORT: /* 0x66 */ 2865 /* File: armv5te/OP_SGET_SHORT.S */ 2866 /* File: armv5te/OP_SGET.S */ 2867 /* 2868 * General 32-bit SGET handler. 2869 * 2870 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2871 */ 2872 /* op vAA, field@BBBB */ 2873 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2874 FETCH(r1, 1) @ r1<- field ref BBBB 2875 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2876 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2877 cmp r0, #0 @ is resolved entry null? 2878 beq .LOP_SGET_SHORT_resolve @ yes, do resolve 2879 .LOP_SGET_SHORT_finish: @ field ptr in r0 2880 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2881 @ no-op @ acquiring load 2882 mov r2, rINST, lsr #8 @ r2<- AA 2883 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2884 SET_VREG(r1, r2) @ fp[AA]<- r1 2885 GET_INST_OPCODE(ip) @ extract opcode from rINST 2886 GOTO_OPCODE(ip) @ jump to next instruction 2887 2888 2889 /* ------------------------------ */ 2890 .balign 64 2891 .L_OP_SPUT: /* 0x67 */ 2892 /* File: armv5te/OP_SPUT.S */ 2893 /* 2894 * General 32-bit SPUT handler. 2895 * 2896 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2897 */ 2898 /* op vAA, field@BBBB */ 2899 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2900 FETCH(r1, 1) @ r1<- field ref BBBB 2901 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2902 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2903 cmp r0, #0 @ is resolved entry null? 2904 beq .LOP_SPUT_resolve @ yes, do resolve 2905 .LOP_SPUT_finish: @ field ptr in r0 2906 mov r2, rINST, lsr #8 @ r2<- AA 2907 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2908 GET_VREG(r1, r2) @ r1<- fp[AA] 2909 GET_INST_OPCODE(ip) @ extract opcode from rINST 2910 @ no-op @ releasing store 2911 str r1, [r0, #offStaticField_value] @ field<- vAA 2912 @ no-op 2913 GOTO_OPCODE(ip) @ jump to next instruction 2914 2915 /* ------------------------------ */ 2916 .balign 64 2917 .L_OP_SPUT_WIDE: /* 0x68 */ 2918 /* File: armv5te/OP_SPUT_WIDE.S */ 2919 /* 2920 * 64-bit SPUT handler. 2921 */ 2922 /* sput-wide vAA, field@BBBB */ 2923 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- DvmDex 2924 FETCH(r1, 1) @ r1<- field ref BBBB 2925 ldr r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2926 mov r9, rINST, lsr #8 @ r9<- AA 2927 ldr r2, [r10, r1, lsl #2] @ r2<- resolved StaticField ptr 2928 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2929 cmp r2, #0 @ is resolved entry null? 2930 beq .LOP_SPUT_WIDE_resolve @ yes, do resolve 2931 .LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9 2932 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2933 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 2934 GET_INST_OPCODE(r10) @ extract opcode from rINST 2935 .if 0 2936 add r2, r2, #offStaticField_value @ r2<- pointer to data 2937 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 2938 .else 2939 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 2940 .endif 2941 GOTO_OPCODE(r10) @ jump to next instruction 2942 2943 /* ------------------------------ */ 2944 .balign 64 2945 .L_OP_SPUT_OBJECT: /* 0x69 */ 2946 /* File: armv5te/OP_SPUT_OBJECT.S */ 2947 /* 2948 * 32-bit SPUT handler for objects 2949 * 2950 * for: sput-object, sput-object-volatile 2951 */ 2952 /* op vAA, field@BBBB */ 2953 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2954 FETCH(r1, 1) @ r1<- field ref BBBB 2955 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2956 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2957 cmp r0, #0 @ is resolved entry null? 2958 beq .LOP_SPUT_OBJECT_resolve @ yes, do resolve 2959 .LOP_SPUT_OBJECT_finish: @ field ptr in r0 2960 mov r2, rINST, lsr #8 @ r2<- AA 2961 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2962 GET_VREG(r1, r2) @ r1<- fp[AA] 2963 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 2964 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 2965 GET_INST_OPCODE(ip) @ extract opcode from rINST 2966 @ no-op @ releasing store 2967 b .LOP_SPUT_OBJECT_end 2968 2969 /* ------------------------------ */ 2970 .balign 64 2971 .L_OP_SPUT_BOOLEAN: /* 0x6a */ 2972 /* File: armv5te/OP_SPUT_BOOLEAN.S */ 2973 /* File: armv5te/OP_SPUT.S */ 2974 /* 2975 * General 32-bit SPUT handler. 2976 * 2977 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2978 */ 2979 /* op vAA, field@BBBB */ 2980 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2981 FETCH(r1, 1) @ r1<- field ref BBBB 2982 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2983 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2984 cmp r0, #0 @ is resolved entry null? 2985 beq .LOP_SPUT_BOOLEAN_resolve @ yes, do resolve 2986 .LOP_SPUT_BOOLEAN_finish: @ field ptr in r0 2987 mov r2, rINST, lsr #8 @ r2<- AA 2988 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2989 GET_VREG(r1, r2) @ r1<- fp[AA] 2990 GET_INST_OPCODE(ip) @ extract opcode from rINST 2991 @ no-op @ releasing store 2992 str r1, [r0, #offStaticField_value] @ field<- vAA 2993 @ no-op 2994 GOTO_OPCODE(ip) @ jump to next instruction 2995 2996 2997 /* ------------------------------ */ 2998 .balign 64 2999 .L_OP_SPUT_BYTE: /* 0x6b */ 3000 /* File: armv5te/OP_SPUT_BYTE.S */ 3001 /* File: armv5te/OP_SPUT.S */ 3002 /* 3003 * General 32-bit SPUT handler. 3004 * 3005 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3006 */ 3007 /* op vAA, field@BBBB */ 3008 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3009 FETCH(r1, 1) @ r1<- field ref BBBB 3010 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 3011 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 3012 cmp r0, #0 @ is resolved entry null? 3013 beq .LOP_SPUT_BYTE_resolve @ yes, do resolve 3014 .LOP_SPUT_BYTE_finish: @ field ptr in r0 3015 mov r2, rINST, lsr #8 @ r2<- AA 3016 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3017 GET_VREG(r1, r2) @ r1<- fp[AA] 3018 GET_INST_OPCODE(ip) @ extract opcode from rINST 3019 @ no-op @ releasing store 3020 str r1, [r0, #offStaticField_value] @ field<- vAA 3021 @ no-op 3022 GOTO_OPCODE(ip) @ jump to next instruction 3023 3024 3025 /* ------------------------------ */ 3026 .balign 64 3027 .L_OP_SPUT_CHAR: /* 0x6c */ 3028 /* File: armv5te/OP_SPUT_CHAR.S */ 3029 /* File: armv5te/OP_SPUT.S */ 3030 /* 3031 * General 32-bit SPUT handler. 3032 * 3033 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3034 */ 3035 /* op vAA, field@BBBB */ 3036 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3037 FETCH(r1, 1) @ r1<- field ref BBBB 3038 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 3039 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 3040 cmp r0, #0 @ is resolved entry null? 3041 beq .LOP_SPUT_CHAR_resolve @ yes, do resolve 3042 .LOP_SPUT_CHAR_finish: @ field ptr in r0 3043 mov r2, rINST, lsr #8 @ r2<- AA 3044 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3045 GET_VREG(r1, r2) @ r1<- fp[AA] 3046 GET_INST_OPCODE(ip) @ extract opcode from rINST 3047 @ no-op @ releasing store 3048 str r1, [r0, #offStaticField_value] @ field<- vAA 3049 @ no-op 3050 GOTO_OPCODE(ip) @ jump to next instruction 3051 3052 3053 /* ------------------------------ */ 3054 .balign 64 3055 .L_OP_SPUT_SHORT: /* 0x6d */ 3056 /* File: armv5te/OP_SPUT_SHORT.S */ 3057 /* File: armv5te/OP_SPUT.S */ 3058 /* 3059 * General 32-bit SPUT handler. 3060 * 3061 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3062 */ 3063 /* op vAA, field@BBBB */ 3064 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3065 FETCH(r1, 1) @ r1<- field ref BBBB 3066 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 3067 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 3068 cmp r0, #0 @ is resolved entry null? 3069 beq .LOP_SPUT_SHORT_resolve @ yes, do resolve 3070 .LOP_SPUT_SHORT_finish: @ field ptr in r0 3071 mov r2, rINST, lsr #8 @ r2<- AA 3072 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3073 GET_VREG(r1, r2) @ r1<- fp[AA] 3074 GET_INST_OPCODE(ip) @ extract opcode from rINST 3075 @ no-op @ releasing store 3076 str r1, [r0, #offStaticField_value] @ field<- vAA 3077 @ no-op 3078 GOTO_OPCODE(ip) @ jump to next instruction 3079 3080 3081 /* ------------------------------ */ 3082 .balign 64 3083 .L_OP_INVOKE_VIRTUAL: /* 0x6e */ 3084 /* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3085 /* 3086 * Handle a virtual method call. 3087 * 3088 * for: invoke-virtual, invoke-virtual/range 3089 */ 3090 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3091 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3092 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3093 FETCH(r1, 1) @ r1<- BBBB 3094 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3095 FETCH(r10, 2) @ r10<- GFED or CCCC 3096 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3097 .if (!0) 3098 and r10, r10, #15 @ r10<- D (or stays CCCC) 3099 .endif 3100 cmp r0, #0 @ already resolved? 3101 EXPORT_PC() @ must export for invoke 3102 bne .LOP_INVOKE_VIRTUAL_continue @ yes, continue on 3103 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3104 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3105 mov r2, #METHOD_VIRTUAL @ resolver method type 3106 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3107 cmp r0, #0 @ got null? 3108 bne .LOP_INVOKE_VIRTUAL_continue @ no, continue 3109 b common_exceptionThrown @ yes, handle exception 3110 3111 /* ------------------------------ */ 3112 .balign 64 3113 .L_OP_INVOKE_SUPER: /* 0x6f */ 3114 /* File: armv5te/OP_INVOKE_SUPER.S */ 3115 /* 3116 * Handle a "super" method call. 3117 * 3118 * for: invoke-super, invoke-super/range 3119 */ 3120 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3121 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3122 FETCH(r10, 2) @ r10<- GFED or CCCC 3123 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3124 .if (!0) 3125 and r10, r10, #15 @ r10<- D (or stays CCCC) 3126 .endif 3127 FETCH(r1, 1) @ r1<- BBBB 3128 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3129 GET_VREG(r9, r10) @ r9<- "this" ptr 3130 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3131 cmp r9, #0 @ null "this"? 3132 ldr r10, [rSELF, #offThread_method] @ r10<- current method 3133 beq common_errNullObject @ null "this", throw exception 3134 cmp r0, #0 @ already resolved? 3135 ldr r10, [r10, #offMethod_clazz] @ r10<- method->clazz 3136 EXPORT_PC() @ must export for invoke 3137 bne .LOP_INVOKE_SUPER_continue @ resolved, continue on 3138 b .LOP_INVOKE_SUPER_resolve @ do resolve now 3139 3140 /* ------------------------------ */ 3141 .balign 64 3142 .L_OP_INVOKE_DIRECT: /* 0x70 */ 3143 /* File: armv5te/OP_INVOKE_DIRECT.S */ 3144 /* 3145 * Handle a direct method call. 3146 * 3147 * (We could defer the "is 'this' pointer null" test to the common 3148 * method invocation code, and use a flag to indicate that static 3149 * calls don't count. If we do this as part of copying the arguments 3150 * out we could avoiding loading the first arg twice.) 3151 * 3152 * for: invoke-direct, invoke-direct/range 3153 */ 3154 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3155 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3156 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3157 FETCH(r1, 1) @ r1<- BBBB 3158 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3159 FETCH(r10, 2) @ r10<- GFED or CCCC 3160 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3161 .if (!0) 3162 and r10, r10, #15 @ r10<- D (or stays CCCC) 3163 .endif 3164 cmp r0, #0 @ already resolved? 3165 EXPORT_PC() @ must export for invoke 3166 GET_VREG(r9, r10) @ r9<- "this" ptr 3167 beq .LOP_INVOKE_DIRECT_resolve @ not resolved, do it now 3168 .LOP_INVOKE_DIRECT_finish: 3169 cmp r9, #0 @ null "this" ref? 3170 bne common_invokeMethodNoRange @ r0=method, r9="this" 3171 b common_errNullObject @ yes, throw exception 3172 3173 /* ------------------------------ */ 3174 .balign 64 3175 .L_OP_INVOKE_STATIC: /* 0x71 */ 3176 /* File: armv5te/OP_INVOKE_STATIC.S */ 3177 /* 3178 * Handle a static method call. 3179 * 3180 * for: invoke-static, invoke-static/range 3181 */ 3182 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3183 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3184 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3185 FETCH(r1, 1) @ r1<- BBBB 3186 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3187 mov r9, #0 @ null "this" in delay slot 3188 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3189 #if defined(WITH_JIT) 3190 add r10, r3, r1, lsl #2 @ r10<- &resolved_methodToCall 3191 #endif 3192 cmp r0, #0 @ already resolved? 3193 EXPORT_PC() @ must export for invoke 3194 bne common_invokeMethodNoRange @ yes, continue on 3195 b .LOP_INVOKE_STATIC_resolve 3196 3197 /* ------------------------------ */ 3198 .balign 64 3199 .L_OP_INVOKE_INTERFACE: /* 0x72 */ 3200 /* File: armv5te/OP_INVOKE_INTERFACE.S */ 3201 /* 3202 * Handle an interface method call. 3203 * 3204 * for: invoke-interface, invoke-interface/range 3205 */ 3206 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3207 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3208 FETCH(r2, 2) @ r2<- FEDC or CCCC 3209 FETCH(r1, 1) @ r1<- BBBB 3210 .if (!0) 3211 and r2, r2, #15 @ r2<- C (or stays CCCC) 3212 .endif 3213 EXPORT_PC() @ must export for invoke 3214 GET_VREG(r9, r2) @ r9<- first arg ("this") 3215 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- methodClassDex 3216 cmp r9, #0 @ null obj? 3217 ldr r2, [rSELF, #offThread_method] @ r2<- method 3218 beq common_errNullObject @ yes, fail 3219 ldr r0, [r9, #offObject_clazz] @ r0<- thisPtr->clazz 3220 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3221 cmp r0, #0 @ failed? 3222 beq common_exceptionThrown @ yes, handle exception 3223 b common_invokeMethodNoRange @ (r0=method, r9="this") 3224 3225 /* ------------------------------ */ 3226 .balign 64 3227 .L_OP_UNUSED_73: /* 0x73 */ 3228 /* File: armv5te/OP_UNUSED_73.S */ 3229 /* File: armv5te/unused.S */ 3230 bl common_abort 3231 3232 3233 /* ------------------------------ */ 3234 .balign 64 3235 .L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 3236 /* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */ 3237 /* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3238 /* 3239 * Handle a virtual method call. 3240 * 3241 * for: invoke-virtual, invoke-virtual/range 3242 */ 3243 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3244 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3245 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3246 FETCH(r1, 1) @ r1<- BBBB 3247 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3248 FETCH(r10, 2) @ r10<- GFED or CCCC 3249 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3250 .if (!1) 3251 and r10, r10, #15 @ r10<- D (or stays CCCC) 3252 .endif 3253 cmp r0, #0 @ already resolved? 3254 EXPORT_PC() @ must export for invoke 3255 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ yes, continue on 3256 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3257 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3258 mov r2, #METHOD_VIRTUAL @ resolver method type 3259 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3260 cmp r0, #0 @ got null? 3261 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ no, continue 3262 b common_exceptionThrown @ yes, handle exception 3263 3264 3265 /* ------------------------------ */ 3266 .balign 64 3267 .L_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 3268 /* File: armv5te/OP_INVOKE_SUPER_RANGE.S */ 3269 /* File: armv5te/OP_INVOKE_SUPER.S */ 3270 /* 3271 * Handle a "super" method call. 3272 * 3273 * for: invoke-super, invoke-super/range 3274 */ 3275 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3276 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3277 FETCH(r10, 2) @ r10<- GFED or CCCC 3278 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3279 .if (!1) 3280 and r10, r10, #15 @ r10<- D (or stays CCCC) 3281 .endif 3282 FETCH(r1, 1) @ r1<- BBBB 3283 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3284 GET_VREG(r9, r10) @ r9<- "this" ptr 3285 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3286 cmp r9, #0 @ null "this"? 3287 ldr r10, [rSELF, #offThread_method] @ r10<- current method 3288 beq common_errNullObject @ null "this", throw exception 3289 cmp r0, #0 @ already resolved? 3290 ldr r10, [r10, #offMethod_clazz] @ r10<- method->clazz 3291 EXPORT_PC() @ must export for invoke 3292 bne .LOP_INVOKE_SUPER_RANGE_continue @ resolved, continue on 3293 b .LOP_INVOKE_SUPER_RANGE_resolve @ do resolve now 3294 3295 3296 /* ------------------------------ */ 3297 .balign 64 3298 .L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 3299 /* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */ 3300 /* File: armv5te/OP_INVOKE_DIRECT.S */ 3301 /* 3302 * Handle a direct method call. 3303 * 3304 * (We could defer the "is 'this' pointer null" test to the common 3305 * method invocation code, and use a flag to indicate that static 3306 * calls don't count. If we do this as part of copying the arguments 3307 * out we could avoiding loading the first arg twice.) 3308 * 3309 * for: invoke-direct, invoke-direct/range 3310 */ 3311 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3312 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3313 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3314 FETCH(r1, 1) @ r1<- BBBB 3315 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3316 FETCH(r10, 2) @ r10<- GFED or CCCC 3317 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3318 .if (!1) 3319 and r10, r10, #15 @ r10<- D (or stays CCCC) 3320 .endif 3321 cmp r0, #0 @ already resolved? 3322 EXPORT_PC() @ must export for invoke 3323 GET_VREG(r9, r10) @ r9<- "this" ptr 3324 beq .LOP_INVOKE_DIRECT_RANGE_resolve @ not resolved, do it now 3325 .LOP_INVOKE_DIRECT_RANGE_finish: 3326 cmp r9, #0 @ null "this" ref? 3327 bne common_invokeMethodRange @ r0=method, r9="this" 3328 b common_errNullObject @ yes, throw exception 3329 3330 3331 /* ------------------------------ */ 3332 .balign 64 3333 .L_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 3334 /* File: armv5te/OP_INVOKE_STATIC_RANGE.S */ 3335 /* File: armv5te/OP_INVOKE_STATIC.S */ 3336 /* 3337 * Handle a static method call. 3338 * 3339 * for: invoke-static, invoke-static/range 3340 */ 3341 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3342 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3343 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3344 FETCH(r1, 1) @ r1<- BBBB 3345 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3346 mov r9, #0 @ null "this" in delay slot 3347 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3348 #if defined(WITH_JIT) 3349 add r10, r3, r1, lsl #2 @ r10<- &resolved_methodToCall 3350 #endif 3351 cmp r0, #0 @ already resolved? 3352 EXPORT_PC() @ must export for invoke 3353 bne common_invokeMethodRange @ yes, continue on 3354 b .LOP_INVOKE_STATIC_RANGE_resolve 3355 3356 3357 /* ------------------------------ */ 3358 .balign 64 3359 .L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 3360 /* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */ 3361 /* File: armv5te/OP_INVOKE_INTERFACE.S */ 3362 /* 3363 * Handle an interface method call. 3364 * 3365 * for: invoke-interface, invoke-interface/range 3366 */ 3367 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3368 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3369 FETCH(r2, 2) @ r2<- FEDC or CCCC 3370 FETCH(r1, 1) @ r1<- BBBB 3371 .if (!1) 3372 and r2, r2, #15 @ r2<- C (or stays CCCC) 3373 .endif 3374 EXPORT_PC() @ must export for invoke 3375 GET_VREG(r9, r2) @ r9<- first arg ("this") 3376 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- methodClassDex 3377 cmp r9, #0 @ null obj? 3378 ldr r2, [rSELF, #offThread_method] @ r2<- method 3379 beq common_errNullObject @ yes, fail 3380 ldr r0, [r9, #offObject_clazz] @ r0<- thisPtr->clazz 3381 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3382 cmp r0, #0 @ failed? 3383 beq common_exceptionThrown @ yes, handle exception 3384 b common_invokeMethodRange @ (r0=method, r9="this") 3385 3386 3387 /* ------------------------------ */ 3388 .balign 64 3389 .L_OP_UNUSED_79: /* 0x79 */ 3390 /* File: armv5te/OP_UNUSED_79.S */ 3391 /* File: armv5te/unused.S */ 3392 bl common_abort 3393 3394 3395 /* ------------------------------ */ 3396 .balign 64 3397 .L_OP_UNUSED_7A: /* 0x7a */ 3398 /* File: armv5te/OP_UNUSED_7A.S */ 3399 /* File: armv5te/unused.S */ 3400 bl common_abort 3401 3402 3403 /* ------------------------------ */ 3404 .balign 64 3405 .L_OP_NEG_INT: /* 0x7b */ 3406 /* File: armv5te/OP_NEG_INT.S */ 3407 /* File: armv5te/unop.S */ 3408 /* 3409 * Generic 32-bit unary operation. Provide an "instr" line that 3410 * specifies an instruction that performs "result = op r0". 3411 * This could be an ARM instruction or a function call. 3412 * 3413 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3414 * int-to-byte, int-to-char, int-to-short 3415 */ 3416 /* unop vA, vB */ 3417 mov r3, rINST, lsr #12 @ r3<- B 3418 mov r9, rINST, lsr #8 @ r9<- A+ 3419 GET_VREG(r0, r3) @ r0<- vB 3420 and r9, r9, #15 3421 @ optional op; may set condition codes 3422 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3423 rsb r0, r0, #0 @ r0<- op, r0-r3 changed 3424 GET_INST_OPCODE(ip) @ extract opcode from rINST 3425 SET_VREG(r0, r9) @ vAA<- r0 3426 GOTO_OPCODE(ip) @ jump to next instruction 3427 /* 9-10 instructions */ 3428 3429 3430 /* ------------------------------ */ 3431 .balign 64 3432 .L_OP_NOT_INT: /* 0x7c */ 3433 /* File: armv5te/OP_NOT_INT.S */ 3434 /* File: armv5te/unop.S */ 3435 /* 3436 * Generic 32-bit unary operation. Provide an "instr" line that 3437 * specifies an instruction that performs "result = op r0". 3438 * This could be an ARM instruction or a function call. 3439 * 3440 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3441 * int-to-byte, int-to-char, int-to-short 3442 */ 3443 /* unop vA, vB */ 3444 mov r3, rINST, lsr #12 @ r3<- B 3445 mov r9, rINST, lsr #8 @ r9<- A+ 3446 GET_VREG(r0, r3) @ r0<- vB 3447 and r9, r9, #15 3448 @ optional op; may set condition codes 3449 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3450 mvn r0, r0 @ r0<- op, r0-r3 changed 3451 GET_INST_OPCODE(ip) @ extract opcode from rINST 3452 SET_VREG(r0, r9) @ vAA<- r0 3453 GOTO_OPCODE(ip) @ jump to next instruction 3454 /* 9-10 instructions */ 3455 3456 3457 /* ------------------------------ */ 3458 .balign 64 3459 .L_OP_NEG_LONG: /* 0x7d */ 3460 /* File: armv5te/OP_NEG_LONG.S */ 3461 /* File: armv5te/unopWide.S */ 3462 /* 3463 * Generic 64-bit unary operation. Provide an "instr" line that 3464 * specifies an instruction that performs "result = op r0/r1". 3465 * This could be an ARM instruction or a function call. 3466 * 3467 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3468 */ 3469 /* unop vA, vB */ 3470 mov r9, rINST, lsr #8 @ r9<- A+ 3471 mov r3, rINST, lsr #12 @ r3<- B 3472 and r9, r9, #15 3473 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3474 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3475 ldmia r3, {r0-r1} @ r0/r1<- vAA 3476 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3477 rsbs r0, r0, #0 @ optional op; may set condition codes 3478 rsc r1, r1, #0 @ r0/r1<- op, r2-r3 changed 3479 GET_INST_OPCODE(ip) @ extract opcode from rINST 3480 stmia r9, {r0-r1} @ vAA<- r0/r1 3481 GOTO_OPCODE(ip) @ jump to next instruction 3482 /* 12-13 instructions */ 3483 3484 3485 /* ------------------------------ */ 3486 .balign 64 3487 .L_OP_NOT_LONG: /* 0x7e */ 3488 /* File: armv5te/OP_NOT_LONG.S */ 3489 /* File: armv5te/unopWide.S */ 3490 /* 3491 * Generic 64-bit unary operation. Provide an "instr" line that 3492 * specifies an instruction that performs "result = op r0/r1". 3493 * This could be an ARM instruction or a function call. 3494 * 3495 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3496 */ 3497 /* unop vA, vB */ 3498 mov r9, rINST, lsr #8 @ r9<- A+ 3499 mov r3, rINST, lsr #12 @ r3<- B 3500 and r9, r9, #15 3501 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3502 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3503 ldmia r3, {r0-r1} @ r0/r1<- vAA 3504 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3505 mvn r0, r0 @ optional op; may set condition codes 3506 mvn r1, r1 @ r0/r1<- op, r2-r3 changed 3507 GET_INST_OPCODE(ip) @ extract opcode from rINST 3508 stmia r9, {r0-r1} @ vAA<- r0/r1 3509 GOTO_OPCODE(ip) @ jump to next instruction 3510 /* 12-13 instructions */ 3511 3512 3513 /* ------------------------------ */ 3514 .balign 64 3515 .L_OP_NEG_FLOAT: /* 0x7f */ 3516 /* File: armv5te/OP_NEG_FLOAT.S */ 3517 /* File: armv5te/unop.S */ 3518 /* 3519 * Generic 32-bit unary operation. Provide an "instr" line that 3520 * specifies an instruction that performs "result = op r0". 3521 * This could be an ARM instruction or a function call. 3522 * 3523 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3524 * int-to-byte, int-to-char, int-to-short 3525 */ 3526 /* unop vA, vB */ 3527 mov r3, rINST, lsr #12 @ r3<- B 3528 mov r9, rINST, lsr #8 @ r9<- A+ 3529 GET_VREG(r0, r3) @ r0<- vB 3530 and r9, r9, #15 3531 @ optional op; may set condition codes 3532 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3533 add r0, r0, #0x80000000 @ r0<- op, r0-r3 changed 3534 GET_INST_OPCODE(ip) @ extract opcode from rINST 3535 SET_VREG(r0, r9) @ vAA<- r0 3536 GOTO_OPCODE(ip) @ jump to next instruction 3537 /* 9-10 instructions */ 3538 3539 3540 /* ------------------------------ */ 3541 .balign 64 3542 .L_OP_NEG_DOUBLE: /* 0x80 */ 3543 /* File: armv5te/OP_NEG_DOUBLE.S */ 3544 /* File: armv5te/unopWide.S */ 3545 /* 3546 * Generic 64-bit unary operation. Provide an "instr" line that 3547 * specifies an instruction that performs "result = op r0/r1". 3548 * This could be an ARM instruction or a function call. 3549 * 3550 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3551 */ 3552 /* unop vA, vB */ 3553 mov r9, rINST, lsr #8 @ r9<- A+ 3554 mov r3, rINST, lsr #12 @ r3<- B 3555 and r9, r9, #15 3556 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3557 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3558 ldmia r3, {r0-r1} @ r0/r1<- vAA 3559 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3560 @ optional op; may set condition codes 3561 add r1, r1, #0x80000000 @ r0/r1<- op, r2-r3 changed 3562 GET_INST_OPCODE(ip) @ extract opcode from rINST 3563 stmia r9, {r0-r1} @ vAA<- r0/r1 3564 GOTO_OPCODE(ip) @ jump to next instruction 3565 /* 12-13 instructions */ 3566 3567 3568 /* ------------------------------ */ 3569 .balign 64 3570 .L_OP_INT_TO_LONG: /* 0x81 */ 3571 /* File: armv5te/OP_INT_TO_LONG.S */ 3572 /* File: armv5te/unopWider.S */ 3573 /* 3574 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3575 * that specifies an instruction that performs "result = op r0", where 3576 * "result" is a 64-bit quantity in r0/r1. 3577 * 3578 * For: int-to-long, int-to-double, float-to-long, float-to-double 3579 */ 3580 /* unop vA, vB */ 3581 mov r9, rINST, lsr #8 @ r9<- A+ 3582 mov r3, rINST, lsr #12 @ r3<- B 3583 and r9, r9, #15 3584 GET_VREG(r0, r3) @ r0<- vB 3585 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3586 @ optional op; may set condition codes 3587 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3588 mov r1, r0, asr #31 @ r0<- op, r0-r3 changed 3589 GET_INST_OPCODE(ip) @ extract opcode from rINST 3590 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3591 GOTO_OPCODE(ip) @ jump to next instruction 3592 /* 10-11 instructions */ 3593 3594 3595 /* ------------------------------ */ 3596 .balign 64 3597 .L_OP_INT_TO_FLOAT: /* 0x82 */ 3598 /* File: armv5te/OP_INT_TO_FLOAT.S */ 3599 /* File: armv5te/unop.S */ 3600 /* 3601 * Generic 32-bit unary operation. Provide an "instr" line that 3602 * specifies an instruction that performs "result = op r0". 3603 * This could be an ARM instruction or a function call. 3604 * 3605 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3606 * int-to-byte, int-to-char, int-to-short 3607 */ 3608 /* unop vA, vB */ 3609 mov r3, rINST, lsr #12 @ r3<- B 3610 mov r9, rINST, lsr #8 @ r9<- A+ 3611 GET_VREG(r0, r3) @ r0<- vB 3612 and r9, r9, #15 3613 @ optional op; may set condition codes 3614 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3615 bl __aeabi_i2f @ r0<- op, r0-r3 changed 3616 GET_INST_OPCODE(ip) @ extract opcode from rINST 3617 SET_VREG(r0, r9) @ vAA<- r0 3618 GOTO_OPCODE(ip) @ jump to next instruction 3619 /* 9-10 instructions */ 3620 3621 3622 /* ------------------------------ */ 3623 .balign 64 3624 .L_OP_INT_TO_DOUBLE: /* 0x83 */ 3625 /* File: armv5te/OP_INT_TO_DOUBLE.S */ 3626 /* File: armv5te/unopWider.S */ 3627 /* 3628 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3629 * that specifies an instruction that performs "result = op r0", where 3630 * "result" is a 64-bit quantity in r0/r1. 3631 * 3632 * For: int-to-long, int-to-double, float-to-long, float-to-double 3633 */ 3634 /* unop vA, vB */ 3635 mov r9, rINST, lsr #8 @ r9<- A+ 3636 mov r3, rINST, lsr #12 @ r3<- B 3637 and r9, r9, #15 3638 GET_VREG(r0, r3) @ r0<- vB 3639 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3640 @ optional op; may set condition codes 3641 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3642 bl __aeabi_i2d @ r0<- op, r0-r3 changed 3643 GET_INST_OPCODE(ip) @ extract opcode from rINST 3644 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3645 GOTO_OPCODE(ip) @ jump to next instruction 3646 /* 10-11 instructions */ 3647 3648 3649 /* ------------------------------ */ 3650 .balign 64 3651 .L_OP_LONG_TO_INT: /* 0x84 */ 3652 /* File: armv5te/OP_LONG_TO_INT.S */ 3653 /* we ignore the high word, making this equivalent to a 32-bit reg move */ 3654 /* File: armv5te/OP_MOVE.S */ 3655 /* for move, move-object, long-to-int */ 3656 /* op vA, vB */ 3657 mov r1, rINST, lsr #12 @ r1<- B from 15:12 3658 mov r0, rINST, lsr #8 @ r0<- A from 11:8 3659 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3660 GET_VREG(r2, r1) @ r2<- fp[B] 3661 and r0, r0, #15 3662 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 3663 SET_VREG(r2, r0) @ fp[A]<- r2 3664 GOTO_OPCODE(ip) @ execute next instruction 3665 3666 3667 /* ------------------------------ */ 3668 .balign 64 3669 .L_OP_LONG_TO_FLOAT: /* 0x85 */ 3670 /* File: armv5te/OP_LONG_TO_FLOAT.S */ 3671 /* File: armv5te/unopNarrower.S */ 3672 /* 3673 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 3674 * that specifies an instruction that performs "result = op r0/r1", where 3675 * "result" is a 32-bit quantity in r0. 3676 * 3677 * For: long-to-float, double-to-int, double-to-float 3678 * 3679 * (This would work for long-to-int, but that instruction is actually 3680 * an exact match for OP_MOVE.) 3681 */ 3682 /* unop vA, vB */ 3683 mov r3, rINST, lsr #12 @ r3<- B 3684 mov r9, rINST, lsr #8 @ r9<- A+ 3685 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3686 and r9, r9, #15 3687 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 3688 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3689 @ optional op; may set condition codes 3690 bl __aeabi_l2f @ r0<- op, r0-r3 changed 3691 GET_INST_OPCODE(ip) @ extract opcode from rINST 3692 SET_VREG(r0, r9) @ vA<- r0 3693 GOTO_OPCODE(ip) @ jump to next instruction 3694 /* 10-11 instructions */ 3695 3696 3697 /* ------------------------------ */ 3698 .balign 64 3699 .L_OP_LONG_TO_DOUBLE: /* 0x86 */ 3700 /* File: armv5te/OP_LONG_TO_DOUBLE.S */ 3701 /* File: armv5te/unopWide.S */ 3702 /* 3703 * Generic 64-bit unary operation. Provide an "instr" line that 3704 * specifies an instruction that performs "result = op r0/r1". 3705 * This could be an ARM instruction or a function call. 3706 * 3707 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3708 */ 3709 /* unop vA, vB */ 3710 mov r9, rINST, lsr #8 @ r9<- A+ 3711 mov r3, rINST, lsr #12 @ r3<- B 3712 and r9, r9, #15 3713 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3714 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3715 ldmia r3, {r0-r1} @ r0/r1<- vAA 3716 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3717 @ optional op; may set condition codes 3718 bl __aeabi_l2d @ r0/r1<- op, r2-r3 changed 3719 GET_INST_OPCODE(ip) @ extract opcode from rINST 3720 stmia r9, {r0-r1} @ vAA<- r0/r1 3721 GOTO_OPCODE(ip) @ jump to next instruction 3722 /* 12-13 instructions */ 3723 3724 3725 /* ------------------------------ */ 3726 .balign 64 3727 .L_OP_FLOAT_TO_INT: /* 0x87 */ 3728 /* File: armv5te/OP_FLOAT_TO_INT.S */ 3729 /* EABI appears to have Java-style conversions of +inf/-inf/NaN */ 3730 /* File: armv5te/unop.S */ 3731 /* 3732 * Generic 32-bit unary operation. Provide an "instr" line that 3733 * specifies an instruction that performs "result = op r0". 3734 * This could be an ARM instruction or a function call. 3735 * 3736 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3737 * int-to-byte, int-to-char, int-to-short 3738 */ 3739 /* unop vA, vB */ 3740 mov r3, rINST, lsr #12 @ r3<- B 3741 mov r9, rINST, lsr #8 @ r9<- A+ 3742 GET_VREG(r0, r3) @ r0<- vB 3743 and r9, r9, #15 3744 @ optional op; may set condition codes 3745 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3746 bl __aeabi_f2iz @ r0<- op, r0-r3 changed 3747 GET_INST_OPCODE(ip) @ extract opcode from rINST 3748 SET_VREG(r0, r9) @ vAA<- r0 3749 GOTO_OPCODE(ip) @ jump to next instruction 3750 /* 9-10 instructions */ 3751 3752 3753 #if 0 3754 @include "armv5te/unop.S" {"instr":"bl f2i_doconv"} 3755 @break 3756 /* 3757 * Convert the float in r0 to an int in r0. 3758 * 3759 * We have to clip values to int min/max per the specification. The 3760 * expected common case is a "reasonable" value that converts directly 3761 * to modest integer. The EABI convert function isn't doing this for us. 3762 */ 3763 f2i_doconv: 3764 stmfd sp!, {r4, lr} 3765 mov r1, #0x4f000000 @ (float)maxint 3766 mov r4, r0 3767 bl __aeabi_fcmpge @ is arg >= maxint? 3768 cmp r0, #0 @ nonzero == yes 3769 mvnne r0, #0x80000000 @ return maxint (7fffffff) 3770 ldmnefd sp!, {r4, pc} 3771 3772 mov r0, r4 @ recover arg 3773 mov r1, #0xcf000000 @ (float)minint 3774 bl __aeabi_fcmple @ is arg <= minint? 3775 cmp r0, #0 @ nonzero == yes 3776 movne r0, #0x80000000 @ return minint (80000000) 3777 ldmnefd sp!, {r4, pc} 3778 3779 mov r0, r4 @ recover arg 3780 mov r1, r4 3781 bl __aeabi_fcmpeq @ is arg == self? 3782 cmp r0, #0 @ zero == no 3783 ldmeqfd sp!, {r4, pc} @ return zero for NaN 3784 3785 mov r0, r4 @ recover arg 3786 bl __aeabi_f2iz @ convert float to int 3787 ldmfd sp!, {r4, pc} 3788 #endif 3789 3790 /* ------------------------------ */ 3791 .balign 64 3792 .L_OP_FLOAT_TO_LONG: /* 0x88 */ 3793 /* File: armv5te/OP_FLOAT_TO_LONG.S */ 3794 @include "armv5te/unopWider.S" {"instr":"bl __aeabi_f2lz"} 3795 /* File: armv5te/unopWider.S */ 3796 /* 3797 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3798 * that specifies an instruction that performs "result = op r0", where 3799 * "result" is a 64-bit quantity in r0/r1. 3800 * 3801 * For: int-to-long, int-to-double, float-to-long, float-to-double 3802 */ 3803 /* unop vA, vB */ 3804 mov r9, rINST, lsr #8 @ r9<- A+ 3805 mov r3, rINST, lsr #12 @ r3<- B 3806 and r9, r9, #15 3807 GET_VREG(r0, r3) @ r0<- vB 3808 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3809 @ optional op; may set condition codes 3810 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3811 bl f2l_doconv @ r0<- op, r0-r3 changed 3812 GET_INST_OPCODE(ip) @ extract opcode from rINST 3813 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3814 GOTO_OPCODE(ip) @ jump to next instruction 3815 /* 10-11 instructions */ 3816 3817 3818 3819 /* ------------------------------ */ 3820 .balign 64 3821 .L_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 3822 /* File: armv5te/OP_FLOAT_TO_DOUBLE.S */ 3823 /* File: armv5te/unopWider.S */ 3824 /* 3825 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3826 * that specifies an instruction that performs "result = op r0", where 3827 * "result" is a 64-bit quantity in r0/r1. 3828 * 3829 * For: int-to-long, int-to-double, float-to-long, float-to-double 3830 */ 3831 /* unop vA, vB */ 3832 mov r9, rINST, lsr #8 @ r9<- A+ 3833 mov r3, rINST, lsr #12 @ r3<- B 3834 and r9, r9, #15 3835 GET_VREG(r0, r3) @ r0<- vB 3836 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3837 @ optional op; may set condition codes 3838 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3839 bl __aeabi_f2d @ r0<- op, r0-r3 changed 3840 GET_INST_OPCODE(ip) @ extract opcode from rINST 3841 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3842 GOTO_OPCODE(ip) @ jump to next instruction 3843 /* 10-11 instructions */ 3844 3845 3846 /* ------------------------------ */ 3847 .balign 64 3848 .L_OP_DOUBLE_TO_INT: /* 0x8a */ 3849 /* File: armv5te/OP_DOUBLE_TO_INT.S */ 3850 /* EABI appears to have Java-style conversions of +inf/-inf/NaN */ 3851 /* File: armv5te/unopNarrower.S */ 3852 /* 3853 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 3854 * that specifies an instruction that performs "result = op r0/r1", where 3855 * "result" is a 32-bit quantity in r0. 3856 * 3857 * For: long-to-float, double-to-int, double-to-float 3858 * 3859 * (This would work for long-to-int, but that instruction is actually 3860 * an exact match for OP_MOVE.) 3861 */ 3862 /* unop vA, vB */ 3863 mov r3, rINST, lsr #12 @ r3<- B 3864 mov r9, rINST, lsr #8 @ r9<- A+ 3865 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3866 and r9, r9, #15 3867 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 3868 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3869 @ optional op; may set condition codes 3870 bl __aeabi_d2iz @ r0<- op, r0-r3 changed 3871 GET_INST_OPCODE(ip) @ extract opcode from rINST 3872 SET_VREG(r0, r9) @ vA<- r0 3873 GOTO_OPCODE(ip) @ jump to next instruction 3874 /* 10-11 instructions */ 3875 3876 3877 #if 0 3878 @include "armv5te/unopNarrower.S" {"instr":"bl d2i_doconv"} 3879 @break 3880 /* 3881 * Convert the double in r0/r1 to an int in r0. 3882 * 3883 * We have to clip values to int min/max per the specification. The 3884 * expected common case is a "reasonable" value that converts directly 3885 * to modest integer. The EABI convert function isn't doing this for us. 3886 */ 3887 d2i_doconv: 3888 stmfd sp!, {r4, r5, lr} @ save regs 3889 mov r2, #0x80000000 @ maxint, as a double (low word) 3890 mov r2, r2, asr #9 @ 0xffc00000 3891 sub sp, sp, #4 @ align for EABI 3892 mvn r3, #0xbe000000 @ maxint, as a double (high word) 3893 sub r3, r3, #0x00200000 @ 0x41dfffff 3894 mov r4, r0 @ save a copy of r0 3895 mov r5, r1 @ and r1 3896 bl __aeabi_dcmpge @ is arg >= maxint? 3897 cmp r0, #0 @ nonzero == yes 3898 mvnne r0, #0x80000000 @ return maxint (0x7fffffff) 3899 bne 1f 3900 3901 mov r0, r4 @ recover arg 3902 mov r1, r5 3903 mov r3, #0xc1000000 @ minint, as a double (high word) 3904 add r3, r3, #0x00e00000 @ 0xc1e00000 3905 mov r2, #0 @ minint, as a double (low word) 3906 bl __aeabi_dcmple @ is arg <= minint? 3907 cmp r0, #0 @ nonzero == yes 3908 movne r0, #0x80000000 @ return minint (80000000) 3909 bne 1f 3910 3911 mov r0, r4 @ recover arg 3912 mov r1, r5 3913 mov r2, r4 @ compare against self 3914 mov r3, r5 3915 bl __aeabi_dcmpeq @ is arg == self? 3916 cmp r0, #0 @ zero == no 3917 beq 1f @ return zero for NaN 3918 3919 mov r0, r4 @ recover arg 3920 mov r1, r5 3921 bl __aeabi_d2iz @ convert double to int 3922 3923 1: 3924 add sp, sp, #4 3925 ldmfd sp!, {r4, r5, pc} 3926 #endif 3927 3928 /* ------------------------------ */ 3929 .balign 64 3930 .L_OP_DOUBLE_TO_LONG: /* 0x8b */ 3931 /* File: armv5te/OP_DOUBLE_TO_LONG.S */ 3932 @include "armv5te/unopWide.S" {"instr":"bl __aeabi_d2lz"} 3933 /* File: armv5te/unopWide.S */ 3934 /* 3935 * Generic 64-bit unary operation. Provide an "instr" line that 3936 * specifies an instruction that performs "result = op r0/r1". 3937 * This could be an ARM instruction or a function call. 3938 * 3939 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3940 */ 3941 /* unop vA, vB */ 3942 mov r9, rINST, lsr #8 @ r9<- A+ 3943 mov r3, rINST, lsr #12 @ r3<- B 3944 and r9, r9, #15 3945 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3946 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3947 ldmia r3, {r0-r1} @ r0/r1<- vAA 3948 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3949 @ optional op; may set condition codes 3950 bl d2l_doconv @ r0/r1<- op, r2-r3 changed 3951 GET_INST_OPCODE(ip) @ extract opcode from rINST 3952 stmia r9, {r0-r1} @ vAA<- r0/r1 3953 GOTO_OPCODE(ip) @ jump to next instruction 3954 /* 12-13 instructions */ 3955 3956 3957 3958 /* ------------------------------ */ 3959 .balign 64 3960 .L_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 3961 /* File: armv5te/OP_DOUBLE_TO_FLOAT.S */ 3962 /* File: armv5te/unopNarrower.S */ 3963 /* 3964 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 3965 * that specifies an instruction that performs "result = op r0/r1", where 3966 * "result" is a 32-bit quantity in r0. 3967 * 3968 * For: long-to-float, double-to-int, double-to-float 3969 * 3970 * (This would work for long-to-int, but that instruction is actually 3971 * an exact match for OP_MOVE.) 3972 */ 3973 /* unop vA, vB */ 3974 mov r3, rINST, lsr #12 @ r3<- B 3975 mov r9, rINST, lsr #8 @ r9<- A+ 3976 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3977 and r9, r9, #15 3978 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 3979 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3980 @ optional op; may set condition codes 3981 bl __aeabi_d2f @ r0<- op, r0-r3 changed 3982 GET_INST_OPCODE(ip) @ extract opcode from rINST 3983 SET_VREG(r0, r9) @ vA<- r0 3984 GOTO_OPCODE(ip) @ jump to next instruction 3985 /* 10-11 instructions */ 3986 3987 3988 /* ------------------------------ */ 3989 .balign 64 3990 .L_OP_INT_TO_BYTE: /* 0x8d */ 3991 /* File: armv5te/OP_INT_TO_BYTE.S */ 3992 /* File: armv5te/unop.S */ 3993 /* 3994 * Generic 32-bit unary operation. Provide an "instr" line that 3995 * specifies an instruction that performs "result = op r0". 3996 * This could be an ARM instruction or a function call. 3997 * 3998 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3999 * int-to-byte, int-to-char, int-to-short 4000 */ 4001 /* unop vA, vB */ 4002 mov r3, rINST, lsr #12 @ r3<- B 4003 mov r9, rINST, lsr #8 @ r9<- A+ 4004 GET_VREG(r0, r3) @ r0<- vB 4005 and r9, r9, #15 4006 mov r0, r0, asl #24 @ optional op; may set condition codes 4007 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 4008 mov r0, r0, asr #24 @ r0<- op, r0-r3 changed 4009 GET_INST_OPCODE(ip) @ extract opcode from rINST 4010 SET_VREG(r0, r9) @ vAA<- r0 4011 GOTO_OPCODE(ip) @ jump to next instruction 4012 /* 9-10 instructions */ 4013 4014 4015 /* ------------------------------ */ 4016 .balign 64 4017 .L_OP_INT_TO_CHAR: /* 0x8e */ 4018 /* File: armv5te/OP_INT_TO_CHAR.S */ 4019 /* File: armv5te/unop.S */ 4020 /* 4021 * Generic 32-bit unary operation. Provide an "instr" line that 4022 * specifies an instruction that performs "result = op r0". 4023 * This could be an ARM instruction or a function call. 4024 * 4025 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 4026 * int-to-byte, int-to-char, int-to-short 4027 */ 4028 /* unop vA, vB */ 4029 mov r3, rINST, lsr #12 @ r3<- B 4030 mov r9, rINST, lsr #8 @ r9<- A+ 4031 GET_VREG(r0, r3) @ r0<- vB 4032 and r9, r9, #15 4033 mov r0, r0, asl #16 @ optional op; may set condition codes 4034 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 4035 mov r0, r0, lsr #16 @ r0<- op, r0-r3 changed 4036 GET_INST_OPCODE(ip) @ extract opcode from rINST 4037 SET_VREG(r0, r9) @ vAA<- r0 4038 GOTO_OPCODE(ip) @ jump to next instruction 4039 /* 9-10 instructions */ 4040 4041 4042 /* ------------------------------ */ 4043 .balign 64 4044 .L_OP_INT_TO_SHORT: /* 0x8f */ 4045 /* File: armv5te/OP_INT_TO_SHORT.S */ 4046 /* File: armv5te/unop.S */ 4047 /* 4048 * Generic 32-bit unary operation. Provide an "instr" line that 4049 * specifies an instruction that performs "result = op r0". 4050 * This could be an ARM instruction or a function call. 4051 * 4052 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 4053 * int-to-byte, int-to-char, int-to-short 4054 */ 4055 /* unop vA, vB */ 4056 mov r3, rINST, lsr #12 @ r3<- B 4057 mov r9, rINST, lsr #8 @ r9<- A+ 4058 GET_VREG(r0, r3) @ r0<- vB 4059 and r9, r9, #15 4060 mov r0, r0, asl #16 @ optional op; may set condition codes 4061 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 4062 mov r0, r0, asr #16 @ r0<- op, r0-r3 changed 4063 GET_INST_OPCODE(ip) @ extract opcode from rINST 4064 SET_VREG(r0, r9) @ vAA<- r0 4065 GOTO_OPCODE(ip) @ jump to next instruction 4066 /* 9-10 instructions */ 4067 4068 4069 /* ------------------------------ */ 4070 .balign 64 4071 .L_OP_ADD_INT: /* 0x90 */ 4072 /* File: armv5te/OP_ADD_INT.S */ 4073 /* File: armv5te/binop.S */ 4074 /* 4075 * Generic 32-bit binary operation. Provide an "instr" line that 4076 * specifies an instruction that performs "result = r0 op r1". 4077 * This could be an ARM instruction or a function call. (If the result 4078 * comes back in a register other than r0, you can override "result".) 4079 * 4080 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4081 * vCC (r1). Useful for integer division and modulus. Note that we 4082 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4083 * handles it correctly. 4084 * 4085 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4086 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4087 * mul-float, div-float, rem-float 4088 */ 4089 /* binop vAA, vBB, vCC */ 4090 FETCH(r0, 1) @ r0<- CCBB 4091 mov r9, rINST, lsr #8 @ r9<- AA 4092 mov r3, r0, lsr #8 @ r3<- CC 4093 and r2, r0, #255 @ r2<- BB 4094 GET_VREG(r1, r3) @ r1<- vCC 4095 GET_VREG(r0, r2) @ r0<- vBB 4096 .if 0 4097 cmp r1, #0 @ is second operand zero? 4098 beq common_errDivideByZero 4099 .endif 4100 4101 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4102 @ optional op; may set condition codes 4103 add r0, r0, r1 @ r0<- op, r0-r3 changed 4104 GET_INST_OPCODE(ip) @ extract opcode from rINST 4105 SET_VREG(r0, r9) @ vAA<- r0 4106 GOTO_OPCODE(ip) @ jump to next instruction 4107 /* 11-14 instructions */ 4108 4109 4110 /* ------------------------------ */ 4111 .balign 64 4112 .L_OP_SUB_INT: /* 0x91 */ 4113 /* File: armv5te/OP_SUB_INT.S */ 4114 /* File: armv5te/binop.S */ 4115 /* 4116 * Generic 32-bit binary operation. Provide an "instr" line that 4117 * specifies an instruction that performs "result = r0 op r1". 4118 * This could be an ARM instruction or a function call. (If the result 4119 * comes back in a register other than r0, you can override "result".) 4120 * 4121 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4122 * vCC (r1). Useful for integer division and modulus. Note that we 4123 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4124 * handles it correctly. 4125 * 4126 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4127 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4128 * mul-float, div-float, rem-float 4129 */ 4130 /* binop vAA, vBB, vCC */ 4131 FETCH(r0, 1) @ r0<- CCBB 4132 mov r9, rINST, lsr #8 @ r9<- AA 4133 mov r3, r0, lsr #8 @ r3<- CC 4134 and r2, r0, #255 @ r2<- BB 4135 GET_VREG(r1, r3) @ r1<- vCC 4136 GET_VREG(r0, r2) @ r0<- vBB 4137 .if 0 4138 cmp r1, #0 @ is second operand zero? 4139 beq common_errDivideByZero 4140 .endif 4141 4142 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4143 @ optional op; may set condition codes 4144 sub r0, r0, r1 @ r0<- op, r0-r3 changed 4145 GET_INST_OPCODE(ip) @ extract opcode from rINST 4146 SET_VREG(r0, r9) @ vAA<- r0 4147 GOTO_OPCODE(ip) @ jump to next instruction 4148 /* 11-14 instructions */ 4149 4150 4151 /* ------------------------------ */ 4152 .balign 64 4153 .L_OP_MUL_INT: /* 0x92 */ 4154 /* File: armv5te/OP_MUL_INT.S */ 4155 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 4156 /* File: armv5te/binop.S */ 4157 /* 4158 * Generic 32-bit binary operation. Provide an "instr" line that 4159 * specifies an instruction that performs "result = r0 op r1". 4160 * This could be an ARM instruction or a function call. (If the result 4161 * comes back in a register other than r0, you can override "result".) 4162 * 4163 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4164 * vCC (r1). Useful for integer division and modulus. Note that we 4165 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4166 * handles it correctly. 4167 * 4168 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4169 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4170 * mul-float, div-float, rem-float 4171 */ 4172 /* binop vAA, vBB, vCC */ 4173 FETCH(r0, 1) @ r0<- CCBB 4174 mov r9, rINST, lsr #8 @ r9<- AA 4175 mov r3, r0, lsr #8 @ r3<- CC 4176 and r2, r0, #255 @ r2<- BB 4177 GET_VREG(r1, r3) @ r1<- vCC 4178 GET_VREG(r0, r2) @ r0<- vBB 4179 .if 0 4180 cmp r1, #0 @ is second operand zero? 4181 beq common_errDivideByZero 4182 .endif 4183 4184 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4185 @ optional op; may set condition codes 4186 mul r0, r1, r0 @ r0<- op, r0-r3 changed 4187 GET_INST_OPCODE(ip) @ extract opcode from rINST 4188 SET_VREG(r0, r9) @ vAA<- r0 4189 GOTO_OPCODE(ip) @ jump to next instruction 4190 /* 11-14 instructions */ 4191 4192 4193 /* ------------------------------ */ 4194 .balign 64 4195 .L_OP_DIV_INT: /* 0x93 */ 4196 /* File: armv5te/OP_DIV_INT.S */ 4197 /* File: armv5te/binop.S */ 4198 /* 4199 * Generic 32-bit binary operation. Provide an "instr" line that 4200 * specifies an instruction that performs "result = r0 op r1". 4201 * This could be an ARM instruction or a function call. (If the result 4202 * comes back in a register other than r0, you can override "result".) 4203 * 4204 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4205 * vCC (r1). Useful for integer division and modulus. Note that we 4206 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4207 * handles it correctly. 4208 * 4209 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4210 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4211 * mul-float, div-float, rem-float 4212 */ 4213 /* binop vAA, vBB, vCC */ 4214 FETCH(r0, 1) @ r0<- CCBB 4215 mov r9, rINST, lsr #8 @ r9<- AA 4216 mov r3, r0, lsr #8 @ r3<- CC 4217 and r2, r0, #255 @ r2<- BB 4218 GET_VREG(r1, r3) @ r1<- vCC 4219 GET_VREG(r0, r2) @ r0<- vBB 4220 .if 1 4221 cmp r1, #0 @ is second operand zero? 4222 beq common_errDivideByZero 4223 .endif 4224 4225 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4226 @ optional op; may set condition codes 4227 bl __aeabi_idiv @ r0<- op, r0-r3 changed 4228 GET_INST_OPCODE(ip) @ extract opcode from rINST 4229 SET_VREG(r0, r9) @ vAA<- r0 4230 GOTO_OPCODE(ip) @ jump to next instruction 4231 /* 11-14 instructions */ 4232 4233 4234 /* ------------------------------ */ 4235 .balign 64 4236 .L_OP_REM_INT: /* 0x94 */ 4237 /* File: armv5te/OP_REM_INT.S */ 4238 /* idivmod returns quotient in r0 and remainder in r1 */ 4239 /* File: armv5te/binop.S */ 4240 /* 4241 * Generic 32-bit binary operation. Provide an "instr" line that 4242 * specifies an instruction that performs "result = r0 op r1". 4243 * This could be an ARM instruction or a function call. (If the result 4244 * comes back in a register other than r0, you can override "result".) 4245 * 4246 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4247 * vCC (r1). Useful for integer division and modulus. Note that we 4248 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4249 * handles it correctly. 4250 * 4251 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4252 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4253 * mul-float, div-float, rem-float 4254 */ 4255 /* binop vAA, vBB, vCC */ 4256 FETCH(r0, 1) @ r0<- CCBB 4257 mov r9, rINST, lsr #8 @ r9<- AA 4258 mov r3, r0, lsr #8 @ r3<- CC 4259 and r2, r0, #255 @ r2<- BB 4260 GET_VREG(r1, r3) @ r1<- vCC 4261 GET_VREG(r0, r2) @ r0<- vBB 4262 .if 1 4263 cmp r1, #0 @ is second operand zero? 4264 beq common_errDivideByZero 4265 .endif 4266 4267 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4268 @ optional op; may set condition codes 4269 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 4270 GET_INST_OPCODE(ip) @ extract opcode from rINST 4271 SET_VREG(r1, r9) @ vAA<- r1 4272 GOTO_OPCODE(ip) @ jump to next instruction 4273 /* 11-14 instructions */ 4274 4275 4276 /* ------------------------------ */ 4277 .balign 64 4278 .L_OP_AND_INT: /* 0x95 */ 4279 /* File: armv5te/OP_AND_INT.S */ 4280 /* File: armv5te/binop.S */ 4281 /* 4282 * Generic 32-bit binary operation. Provide an "instr" line that 4283 * specifies an instruction that performs "result = r0 op r1". 4284 * This could be an ARM instruction or a function call. (If the result 4285 * comes back in a register other than r0, you can override "result".) 4286 * 4287 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4288 * vCC (r1). Useful for integer division and modulus. Note that we 4289 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4290 * handles it correctly. 4291 * 4292 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4293 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4294 * mul-float, div-float, rem-float 4295 */ 4296 /* binop vAA, vBB, vCC */ 4297 FETCH(r0, 1) @ r0<- CCBB 4298 mov r9, rINST, lsr #8 @ r9<- AA 4299 mov r3, r0, lsr #8 @ r3<- CC 4300 and r2, r0, #255 @ r2<- BB 4301 GET_VREG(r1, r3) @ r1<- vCC 4302 GET_VREG(r0, r2) @ r0<- vBB 4303 .if 0 4304 cmp r1, #0 @ is second operand zero? 4305 beq common_errDivideByZero 4306 .endif 4307 4308 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4309 @ optional op; may set condition codes 4310 and r0, r0, r1 @ r0<- op, r0-r3 changed 4311 GET_INST_OPCODE(ip) @ extract opcode from rINST 4312 SET_VREG(r0, r9) @ vAA<- r0 4313 GOTO_OPCODE(ip) @ jump to next instruction 4314 /* 11-14 instructions */ 4315 4316 4317 /* ------------------------------ */ 4318 .balign 64 4319 .L_OP_OR_INT: /* 0x96 */ 4320 /* File: armv5te/OP_OR_INT.S */ 4321 /* File: armv5te/binop.S */ 4322 /* 4323 * Generic 32-bit binary operation. Provide an "instr" line that 4324 * specifies an instruction that performs "result = r0 op r1". 4325 * This could be an ARM instruction or a function call. (If the result 4326 * comes back in a register other than r0, you can override "result".) 4327 * 4328 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4329 * vCC (r1). Useful for integer division and modulus. Note that we 4330 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4331 * handles it correctly. 4332 * 4333 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4334 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4335 * mul-float, div-float, rem-float 4336 */ 4337 /* binop vAA, vBB, vCC */ 4338 FETCH(r0, 1) @ r0<- CCBB 4339 mov r9, rINST, lsr #8 @ r9<- AA 4340 mov r3, r0, lsr #8 @ r3<- CC 4341 and r2, r0, #255 @ r2<- BB 4342 GET_VREG(r1, r3) @ r1<- vCC 4343 GET_VREG(r0, r2) @ r0<- vBB 4344 .if 0 4345 cmp r1, #0 @ is second operand zero? 4346 beq common_errDivideByZero 4347 .endif 4348 4349 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4350 @ optional op; may set condition codes 4351 orr r0, r0, r1 @ r0<- op, r0-r3 changed 4352 GET_INST_OPCODE(ip) @ extract opcode from rINST 4353 SET_VREG(r0, r9) @ vAA<- r0 4354 GOTO_OPCODE(ip) @ jump to next instruction 4355 /* 11-14 instructions */ 4356 4357 4358 /* ------------------------------ */ 4359 .balign 64 4360 .L_OP_XOR_INT: /* 0x97 */ 4361 /* File: armv5te/OP_XOR_INT.S */ 4362 /* File: armv5te/binop.S */ 4363 /* 4364 * Generic 32-bit binary operation. Provide an "instr" line that 4365 * specifies an instruction that performs "result = r0 op r1". 4366 * This could be an ARM instruction or a function call. (If the result 4367 * comes back in a register other than r0, you can override "result".) 4368 * 4369 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4370 * vCC (r1). Useful for integer division and modulus. Note that we 4371 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4372 * handles it correctly. 4373 * 4374 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4375 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4376 * mul-float, div-float, rem-float 4377 */ 4378 /* binop vAA, vBB, vCC */ 4379 FETCH(r0, 1) @ r0<- CCBB 4380 mov r9, rINST, lsr #8 @ r9<- AA 4381 mov r3, r0, lsr #8 @ r3<- CC 4382 and r2, r0, #255 @ r2<- BB 4383 GET_VREG(r1, r3) @ r1<- vCC 4384 GET_VREG(r0, r2) @ r0<- vBB 4385 .if 0 4386 cmp r1, #0 @ is second operand zero? 4387 beq common_errDivideByZero 4388 .endif 4389 4390 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4391 @ optional op; may set condition codes 4392 eor r0, r0, r1 @ r0<- op, r0-r3 changed 4393 GET_INST_OPCODE(ip) @ extract opcode from rINST 4394 SET_VREG(r0, r9) @ vAA<- r0 4395 GOTO_OPCODE(ip) @ jump to next instruction 4396 /* 11-14 instructions */ 4397 4398 4399 /* ------------------------------ */ 4400 .balign 64 4401 .L_OP_SHL_INT: /* 0x98 */ 4402 /* File: armv5te/OP_SHL_INT.S */ 4403 /* File: armv5te/binop.S */ 4404 /* 4405 * Generic 32-bit binary operation. Provide an "instr" line that 4406 * specifies an instruction that performs "result = r0 op r1". 4407 * This could be an ARM instruction or a function call. (If the result 4408 * comes back in a register other than r0, you can override "result".) 4409 * 4410 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4411 * vCC (r1). Useful for integer division and modulus. Note that we 4412 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4413 * handles it correctly. 4414 * 4415 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4416 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4417 * mul-float, div-float, rem-float 4418 */ 4419 /* binop vAA, vBB, vCC */ 4420 FETCH(r0, 1) @ r0<- CCBB 4421 mov r9, rINST, lsr #8 @ r9<- AA 4422 mov r3, r0, lsr #8 @ r3<- CC 4423 and r2, r0, #255 @ r2<- BB 4424 GET_VREG(r1, r3) @ r1<- vCC 4425 GET_VREG(r0, r2) @ r0<- vBB 4426 .if 0 4427 cmp r1, #0 @ is second operand zero? 4428 beq common_errDivideByZero 4429 .endif 4430 4431 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4432 and r1, r1, #31 @ optional op; may set condition codes 4433 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 4434 GET_INST_OPCODE(ip) @ extract opcode from rINST 4435 SET_VREG(r0, r9) @ vAA<- r0 4436 GOTO_OPCODE(ip) @ jump to next instruction 4437 /* 11-14 instructions */ 4438 4439 4440 /* ------------------------------ */ 4441 .balign 64 4442 .L_OP_SHR_INT: /* 0x99 */ 4443 /* File: armv5te/OP_SHR_INT.S */ 4444 /* File: armv5te/binop.S */ 4445 /* 4446 * Generic 32-bit binary operation. Provide an "instr" line that 4447 * specifies an instruction that performs "result = r0 op r1". 4448 * This could be an ARM instruction or a function call. (If the result 4449 * comes back in a register other than r0, you can override "result".) 4450 * 4451 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4452 * vCC (r1). Useful for integer division and modulus. Note that we 4453 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4454 * handles it correctly. 4455 * 4456 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4457 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4458 * mul-float, div-float, rem-float 4459 */ 4460 /* binop vAA, vBB, vCC */ 4461 FETCH(r0, 1) @ r0<- CCBB 4462 mov r9, rINST, lsr #8 @ r9<- AA 4463 mov r3, r0, lsr #8 @ r3<- CC 4464 and r2, r0, #255 @ r2<- BB 4465 GET_VREG(r1, r3) @ r1<- vCC 4466 GET_VREG(r0, r2) @ r0<- vBB 4467 .if 0 4468 cmp r1, #0 @ is second operand zero? 4469 beq common_errDivideByZero 4470 .endif 4471 4472 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4473 and r1, r1, #31 @ optional op; may set condition codes 4474 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 4475 GET_INST_OPCODE(ip) @ extract opcode from rINST 4476 SET_VREG(r0, r9) @ vAA<- r0 4477 GOTO_OPCODE(ip) @ jump to next instruction 4478 /* 11-14 instructions */ 4479 4480 4481 /* ------------------------------ */ 4482 .balign 64 4483 .L_OP_USHR_INT: /* 0x9a */ 4484 /* File: armv5te/OP_USHR_INT.S */ 4485 /* File: armv5te/binop.S */ 4486 /* 4487 * Generic 32-bit binary operation. Provide an "instr" line that 4488 * specifies an instruction that performs "result = r0 op r1". 4489 * This could be an ARM instruction or a function call. (If the result 4490 * comes back in a register other than r0, you can override "result".) 4491 * 4492 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4493 * vCC (r1). Useful for integer division and modulus. Note that we 4494 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4495 * handles it correctly. 4496 * 4497 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4498 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4499 * mul-float, div-float, rem-float 4500 */ 4501 /* binop vAA, vBB, vCC */ 4502 FETCH(r0, 1) @ r0<- CCBB 4503 mov r9, rINST, lsr #8 @ r9<- AA 4504 mov r3, r0, lsr #8 @ r3<- CC 4505 and r2, r0, #255 @ r2<- BB 4506 GET_VREG(r1, r3) @ r1<- vCC 4507 GET_VREG(r0, r2) @ r0<- vBB 4508 .if 0 4509 cmp r1, #0 @ is second operand zero? 4510 beq common_errDivideByZero 4511 .endif 4512 4513 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4514 and r1, r1, #31 @ optional op; may set condition codes 4515 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 4516 GET_INST_OPCODE(ip) @ extract opcode from rINST 4517 SET_VREG(r0, r9) @ vAA<- r0 4518 GOTO_OPCODE(ip) @ jump to next instruction 4519 /* 11-14 instructions */ 4520 4521 4522 /* ------------------------------ */ 4523 .balign 64 4524 .L_OP_ADD_LONG: /* 0x9b */ 4525 /* File: armv5te/OP_ADD_LONG.S */ 4526 /* File: armv5te/binopWide.S */ 4527 /* 4528 * Generic 64-bit binary operation. Provide an "instr" line that 4529 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4530 * This could be an ARM instruction or a function call. (If the result 4531 * comes back in a register other than r0, you can override "result".) 4532 * 4533 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4534 * vCC (r1). Useful for integer division and modulus. 4535 * 4536 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4537 * xor-long, add-double, sub-double, mul-double, div-double, 4538 * rem-double 4539 * 4540 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4541 */ 4542 /* binop vAA, vBB, vCC */ 4543 FETCH(r0, 1) @ r0<- CCBB 4544 mov r9, rINST, lsr #8 @ r9<- AA 4545 and r2, r0, #255 @ r2<- BB 4546 mov r3, r0, lsr #8 @ r3<- CC 4547 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4548 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4549 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4550 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4551 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4552 .if 0 4553 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4554 beq common_errDivideByZero 4555 .endif 4556 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4557 4558 adds r0, r0, r2 @ optional op; may set condition codes 4559 adc r1, r1, r3 @ result<- op, r0-r3 changed 4560 GET_INST_OPCODE(ip) @ extract opcode from rINST 4561 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4562 GOTO_OPCODE(ip) @ jump to next instruction 4563 /* 14-17 instructions */ 4564 4565 4566 /* ------------------------------ */ 4567 .balign 64 4568 .L_OP_SUB_LONG: /* 0x9c */ 4569 /* File: armv5te/OP_SUB_LONG.S */ 4570 /* File: armv5te/binopWide.S */ 4571 /* 4572 * Generic 64-bit binary operation. Provide an "instr" line that 4573 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4574 * This could be an ARM instruction or a function call. (If the result 4575 * comes back in a register other than r0, you can override "result".) 4576 * 4577 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4578 * vCC (r1). Useful for integer division and modulus. 4579 * 4580 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4581 * xor-long, add-double, sub-double, mul-double, div-double, 4582 * rem-double 4583 * 4584 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4585 */ 4586 /* binop vAA, vBB, vCC */ 4587 FETCH(r0, 1) @ r0<- CCBB 4588 mov r9, rINST, lsr #8 @ r9<- AA 4589 and r2, r0, #255 @ r2<- BB 4590 mov r3, r0, lsr #8 @ r3<- CC 4591 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4592 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4593 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4594 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4595 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4596 .if 0 4597 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4598 beq common_errDivideByZero 4599 .endif 4600 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4601 4602 subs r0, r0, r2 @ optional op; may set condition codes 4603 sbc r1, r1, r3 @ result<- op, r0-r3 changed 4604 GET_INST_OPCODE(ip) @ extract opcode from rINST 4605 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4606 GOTO_OPCODE(ip) @ jump to next instruction 4607 /* 14-17 instructions */ 4608 4609 4610 /* ------------------------------ */ 4611 .balign 64 4612 .L_OP_MUL_LONG: /* 0x9d */ 4613 /* File: armv5te/OP_MUL_LONG.S */ 4614 /* 4615 * Signed 64-bit integer multiply. 4616 * 4617 * Consider WXxYZ (r1r0 x r3r2) with a long multiply: 4618 * WX 4619 * x YZ 4620 * -------- 4621 * ZW ZX 4622 * YW YX 4623 * 4624 * The low word of the result holds ZX, the high word holds 4625 * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because 4626 * it doesn't fit in the low 64 bits. 4627 * 4628 * Unlike most ARM math operations, multiply instructions have 4629 * restrictions on using the same register more than once (Rd and Rm 4630 * cannot be the same). 4631 */ 4632 /* mul-long vAA, vBB, vCC */ 4633 FETCH(r0, 1) @ r0<- CCBB 4634 and r2, r0, #255 @ r2<- BB 4635 mov r3, r0, lsr #8 @ r3<- CC 4636 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4637 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4638 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4639 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4640 mul ip, r2, r1 @ ip<- ZxW 4641 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 4642 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 4643 mov r0, rINST, lsr #8 @ r0<- AA 4644 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 4645 add r0, rFP, r0, lsl #2 @ r0<- &fp[AA] 4646 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4647 b .LOP_MUL_LONG_finish 4648 4649 /* ------------------------------ */ 4650 .balign 64 4651 .L_OP_DIV_LONG: /* 0x9e */ 4652 /* File: armv5te/OP_DIV_LONG.S */ 4653 /* File: armv5te/binopWide.S */ 4654 /* 4655 * Generic 64-bit binary operation. Provide an "instr" line that 4656 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4657 * This could be an ARM instruction or a function call. (If the result 4658 * comes back in a register other than r0, you can override "result".) 4659 * 4660 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4661 * vCC (r1). Useful for integer division and modulus. 4662 * 4663 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4664 * xor-long, add-double, sub-double, mul-double, div-double, 4665 * rem-double 4666 * 4667 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4668 */ 4669 /* binop vAA, vBB, vCC */ 4670 FETCH(r0, 1) @ r0<- CCBB 4671 mov r9, rINST, lsr #8 @ r9<- AA 4672 and r2, r0, #255 @ r2<- BB 4673 mov r3, r0, lsr #8 @ r3<- CC 4674 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4675 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4676 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4677 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4678 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4679 .if 1 4680 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4681 beq common_errDivideByZero 4682 .endif 4683 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4684 4685 @ optional op; may set condition codes 4686 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4687 GET_INST_OPCODE(ip) @ extract opcode from rINST 4688 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4689 GOTO_OPCODE(ip) @ jump to next instruction 4690 /* 14-17 instructions */ 4691 4692 4693 /* ------------------------------ */ 4694 .balign 64 4695 .L_OP_REM_LONG: /* 0x9f */ 4696 /* File: armv5te/OP_REM_LONG.S */ 4697 /* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 4698 /* File: armv5te/binopWide.S */ 4699 /* 4700 * Generic 64-bit binary operation. Provide an "instr" line that 4701 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4702 * This could be an ARM instruction or a function call. (If the result 4703 * comes back in a register other than r0, you can override "result".) 4704 * 4705 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4706 * vCC (r1). Useful for integer division and modulus. 4707 * 4708 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4709 * xor-long, add-double, sub-double, mul-double, div-double, 4710 * rem-double 4711 * 4712 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4713 */ 4714 /* binop vAA, vBB, vCC */ 4715 FETCH(r0, 1) @ r0<- CCBB 4716 mov r9, rINST, lsr #8 @ r9<- AA 4717 and r2, r0, #255 @ r2<- BB 4718 mov r3, r0, lsr #8 @ r3<- CC 4719 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4720 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4721 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4722 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4723 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4724 .if 1 4725 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4726 beq common_errDivideByZero 4727 .endif 4728 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4729 4730 @ optional op; may set condition codes 4731 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4732 GET_INST_OPCODE(ip) @ extract opcode from rINST 4733 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 4734 GOTO_OPCODE(ip) @ jump to next instruction 4735 /* 14-17 instructions */ 4736 4737 4738 /* ------------------------------ */ 4739 .balign 64 4740 .L_OP_AND_LONG: /* 0xa0 */ 4741 /* File: armv5te/OP_AND_LONG.S */ 4742 /* File: armv5te/binopWide.S */ 4743 /* 4744 * Generic 64-bit binary operation. Provide an "instr" line that 4745 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4746 * This could be an ARM instruction or a function call. (If the result 4747 * comes back in a register other than r0, you can override "result".) 4748 * 4749 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4750 * vCC (r1). Useful for integer division and modulus. 4751 * 4752 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4753 * xor-long, add-double, sub-double, mul-double, div-double, 4754 * rem-double 4755 * 4756 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4757 */ 4758 /* binop vAA, vBB, vCC */ 4759 FETCH(r0, 1) @ r0<- CCBB 4760 mov r9, rINST, lsr #8 @ r9<- AA 4761 and r2, r0, #255 @ r2<- BB 4762 mov r3, r0, lsr #8 @ r3<- CC 4763 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4764 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4765 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4766 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4767 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4768 .if 0 4769 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4770 beq common_errDivideByZero 4771 .endif 4772 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4773 4774 and r0, r0, r2 @ optional op; may set condition codes 4775 and r1, r1, r3 @ result<- op, r0-r3 changed 4776 GET_INST_OPCODE(ip) @ extract opcode from rINST 4777 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4778 GOTO_OPCODE(ip) @ jump to next instruction 4779 /* 14-17 instructions */ 4780 4781 4782 /* ------------------------------ */ 4783 .balign 64 4784 .L_OP_OR_LONG: /* 0xa1 */ 4785 /* File: armv5te/OP_OR_LONG.S */ 4786 /* File: armv5te/binopWide.S */ 4787 /* 4788 * Generic 64-bit binary operation. Provide an "instr" line that 4789 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4790 * This could be an ARM instruction or a function call. (If the result 4791 * comes back in a register other than r0, you can override "result".) 4792 * 4793 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4794 * vCC (r1). Useful for integer division and modulus. 4795 * 4796 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4797 * xor-long, add-double, sub-double, mul-double, div-double, 4798 * rem-double 4799 * 4800 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4801 */ 4802 /* binop vAA, vBB, vCC */ 4803 FETCH(r0, 1) @ r0<- CCBB 4804 mov r9, rINST, lsr #8 @ r9<- AA 4805 and r2, r0, #255 @ r2<- BB 4806 mov r3, r0, lsr #8 @ r3<- CC 4807 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4808 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4809 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4810 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4811 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4812 .if 0 4813 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4814 beq common_errDivideByZero 4815 .endif 4816 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4817 4818 orr r0, r0, r2 @ optional op; may set condition codes 4819 orr r1, r1, r3 @ result<- op, r0-r3 changed 4820 GET_INST_OPCODE(ip) @ extract opcode from rINST 4821 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4822 GOTO_OPCODE(ip) @ jump to next instruction 4823 /* 14-17 instructions */ 4824 4825 4826 /* ------------------------------ */ 4827 .balign 64 4828 .L_OP_XOR_LONG: /* 0xa2 */ 4829 /* File: armv5te/OP_XOR_LONG.S */ 4830 /* File: armv5te/binopWide.S */ 4831 /* 4832 * Generic 64-bit binary operation. Provide an "instr" line that 4833 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4834 * This could be an ARM instruction or a function call. (If the result 4835 * comes back in a register other than r0, you can override "result".) 4836 * 4837 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4838 * vCC (r1). Useful for integer division and modulus. 4839 * 4840 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4841 * xor-long, add-double, sub-double, mul-double, div-double, 4842 * rem-double 4843 * 4844 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4845 */ 4846 /* binop vAA, vBB, vCC */ 4847 FETCH(r0, 1) @ r0<- CCBB 4848 mov r9, rINST, lsr #8 @ r9<- AA 4849 and r2, r0, #255 @ r2<- BB 4850 mov r3, r0, lsr #8 @ r3<- CC 4851 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4852 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4853 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4854 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4855 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4856 .if 0 4857 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4858 beq common_errDivideByZero 4859 .endif 4860 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4861 4862 eor r0, r0, r2 @ optional op; may set condition codes 4863 eor r1, r1, r3 @ result<- op, r0-r3 changed 4864 GET_INST_OPCODE(ip) @ extract opcode from rINST 4865 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4866 GOTO_OPCODE(ip) @ jump to next instruction 4867 /* 14-17 instructions */ 4868 4869 4870 /* ------------------------------ */ 4871 .balign 64 4872 .L_OP_SHL_LONG: /* 0xa3 */ 4873 /* File: armv5te/OP_SHL_LONG.S */ 4874 /* 4875 * Long integer shift. This is different from the generic 32/64-bit 4876 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4877 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4878 * 6 bits of the shift distance. 4879 */ 4880 /* shl-long vAA, vBB, vCC */ 4881 FETCH(r0, 1) @ r0<- CCBB 4882 mov r9, rINST, lsr #8 @ r9<- AA 4883 and r3, r0, #255 @ r3<- BB 4884 mov r0, r0, lsr #8 @ r0<- CC 4885 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4886 GET_VREG(r2, r0) @ r2<- vCC 4887 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4888 and r2, r2, #63 @ r2<- r2 & 0x3f 4889 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4890 4891 mov r1, r1, asl r2 @ r1<- r1 << r2 4892 rsb r3, r2, #32 @ r3<- 32 - r2 4893 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 4894 subs ip, r2, #32 @ ip<- r2 - 32 4895 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 4896 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4897 b .LOP_SHL_LONG_finish 4898 4899 /* ------------------------------ */ 4900 .balign 64 4901 .L_OP_SHR_LONG: /* 0xa4 */ 4902 /* File: armv5te/OP_SHR_LONG.S */ 4903 /* 4904 * Long integer shift. This is different from the generic 32/64-bit 4905 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4906 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4907 * 6 bits of the shift distance. 4908 */ 4909 /* shr-long vAA, vBB, vCC */ 4910 FETCH(r0, 1) @ r0<- CCBB 4911 mov r9, rINST, lsr #8 @ r9<- AA 4912 and r3, r0, #255 @ r3<- BB 4913 mov r0, r0, lsr #8 @ r0<- CC 4914 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4915 GET_VREG(r2, r0) @ r2<- vCC 4916 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4917 and r2, r2, #63 @ r0<- r0 & 0x3f 4918 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4919 4920 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4921 rsb r3, r2, #32 @ r3<- 32 - r2 4922 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4923 subs ip, r2, #32 @ ip<- r2 - 32 4924 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 4925 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4926 b .LOP_SHR_LONG_finish 4927 4928 /* ------------------------------ */ 4929 .balign 64 4930 .L_OP_USHR_LONG: /* 0xa5 */ 4931 /* File: armv5te/OP_USHR_LONG.S */ 4932 /* 4933 * Long integer shift. This is different from the generic 32/64-bit 4934 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4935 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4936 * 6 bits of the shift distance. 4937 */ 4938 /* ushr-long vAA, vBB, vCC */ 4939 FETCH(r0, 1) @ r0<- CCBB 4940 mov r9, rINST, lsr #8 @ r9<- AA 4941 and r3, r0, #255 @ r3<- BB 4942 mov r0, r0, lsr #8 @ r0<- CC 4943 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4944 GET_VREG(r2, r0) @ r2<- vCC 4945 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4946 and r2, r2, #63 @ r0<- r0 & 0x3f 4947 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4948 4949 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4950 rsb r3, r2, #32 @ r3<- 32 - r2 4951 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4952 subs ip, r2, #32 @ ip<- r2 - 32 4953 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 4954 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4955 b .LOP_USHR_LONG_finish 4956 4957 /* ------------------------------ */ 4958 .balign 64 4959 .L_OP_ADD_FLOAT: /* 0xa6 */ 4960 /* File: armv5te/OP_ADD_FLOAT.S */ 4961 /* File: armv5te/binop.S */ 4962 /* 4963 * Generic 32-bit binary operation. Provide an "instr" line that 4964 * specifies an instruction that performs "result = r0 op r1". 4965 * This could be an ARM instruction or a function call. (If the result 4966 * comes back in a register other than r0, you can override "result".) 4967 * 4968 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4969 * vCC (r1). Useful for integer division and modulus. Note that we 4970 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4971 * handles it correctly. 4972 * 4973 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4974 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4975 * mul-float, div-float, rem-float 4976 */ 4977 /* binop vAA, vBB, vCC */ 4978 FETCH(r0, 1) @ r0<- CCBB 4979 mov r9, rINST, lsr #8 @ r9<- AA 4980 mov r3, r0, lsr #8 @ r3<- CC 4981 and r2, r0, #255 @ r2<- BB 4982 GET_VREG(r1, r3) @ r1<- vCC 4983 GET_VREG(r0, r2) @ r0<- vBB 4984 .if 0 4985 cmp r1, #0 @ is second operand zero? 4986 beq common_errDivideByZero 4987 .endif 4988 4989 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4990 @ optional op; may set condition codes 4991 bl __aeabi_fadd @ r0<- op, r0-r3 changed 4992 GET_INST_OPCODE(ip) @ extract opcode from rINST 4993 SET_VREG(r0, r9) @ vAA<- r0 4994 GOTO_OPCODE(ip) @ jump to next instruction 4995 /* 11-14 instructions */ 4996 4997 4998 /* ------------------------------ */ 4999 .balign 64 5000 .L_OP_SUB_FLOAT: /* 0xa7 */ 5001 /* File: armv5te/OP_SUB_FLOAT.S */ 5002 /* File: armv5te/binop.S */ 5003 /* 5004 * Generic 32-bit binary operation. Provide an "instr" line that 5005 * specifies an instruction that performs "result = r0 op r1". 5006 * This could be an ARM instruction or a function call. (If the result 5007 * comes back in a register other than r0, you can override "result".) 5008 * 5009 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5010 * vCC (r1). Useful for integer division and modulus. Note that we 5011 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 5012 * handles it correctly. 5013 * 5014 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 5015 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 5016 * mul-float, div-float, rem-float 5017 */ 5018 /* binop vAA, vBB, vCC */ 5019 FETCH(r0, 1) @ r0<- CCBB 5020 mov r9, rINST, lsr #8 @ r9<- AA 5021 mov r3, r0, lsr #8 @ r3<- CC 5022 and r2, r0, #255 @ r2<- BB 5023 GET_VREG(r1, r3) @ r1<- vCC 5024 GET_VREG(r0, r2) @ r0<- vBB 5025 .if 0 5026 cmp r1, #0 @ is second operand zero? 5027 beq common_errDivideByZero 5028 .endif 5029 5030 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5031 @ optional op; may set condition codes 5032 bl __aeabi_fsub @ r0<- op, r0-r3 changed 5033 GET_INST_OPCODE(ip) @ extract opcode from rINST 5034 SET_VREG(r0, r9) @ vAA<- r0 5035 GOTO_OPCODE(ip) @ jump to next instruction 5036 /* 11-14 instructions */ 5037 5038 5039 /* ------------------------------ */ 5040 .balign 64 5041 .L_OP_MUL_FLOAT: /* 0xa8 */ 5042 /* File: armv5te/OP_MUL_FLOAT.S */ 5043 /* File: armv5te/binop.S */ 5044 /* 5045 * Generic 32-bit binary operation. Provide an "instr" line that 5046 * specifies an instruction that performs "result = r0 op r1". 5047 * This could be an ARM instruction or a function call. (If the result 5048 * comes back in a register other than r0, you can override "result".) 5049 * 5050 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5051 * vCC (r1). Useful for integer division and modulus. Note that we 5052 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 5053 * handles it correctly. 5054 * 5055 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 5056 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 5057 * mul-float, div-float, rem-float 5058 */ 5059 /* binop vAA, vBB, vCC */ 5060 FETCH(r0, 1) @ r0<- CCBB 5061 mov r9, rINST, lsr #8 @ r9<- AA 5062 mov r3, r0, lsr #8 @ r3<- CC 5063 and r2, r0, #255 @ r2<- BB 5064 GET_VREG(r1, r3) @ r1<- vCC 5065 GET_VREG(r0, r2) @ r0<- vBB 5066 .if 0 5067 cmp r1, #0 @ is second operand zero? 5068 beq common_errDivideByZero 5069 .endif 5070 5071 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5072 @ optional op; may set condition codes 5073 bl __aeabi_fmul @ r0<- op, r0-r3 changed 5074 GET_INST_OPCODE(ip) @ extract opcode from rINST 5075 SET_VREG(r0, r9) @ vAA<- r0 5076 GOTO_OPCODE(ip) @ jump to next instruction 5077 /* 11-14 instructions */ 5078 5079 5080 /* ------------------------------ */ 5081 .balign 64 5082 .L_OP_DIV_FLOAT: /* 0xa9 */ 5083 /* File: armv5te/OP_DIV_FLOAT.S */ 5084 /* File: armv5te/binop.S */ 5085 /* 5086 * Generic 32-bit binary operation. Provide an "instr" line that 5087 * specifies an instruction that performs "result = r0 op r1". 5088 * This could be an ARM instruction or a function call. (If the result 5089 * comes back in a register other than r0, you can override "result".) 5090 * 5091 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5092 * vCC (r1). Useful for integer division and modulus. Note that we 5093 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 5094 * handles it correctly. 5095 * 5096 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 5097 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 5098 * mul-float, div-float, rem-float 5099 */ 5100 /* binop vAA, vBB, vCC */ 5101 FETCH(r0, 1) @ r0<- CCBB 5102 mov r9, rINST, lsr #8 @ r9<- AA 5103 mov r3, r0, lsr #8 @ r3<- CC 5104 and r2, r0, #255 @ r2<- BB 5105 GET_VREG(r1, r3) @ r1<- vCC 5106 GET_VREG(r0, r2) @ r0<- vBB 5107 .if 0 5108 cmp r1, #0 @ is second operand zero? 5109 beq common_errDivideByZero 5110 .endif 5111 5112 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5113 @ optional op; may set condition codes 5114 bl __aeabi_fdiv @ r0<- op, r0-r3 changed 5115 GET_INST_OPCODE(ip) @ extract opcode from rINST 5116 SET_VREG(r0, r9) @ vAA<- r0 5117 GOTO_OPCODE(ip) @ jump to next instruction 5118 /* 11-14 instructions */ 5119 5120 5121 /* ------------------------------ */ 5122 .balign 64 5123 .L_OP_REM_FLOAT: /* 0xaa */ 5124 /* File: armv5te/OP_REM_FLOAT.S */ 5125 /* EABI doesn't define a float remainder function, but libm does */ 5126 /* File: armv5te/binop.S */ 5127 /* 5128 * Generic 32-bit binary operation. Provide an "instr" line that 5129 * specifies an instruction that performs "result = r0 op r1". 5130 * This could be an ARM instruction or a function call. (If the result 5131 * comes back in a register other than r0, you can override "result".) 5132 * 5133 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5134 * vCC (r1). Useful for integer division and modulus. Note that we 5135 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 5136 * handles it correctly. 5137 * 5138 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 5139 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 5140 * mul-float, div-float, rem-float 5141 */ 5142 /* binop vAA, vBB, vCC */ 5143 FETCH(r0, 1) @ r0<- CCBB 5144 mov r9, rINST, lsr #8 @ r9<- AA 5145 mov r3, r0, lsr #8 @ r3<- CC 5146 and r2, r0, #255 @ r2<- BB 5147 GET_VREG(r1, r3) @ r1<- vCC 5148 GET_VREG(r0, r2) @ r0<- vBB 5149 .if 0 5150 cmp r1, #0 @ is second operand zero? 5151 beq common_errDivideByZero 5152 .endif 5153 5154 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5155 @ optional op; may set condition codes 5156 bl fmodf @ r0<- op, r0-r3 changed 5157 GET_INST_OPCODE(ip) @ extract opcode from rINST 5158 SET_VREG(r0, r9) @ vAA<- r0 5159 GOTO_OPCODE(ip) @ jump to next instruction 5160 /* 11-14 instructions */ 5161 5162 5163 /* ------------------------------ */ 5164 .balign 64 5165 .L_OP_ADD_DOUBLE: /* 0xab */ 5166 /* File: armv5te/OP_ADD_DOUBLE.S */ 5167 /* File: armv5te/binopWide.S */ 5168 /* 5169 * Generic 64-bit binary operation. Provide an "instr" line that 5170 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5171 * This could be an ARM instruction or a function call. (If the result 5172 * comes back in a register other than r0, you can override "result".) 5173 * 5174 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5175 * vCC (r1). Useful for integer division and modulus. 5176 * 5177 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5178 * xor-long, add-double, sub-double, mul-double, div-double, 5179 * rem-double 5180 * 5181 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5182 */ 5183 /* binop vAA, vBB, vCC */ 5184 FETCH(r0, 1) @ r0<- CCBB 5185 mov r9, rINST, lsr #8 @ r9<- AA 5186 and r2, r0, #255 @ r2<- BB 5187 mov r3, r0, lsr #8 @ r3<- CC 5188 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5189 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5190 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5191 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5192 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5193 .if 0 5194 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5195 beq common_errDivideByZero 5196 .endif 5197 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5198 5199 @ optional op; may set condition codes 5200 bl __aeabi_dadd @ result<- op, r0-r3 changed 5201 GET_INST_OPCODE(ip) @ extract opcode from rINST 5202 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5203 GOTO_OPCODE(ip) @ jump to next instruction 5204 /* 14-17 instructions */ 5205 5206 5207 /* ------------------------------ */ 5208 .balign 64 5209 .L_OP_SUB_DOUBLE: /* 0xac */ 5210 /* File: armv5te/OP_SUB_DOUBLE.S */ 5211 /* File: armv5te/binopWide.S */ 5212 /* 5213 * Generic 64-bit binary operation. Provide an "instr" line that 5214 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5215 * This could be an ARM instruction or a function call. (If the result 5216 * comes back in a register other than r0, you can override "result".) 5217 * 5218 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5219 * vCC (r1). Useful for integer division and modulus. 5220 * 5221 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5222 * xor-long, add-double, sub-double, mul-double, div-double, 5223 * rem-double 5224 * 5225 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5226 */ 5227 /* binop vAA, vBB, vCC */ 5228 FETCH(r0, 1) @ r0<- CCBB 5229 mov r9, rINST, lsr #8 @ r9<- AA 5230 and r2, r0, #255 @ r2<- BB 5231 mov r3, r0, lsr #8 @ r3<- CC 5232 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5233 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5234 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5235 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5236 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5237 .if 0 5238 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5239 beq common_errDivideByZero 5240 .endif 5241 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5242 5243 @ optional op; may set condition codes 5244 bl __aeabi_dsub @ result<- op, r0-r3 changed 5245 GET_INST_OPCODE(ip) @ extract opcode from rINST 5246 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5247 GOTO_OPCODE(ip) @ jump to next instruction 5248 /* 14-17 instructions */ 5249 5250 5251 /* ------------------------------ */ 5252 .balign 64 5253 .L_OP_MUL_DOUBLE: /* 0xad */ 5254 /* File: armv5te/OP_MUL_DOUBLE.S */ 5255 /* File: armv5te/binopWide.S */ 5256 /* 5257 * Generic 64-bit binary operation. Provide an "instr" line that 5258 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5259 * This could be an ARM instruction or a function call. (If the result 5260 * comes back in a register other than r0, you can override "result".) 5261 * 5262 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5263 * vCC (r1). Useful for integer division and modulus. 5264 * 5265 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5266 * xor-long, add-double, sub-double, mul-double, div-double, 5267 * rem-double 5268 * 5269 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5270 */ 5271 /* binop vAA, vBB, vCC */ 5272 FETCH(r0, 1) @ r0<- CCBB 5273 mov r9, rINST, lsr #8 @ r9<- AA 5274 and r2, r0, #255 @ r2<- BB 5275 mov r3, r0, lsr #8 @ r3<- CC 5276 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5277 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5278 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5279 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5280 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5281 .if 0 5282 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5283 beq common_errDivideByZero 5284 .endif 5285 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5286 5287 @ optional op; may set condition codes 5288 bl __aeabi_dmul @ result<- op, r0-r3 changed 5289 GET_INST_OPCODE(ip) @ extract opcode from rINST 5290 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5291 GOTO_OPCODE(ip) @ jump to next instruction 5292 /* 14-17 instructions */ 5293 5294 5295 /* ------------------------------ */ 5296 .balign 64 5297 .L_OP_DIV_DOUBLE: /* 0xae */ 5298 /* File: armv5te/OP_DIV_DOUBLE.S */ 5299 /* File: armv5te/binopWide.S */ 5300 /* 5301 * Generic 64-bit binary operation. Provide an "instr" line that 5302 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5303 * This could be an ARM instruction or a function call. (If the result 5304 * comes back in a register other than r0, you can override "result".) 5305 * 5306 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5307 * vCC (r1). Useful for integer division and modulus. 5308 * 5309 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5310 * xor-long, add-double, sub-double, mul-double, div-double, 5311 * rem-double 5312 * 5313 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5314 */ 5315 /* binop vAA, vBB, vCC */ 5316 FETCH(r0, 1) @ r0<- CCBB 5317 mov r9, rINST, lsr #8 @ r9<- AA 5318 and r2, r0, #255 @ r2<- BB 5319 mov r3, r0, lsr #8 @ r3<- CC 5320 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5321 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5322 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5323 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5324 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5325 .if 0 5326 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5327 beq common_errDivideByZero 5328 .endif 5329 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5330 5331 @ optional op; may set condition codes 5332 bl __aeabi_ddiv @ result<- op, r0-r3 changed 5333 GET_INST_OPCODE(ip) @ extract opcode from rINST 5334 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5335 GOTO_OPCODE(ip) @ jump to next instruction 5336 /* 14-17 instructions */ 5337 5338 5339 /* ------------------------------ */ 5340 .balign 64 5341 .L_OP_REM_DOUBLE: /* 0xaf */ 5342 /* File: armv5te/OP_REM_DOUBLE.S */ 5343 /* EABI doesn't define a double remainder function, but libm does */ 5344 /* File: armv5te/binopWide.S */ 5345 /* 5346 * Generic 64-bit binary operation. Provide an "instr" line that 5347 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5348 * This could be an ARM instruction or a function call. (If the result 5349 * comes back in a register other than r0, you can override "result".) 5350 * 5351 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5352 * vCC (r1). Useful for integer division and modulus. 5353 * 5354 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5355 * xor-long, add-double, sub-double, mul-double, div-double, 5356 * rem-double 5357 * 5358 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5359 */ 5360 /* binop vAA, vBB, vCC */ 5361 FETCH(r0, 1) @ r0<- CCBB 5362 mov r9, rINST, lsr #8 @ r9<- AA 5363 and r2, r0, #255 @ r2<- BB 5364 mov r3, r0, lsr #8 @ r3<- CC 5365 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5366 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5367 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5368 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5369 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5370 .if 0 5371 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5372 beq common_errDivideByZero 5373 .endif 5374 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5375 5376 @ optional op; may set condition codes 5377 bl fmod @ result<- op, r0-r3 changed 5378 GET_INST_OPCODE(ip) @ extract opcode from rINST 5379 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5380 GOTO_OPCODE(ip) @ jump to next instruction 5381 /* 14-17 instructions */ 5382 5383 5384 /* ------------------------------ */ 5385 .balign 64 5386 .L_OP_ADD_INT_2ADDR: /* 0xb0 */ 5387 /* File: armv5te/OP_ADD_INT_2ADDR.S */ 5388 /* File: armv5te/binop2addr.S */ 5389 /* 5390 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5391 * that specifies an instruction that performs "result = r0 op r1". 5392 * This could be an ARM instruction or a function call. (If the result 5393 * comes back in a register other than r0, you can override "result".) 5394 * 5395 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5396 * vCC (r1). Useful for integer division and modulus. 5397 * 5398 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5399 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5400 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5401 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5402 */ 5403 /* binop/2addr vA, vB */ 5404 mov r9, rINST, lsr #8 @ r9<- A+ 5405 mov r3, rINST, lsr #12 @ r3<- B 5406 and r9, r9, #15 5407 GET_VREG(r1, r3) @ r1<- vB 5408 GET_VREG(r0, r9) @ r0<- vA 5409 .if 0 5410 cmp r1, #0 @ is second operand zero? 5411 beq common_errDivideByZero 5412 .endif 5413 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5414 5415 @ optional op; may set condition codes 5416 add r0, r0, r1 @ r0<- op, r0-r3 changed 5417 GET_INST_OPCODE(ip) @ extract opcode from rINST 5418 SET_VREG(r0, r9) @ vAA<- r0 5419 GOTO_OPCODE(ip) @ jump to next instruction 5420 /* 10-13 instructions */ 5421 5422 5423 /* ------------------------------ */ 5424 .balign 64 5425 .L_OP_SUB_INT_2ADDR: /* 0xb1 */ 5426 /* File: armv5te/OP_SUB_INT_2ADDR.S */ 5427 /* File: armv5te/binop2addr.S */ 5428 /* 5429 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5430 * that specifies an instruction that performs "result = r0 op r1". 5431 * This could be an ARM instruction or a function call. (If the result 5432 * comes back in a register other than r0, you can override "result".) 5433 * 5434 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5435 * vCC (r1). Useful for integer division and modulus. 5436 * 5437 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5438 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5439 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5440 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5441 */ 5442 /* binop/2addr vA, vB */ 5443 mov r9, rINST, lsr #8 @ r9<- A+ 5444 mov r3, rINST, lsr #12 @ r3<- B 5445 and r9, r9, #15 5446 GET_VREG(r1, r3) @ r1<- vB 5447 GET_VREG(r0, r9) @ r0<- vA 5448 .if 0 5449 cmp r1, #0 @ is second operand zero? 5450 beq common_errDivideByZero 5451 .endif 5452 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5453 5454 @ optional op; may set condition codes 5455 sub r0, r0, r1 @ r0<- op, r0-r3 changed 5456 GET_INST_OPCODE(ip) @ extract opcode from rINST 5457 SET_VREG(r0, r9) @ vAA<- r0 5458 GOTO_OPCODE(ip) @ jump to next instruction 5459 /* 10-13 instructions */ 5460 5461 5462 /* ------------------------------ */ 5463 .balign 64 5464 .L_OP_MUL_INT_2ADDR: /* 0xb2 */ 5465 /* File: armv5te/OP_MUL_INT_2ADDR.S */ 5466 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 5467 /* File: armv5te/binop2addr.S */ 5468 /* 5469 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5470 * that specifies an instruction that performs "result = r0 op r1". 5471 * This could be an ARM instruction or a function call. (If the result 5472 * comes back in a register other than r0, you can override "result".) 5473 * 5474 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5475 * vCC (r1). Useful for integer division and modulus. 5476 * 5477 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5478 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5479 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5480 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5481 */ 5482 /* binop/2addr vA, vB */ 5483 mov r9, rINST, lsr #8 @ r9<- A+ 5484 mov r3, rINST, lsr #12 @ r3<- B 5485 and r9, r9, #15 5486 GET_VREG(r1, r3) @ r1<- vB 5487 GET_VREG(r0, r9) @ r0<- vA 5488 .if 0 5489 cmp r1, #0 @ is second operand zero? 5490 beq common_errDivideByZero 5491 .endif 5492 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5493 5494 @ optional op; may set condition codes 5495 mul r0, r1, r0 @ r0<- op, r0-r3 changed 5496 GET_INST_OPCODE(ip) @ extract opcode from rINST 5497 SET_VREG(r0, r9) @ vAA<- r0 5498 GOTO_OPCODE(ip) @ jump to next instruction 5499 /* 10-13 instructions */ 5500 5501 5502 /* ------------------------------ */ 5503 .balign 64 5504 .L_OP_DIV_INT_2ADDR: /* 0xb3 */ 5505 /* File: armv5te/OP_DIV_INT_2ADDR.S */ 5506 /* File: armv5te/binop2addr.S */ 5507 /* 5508 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5509 * that specifies an instruction that performs "result = r0 op r1". 5510 * This could be an ARM instruction or a function call. (If the result 5511 * comes back in a register other than r0, you can override "result".) 5512 * 5513 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5514 * vCC (r1). Useful for integer division and modulus. 5515 * 5516 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5517 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5518 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5519 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5520 */ 5521 /* binop/2addr vA, vB */ 5522 mov r9, rINST, lsr #8 @ r9<- A+ 5523 mov r3, rINST, lsr #12 @ r3<- B 5524 and r9, r9, #15 5525 GET_VREG(r1, r3) @ r1<- vB 5526 GET_VREG(r0, r9) @ r0<- vA 5527 .if 1 5528 cmp r1, #0 @ is second operand zero? 5529 beq common_errDivideByZero 5530 .endif 5531 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5532 5533 @ optional op; may set condition codes 5534 bl __aeabi_idiv @ r0<- op, r0-r3 changed 5535 GET_INST_OPCODE(ip) @ extract opcode from rINST 5536 SET_VREG(r0, r9) @ vAA<- r0 5537 GOTO_OPCODE(ip) @ jump to next instruction 5538 /* 10-13 instructions */ 5539 5540 5541 /* ------------------------------ */ 5542 .balign 64 5543 .L_OP_REM_INT_2ADDR: /* 0xb4 */ 5544 /* File: armv5te/OP_REM_INT_2ADDR.S */ 5545 /* idivmod returns quotient in r0 and remainder in r1 */ 5546 /* File: armv5te/binop2addr.S */ 5547 /* 5548 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5549 * that specifies an instruction that performs "result = r0 op r1". 5550 * This could be an ARM instruction or a function call. (If the result 5551 * comes back in a register other than r0, you can override "result".) 5552 * 5553 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5554 * vCC (r1). Useful for integer division and modulus. 5555 * 5556 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5557 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5558 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5559 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5560 */ 5561 /* binop/2addr vA, vB */ 5562 mov r9, rINST, lsr #8 @ r9<- A+ 5563 mov r3, rINST, lsr #12 @ r3<- B 5564 and r9, r9, #15 5565 GET_VREG(r1, r3) @ r1<- vB 5566 GET_VREG(r0, r9) @ r0<- vA 5567 .if 1 5568 cmp r1, #0 @ is second operand zero? 5569 beq common_errDivideByZero 5570 .endif 5571 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5572 5573 @ optional op; may set condition codes 5574 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 5575 GET_INST_OPCODE(ip) @ extract opcode from rINST 5576 SET_VREG(r1, r9) @ vAA<- r1 5577 GOTO_OPCODE(ip) @ jump to next instruction 5578 /* 10-13 instructions */ 5579 5580 5581 /* ------------------------------ */ 5582 .balign 64 5583 .L_OP_AND_INT_2ADDR: /* 0xb5 */ 5584 /* File: armv5te/OP_AND_INT_2ADDR.S */ 5585 /* File: armv5te/binop2addr.S */ 5586 /* 5587 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5588 * that specifies an instruction that performs "result = r0 op r1". 5589 * This could be an ARM instruction or a function call. (If the result 5590 * comes back in a register other than r0, you can override "result".) 5591 * 5592 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5593 * vCC (r1). Useful for integer division and modulus. 5594 * 5595 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5596 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5597 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5598 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5599 */ 5600 /* binop/2addr vA, vB */ 5601 mov r9, rINST, lsr #8 @ r9<- A+ 5602 mov r3, rINST, lsr #12 @ r3<- B 5603 and r9, r9, #15 5604 GET_VREG(r1, r3) @ r1<- vB 5605 GET_VREG(r0, r9) @ r0<- vA 5606 .if 0 5607 cmp r1, #0 @ is second operand zero? 5608 beq common_errDivideByZero 5609 .endif 5610 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5611 5612 @ optional op; may set condition codes 5613 and r0, r0, r1 @ r0<- op, r0-r3 changed 5614 GET_INST_OPCODE(ip) @ extract opcode from rINST 5615 SET_VREG(r0, r9) @ vAA<- r0 5616 GOTO_OPCODE(ip) @ jump to next instruction 5617 /* 10-13 instructions */ 5618 5619 5620 /* ------------------------------ */ 5621 .balign 64 5622 .L_OP_OR_INT_2ADDR: /* 0xb6 */ 5623 /* File: armv5te/OP_OR_INT_2ADDR.S */ 5624 /* File: armv5te/binop2addr.S */ 5625 /* 5626 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5627 * that specifies an instruction that performs "result = r0 op r1". 5628 * This could be an ARM instruction or a function call. (If the result 5629 * comes back in a register other than r0, you can override "result".) 5630 * 5631 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5632 * vCC (r1). Useful for integer division and modulus. 5633 * 5634 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5635 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5636 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5637 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5638 */ 5639 /* binop/2addr vA, vB */ 5640 mov r9, rINST, lsr #8 @ r9<- A+ 5641 mov r3, rINST, lsr #12 @ r3<- B 5642 and r9, r9, #15 5643 GET_VREG(r1, r3) @ r1<- vB 5644 GET_VREG(r0, r9) @ r0<- vA 5645 .if 0 5646 cmp r1, #0 @ is second operand zero? 5647 beq common_errDivideByZero 5648 .endif 5649 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5650 5651 @ optional op; may set condition codes 5652 orr r0, r0, r1 @ r0<- op, r0-r3 changed 5653 GET_INST_OPCODE(ip) @ extract opcode from rINST 5654 SET_VREG(r0, r9) @ vAA<- r0 5655 GOTO_OPCODE(ip) @ jump to next instruction 5656 /* 10-13 instructions */ 5657 5658 5659 /* ------------------------------ */ 5660 .balign 64 5661 .L_OP_XOR_INT_2ADDR: /* 0xb7 */ 5662 /* File: armv5te/OP_XOR_INT_2ADDR.S */ 5663 /* File: armv5te/binop2addr.S */ 5664 /* 5665 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5666 * that specifies an instruction that performs "result = r0 op r1". 5667 * This could be an ARM instruction or a function call. (If the result 5668 * comes back in a register other than r0, you can override "result".) 5669 * 5670 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5671 * vCC (r1). Useful for integer division and modulus. 5672 * 5673 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5674 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5675 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5676 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5677 */ 5678 /* binop/2addr vA, vB */ 5679 mov r9, rINST, lsr #8 @ r9<- A+ 5680 mov r3, rINST, lsr #12 @ r3<- B 5681 and r9, r9, #15 5682 GET_VREG(r1, r3) @ r1<- vB 5683 GET_VREG(r0, r9) @ r0<- vA 5684 .if 0 5685 cmp r1, #0 @ is second operand zero? 5686 beq common_errDivideByZero 5687 .endif 5688 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5689 5690 @ optional op; may set condition codes 5691 eor r0, r0, r1 @ r0<- op, r0-r3 changed 5692 GET_INST_OPCODE(ip) @ extract opcode from rINST 5693 SET_VREG(r0, r9) @ vAA<- r0 5694 GOTO_OPCODE(ip) @ jump to next instruction 5695 /* 10-13 instructions */ 5696 5697 5698 /* ------------------------------ */ 5699 .balign 64 5700 .L_OP_SHL_INT_2ADDR: /* 0xb8 */ 5701 /* File: armv5te/OP_SHL_INT_2ADDR.S */ 5702 /* File: armv5te/binop2addr.S */ 5703 /* 5704 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5705 * that specifies an instruction that performs "result = r0 op r1". 5706 * This could be an ARM instruction or a function call. (If the result 5707 * comes back in a register other than r0, you can override "result".) 5708 * 5709 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5710 * vCC (r1). Useful for integer division and modulus. 5711 * 5712 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5713 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5714 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5715 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5716 */ 5717 /* binop/2addr vA, vB */ 5718 mov r9, rINST, lsr #8 @ r9<- A+ 5719 mov r3, rINST, lsr #12 @ r3<- B 5720 and r9, r9, #15 5721 GET_VREG(r1, r3) @ r1<- vB 5722 GET_VREG(r0, r9) @ r0<- vA 5723 .if 0 5724 cmp r1, #0 @ is second operand zero? 5725 beq common_errDivideByZero 5726 .endif 5727 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5728 5729 and r1, r1, #31 @ optional op; may set condition codes 5730 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 5731 GET_INST_OPCODE(ip) @ extract opcode from rINST 5732 SET_VREG(r0, r9) @ vAA<- r0 5733 GOTO_OPCODE(ip) @ jump to next instruction 5734 /* 10-13 instructions */ 5735 5736 5737 /* ------------------------------ */ 5738 .balign 64 5739 .L_OP_SHR_INT_2ADDR: /* 0xb9 */ 5740 /* File: armv5te/OP_SHR_INT_2ADDR.S */ 5741 /* File: armv5te/binop2addr.S */ 5742 /* 5743 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5744 * that specifies an instruction that performs "result = r0 op r1". 5745 * This could be an ARM instruction or a function call. (If the result 5746 * comes back in a register other than r0, you can override "result".) 5747 * 5748 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5749 * vCC (r1). Useful for integer division and modulus. 5750 * 5751 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5752 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5753 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5754 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5755 */ 5756 /* binop/2addr vA, vB */ 5757 mov r9, rINST, lsr #8 @ r9<- A+ 5758 mov r3, rINST, lsr #12 @ r3<- B 5759 and r9, r9, #15 5760 GET_VREG(r1, r3) @ r1<- vB 5761 GET_VREG(r0, r9) @ r0<- vA 5762 .if 0 5763 cmp r1, #0 @ is second operand zero? 5764 beq common_errDivideByZero 5765 .endif 5766 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5767 5768 and r1, r1, #31 @ optional op; may set condition codes 5769 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 5770 GET_INST_OPCODE(ip) @ extract opcode from rINST 5771 SET_VREG(r0, r9) @ vAA<- r0 5772 GOTO_OPCODE(ip) @ jump to next instruction 5773 /* 10-13 instructions */ 5774 5775 5776 /* ------------------------------ */ 5777 .balign 64 5778 .L_OP_USHR_INT_2ADDR: /* 0xba */ 5779 /* File: armv5te/OP_USHR_INT_2ADDR.S */ 5780 /* File: armv5te/binop2addr.S */ 5781 /* 5782 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5783 * that specifies an instruction that performs "result = r0 op r1". 5784 * This could be an ARM instruction or a function call. (If the result 5785 * comes back in a register other than r0, you can override "result".) 5786 * 5787 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5788 * vCC (r1). Useful for integer division and modulus. 5789 * 5790 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5791 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5792 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5793 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5794 */ 5795 /* binop/2addr vA, vB */ 5796 mov r9, rINST, lsr #8 @ r9<- A+ 5797 mov r3, rINST, lsr #12 @ r3<- B 5798 and r9, r9, #15 5799 GET_VREG(r1, r3) @ r1<- vB 5800 GET_VREG(r0, r9) @ r0<- vA 5801 .if 0 5802 cmp r1, #0 @ is second operand zero? 5803 beq common_errDivideByZero 5804 .endif 5805 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5806 5807 and r1, r1, #31 @ optional op; may set condition codes 5808 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 5809 GET_INST_OPCODE(ip) @ extract opcode from rINST 5810 SET_VREG(r0, r9) @ vAA<- r0 5811 GOTO_OPCODE(ip) @ jump to next instruction 5812 /* 10-13 instructions */ 5813 5814 5815 /* ------------------------------ */ 5816 .balign 64 5817 .L_OP_ADD_LONG_2ADDR: /* 0xbb */ 5818 /* File: armv5te/OP_ADD_LONG_2ADDR.S */ 5819 /* File: armv5te/binopWide2addr.S */ 5820 /* 5821 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5822 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5823 * This could be an ARM instruction or a function call. (If the result 5824 * comes back in a register other than r0, you can override "result".) 5825 * 5826 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5827 * vCC (r1). Useful for integer division and modulus. 5828 * 5829 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5830 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5831 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5832 * rem-double/2addr 5833 */ 5834 /* binop/2addr vA, vB */ 5835 mov r9, rINST, lsr #8 @ r9<- A+ 5836 mov r1, rINST, lsr #12 @ r1<- B 5837 and r9, r9, #15 5838 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5839 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5840 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5841 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5842 .if 0 5843 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5844 beq common_errDivideByZero 5845 .endif 5846 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5847 5848 adds r0, r0, r2 @ optional op; may set condition codes 5849 adc r1, r1, r3 @ result<- op, r0-r3 changed 5850 GET_INST_OPCODE(ip) @ extract opcode from rINST 5851 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5852 GOTO_OPCODE(ip) @ jump to next instruction 5853 /* 12-15 instructions */ 5854 5855 5856 /* ------------------------------ */ 5857 .balign 64 5858 .L_OP_SUB_LONG_2ADDR: /* 0xbc */ 5859 /* File: armv5te/OP_SUB_LONG_2ADDR.S */ 5860 /* File: armv5te/binopWide2addr.S */ 5861 /* 5862 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5863 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5864 * This could be an ARM instruction or a function call. (If the result 5865 * comes back in a register other than r0, you can override "result".) 5866 * 5867 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5868 * vCC (r1). Useful for integer division and modulus. 5869 * 5870 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5871 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5872 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5873 * rem-double/2addr 5874 */ 5875 /* binop/2addr vA, vB */ 5876 mov r9, rINST, lsr #8 @ r9<- A+ 5877 mov r1, rINST, lsr #12 @ r1<- B 5878 and r9, r9, #15 5879 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5880 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5881 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5882 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5883 .if 0 5884 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5885 beq common_errDivideByZero 5886 .endif 5887 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5888 5889 subs r0, r0, r2 @ optional op; may set condition codes 5890 sbc r1, r1, r3 @ result<- op, r0-r3 changed 5891 GET_INST_OPCODE(ip) @ extract opcode from rINST 5892 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5893 GOTO_OPCODE(ip) @ jump to next instruction 5894 /* 12-15 instructions */ 5895 5896 5897 /* ------------------------------ */ 5898 .balign 64 5899 .L_OP_MUL_LONG_2ADDR: /* 0xbd */ 5900 /* File: armv5te/OP_MUL_LONG_2ADDR.S */ 5901 /* 5902 * Signed 64-bit integer multiply, "/2addr" version. 5903 * 5904 * See OP_MUL_LONG for an explanation. 5905 * 5906 * We get a little tight on registers, so to avoid looking up &fp[A] 5907 * again we stuff it into rINST. 5908 */ 5909 /* mul-long/2addr vA, vB */ 5910 mov r9, rINST, lsr #8 @ r9<- A+ 5911 mov r1, rINST, lsr #12 @ r1<- B 5912 and r9, r9, #15 5913 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5914 add rINST, rFP, r9, lsl #2 @ rINST<- &fp[A] 5915 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5916 ldmia rINST, {r0-r1} @ r0/r1<- vAA/vAA+1 5917 mul ip, r2, r1 @ ip<- ZxW 5918 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 5919 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 5920 mov r0, rINST @ r0<- &fp[A] (free up rINST) 5921 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5922 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 5923 GET_INST_OPCODE(ip) @ extract opcode from rINST 5924 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 5925 GOTO_OPCODE(ip) @ jump to next instruction 5926 5927 /* ------------------------------ */ 5928 .balign 64 5929 .L_OP_DIV_LONG_2ADDR: /* 0xbe */ 5930 /* File: armv5te/OP_DIV_LONG_2ADDR.S */ 5931 /* File: armv5te/binopWide2addr.S */ 5932 /* 5933 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5934 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5935 * This could be an ARM instruction or a function call. (If the result 5936 * comes back in a register other than r0, you can override "result".) 5937 * 5938 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5939 * vCC (r1). Useful for integer division and modulus. 5940 * 5941 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5942 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5943 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5944 * rem-double/2addr 5945 */ 5946 /* binop/2addr vA, vB */ 5947 mov r9, rINST, lsr #8 @ r9<- A+ 5948 mov r1, rINST, lsr #12 @ r1<- B 5949 and r9, r9, #15 5950 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5951 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5952 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5953 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5954 .if 1 5955 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5956 beq common_errDivideByZero 5957 .endif 5958 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5959 5960 @ optional op; may set condition codes 5961 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5962 GET_INST_OPCODE(ip) @ extract opcode from rINST 5963 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5964 GOTO_OPCODE(ip) @ jump to next instruction 5965 /* 12-15 instructions */ 5966 5967 5968 /* ------------------------------ */ 5969 .balign 64 5970 .L_OP_REM_LONG_2ADDR: /* 0xbf */ 5971 /* File: armv5te/OP_REM_LONG_2ADDR.S */ 5972 /* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 5973 /* File: armv5te/binopWide2addr.S */ 5974 /* 5975 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5976 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5977 * This could be an ARM instruction or a function call. (If the result 5978 * comes back in a register other than r0, you can override "result".) 5979 * 5980 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5981 * vCC (r1). Useful for integer division and modulus. 5982 * 5983 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5984 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5985 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5986 * rem-double/2addr 5987 */ 5988 /* binop/2addr vA, vB */ 5989 mov r9, rINST, lsr #8 @ r9<- A+ 5990 mov r1, rINST, lsr #12 @ r1<- B 5991 and r9, r9, #15 5992 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5993 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5994 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5995 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5996 .if 1 5997 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5998 beq common_errDivideByZero 5999 .endif 6000 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6001 6002 @ optional op; may set condition codes 6003 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 6004 GET_INST_OPCODE(ip) @ extract opcode from rINST 6005 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 6006 GOTO_OPCODE(ip) @ jump to next instruction 6007 /* 12-15 instructions */ 6008 6009 6010 /* ------------------------------ */ 6011 .balign 64 6012 .L_OP_AND_LONG_2ADDR: /* 0xc0 */ 6013 /* File: armv5te/OP_AND_LONG_2ADDR.S */ 6014 /* File: armv5te/binopWide2addr.S */ 6015 /* 6016 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6017 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6018 * This could be an ARM instruction or a function call. (If the result 6019 * comes back in a register other than r0, you can override "result".) 6020 * 6021 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6022 * vCC (r1). Useful for integer division and modulus. 6023 * 6024 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6025 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6026 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6027 * rem-double/2addr 6028 */ 6029 /* binop/2addr vA, vB */ 6030 mov r9, rINST, lsr #8 @ r9<- A+ 6031 mov r1, rINST, lsr #12 @ r1<- B 6032 and r9, r9, #15 6033 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6034 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6035 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6036 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6037 .if 0 6038 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6039 beq common_errDivideByZero 6040 .endif 6041 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6042 6043 and r0, r0, r2 @ optional op; may set condition codes 6044 and r1, r1, r3 @ result<- op, r0-r3 changed 6045 GET_INST_OPCODE(ip) @ extract opcode from rINST 6046 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6047 GOTO_OPCODE(ip) @ jump to next instruction 6048 /* 12-15 instructions */ 6049 6050 6051 /* ------------------------------ */ 6052 .balign 64 6053 .L_OP_OR_LONG_2ADDR: /* 0xc1 */ 6054 /* File: armv5te/OP_OR_LONG_2ADDR.S */ 6055 /* File: armv5te/binopWide2addr.S */ 6056 /* 6057 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6058 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6059 * This could be an ARM instruction or a function call. (If the result 6060 * comes back in a register other than r0, you can override "result".) 6061 * 6062 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6063 * vCC (r1). Useful for integer division and modulus. 6064 * 6065 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6066 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6067 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6068 * rem-double/2addr 6069 */ 6070 /* binop/2addr vA, vB */ 6071 mov r9, rINST, lsr #8 @ r9<- A+ 6072 mov r1, rINST, lsr #12 @ r1<- B 6073 and r9, r9, #15 6074 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6075 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6076 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6077 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6078 .if 0 6079 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6080 beq common_errDivideByZero 6081 .endif 6082 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6083 6084 orr r0, r0, r2 @ optional op; may set condition codes 6085 orr r1, r1, r3 @ result<- op, r0-r3 changed 6086 GET_INST_OPCODE(ip) @ extract opcode from rINST 6087 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6088 GOTO_OPCODE(ip) @ jump to next instruction 6089 /* 12-15 instructions */ 6090 6091 6092 /* ------------------------------ */ 6093 .balign 64 6094 .L_OP_XOR_LONG_2ADDR: /* 0xc2 */ 6095 /* File: armv5te/OP_XOR_LONG_2ADDR.S */ 6096 /* File: armv5te/binopWide2addr.S */ 6097 /* 6098 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6099 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6100 * This could be an ARM instruction or a function call. (If the result 6101 * comes back in a register other than r0, you can override "result".) 6102 * 6103 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6104 * vCC (r1). Useful for integer division and modulus. 6105 * 6106 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6107 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6108 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6109 * rem-double/2addr 6110 */ 6111 /* binop/2addr vA, vB */ 6112 mov r9, rINST, lsr #8 @ r9<- A+ 6113 mov r1, rINST, lsr #12 @ r1<- B 6114 and r9, r9, #15 6115 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6116 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6117 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6118 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6119 .if 0 6120 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6121 beq common_errDivideByZero 6122 .endif 6123 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6124 6125 eor r0, r0, r2 @ optional op; may set condition codes 6126 eor r1, r1, r3 @ result<- op, r0-r3 changed 6127 GET_INST_OPCODE(ip) @ extract opcode from rINST 6128 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6129 GOTO_OPCODE(ip) @ jump to next instruction 6130 /* 12-15 instructions */ 6131 6132 6133 /* ------------------------------ */ 6134 .balign 64 6135 .L_OP_SHL_LONG_2ADDR: /* 0xc3 */ 6136 /* File: armv5te/OP_SHL_LONG_2ADDR.S */ 6137 /* 6138 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6139 * 32-bit shift distance. 6140 */ 6141 /* shl-long/2addr vA, vB */ 6142 mov r9, rINST, lsr #8 @ r9<- A+ 6143 mov r3, rINST, lsr #12 @ r3<- B 6144 and r9, r9, #15 6145 GET_VREG(r2, r3) @ r2<- vB 6146 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6147 and r2, r2, #63 @ r2<- r2 & 0x3f 6148 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6149 6150 mov r1, r1, asl r2 @ r1<- r1 << r2 6151 rsb r3, r2, #32 @ r3<- 32 - r2 6152 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 6153 subs ip, r2, #32 @ ip<- r2 - 32 6154 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6155 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 6156 mov r0, r0, asl r2 @ r0<- r0 << r2 6157 b .LOP_SHL_LONG_2ADDR_finish 6158 6159 /* ------------------------------ */ 6160 .balign 64 6161 .L_OP_SHR_LONG_2ADDR: /* 0xc4 */ 6162 /* File: armv5te/OP_SHR_LONG_2ADDR.S */ 6163 /* 6164 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6165 * 32-bit shift distance. 6166 */ 6167 /* shr-long/2addr vA, vB */ 6168 mov r9, rINST, lsr #8 @ r9<- A+ 6169 mov r3, rINST, lsr #12 @ r3<- B 6170 and r9, r9, #15 6171 GET_VREG(r2, r3) @ r2<- vB 6172 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6173 and r2, r2, #63 @ r2<- r2 & 0x3f 6174 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6175 6176 mov r0, r0, lsr r2 @ r0<- r2 >> r2 6177 rsb r3, r2, #32 @ r3<- 32 - r2 6178 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 6179 subs ip, r2, #32 @ ip<- r2 - 32 6180 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6181 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 6182 mov r1, r1, asr r2 @ r1<- r1 >> r2 6183 b .LOP_SHR_LONG_2ADDR_finish 6184 6185 /* ------------------------------ */ 6186 .balign 64 6187 .L_OP_USHR_LONG_2ADDR: /* 0xc5 */ 6188 /* File: armv5te/OP_USHR_LONG_2ADDR.S */ 6189 /* 6190 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6191 * 32-bit shift distance. 6192 */ 6193 /* ushr-long/2addr vA, vB */ 6194 mov r9, rINST, lsr #8 @ r9<- A+ 6195 mov r3, rINST, lsr #12 @ r3<- B 6196 and r9, r9, #15 6197 GET_VREG(r2, r3) @ r2<- vB 6198 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6199 and r2, r2, #63 @ r2<- r2 & 0x3f 6200 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6201 6202 mov r0, r0, lsr r2 @ r0<- r2 >> r2 6203 rsb r3, r2, #32 @ r3<- 32 - r2 6204 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 6205 subs ip, r2, #32 @ ip<- r2 - 32 6206 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6207 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 6208 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 6209 b .LOP_USHR_LONG_2ADDR_finish 6210 6211 /* ------------------------------ */ 6212 .balign 64 6213 .L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 6214 /* File: armv5te/OP_ADD_FLOAT_2ADDR.S */ 6215 /* File: armv5te/binop2addr.S */ 6216 /* 6217 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6218 * that specifies an instruction that performs "result = r0 op r1". 6219 * This could be an ARM instruction or a function call. (If the result 6220 * comes back in a register other than r0, you can override "result".) 6221 * 6222 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6223 * vCC (r1). Useful for integer division and modulus. 6224 * 6225 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6226 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6227 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6228 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6229 */ 6230 /* binop/2addr vA, vB */ 6231 mov r9, rINST, lsr #8 @ r9<- A+ 6232 mov r3, rINST, lsr #12 @ r3<- B 6233 and r9, r9, #15 6234 GET_VREG(r1, r3) @ r1<- vB 6235 GET_VREG(r0, r9) @ r0<- vA 6236 .if 0 6237 cmp r1, #0 @ is second operand zero? 6238 beq common_errDivideByZero 6239 .endif 6240 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6241 6242 @ optional op; may set condition codes 6243 bl __aeabi_fadd @ r0<- op, r0-r3 changed 6244 GET_INST_OPCODE(ip) @ extract opcode from rINST 6245 SET_VREG(r0, r9) @ vAA<- r0 6246 GOTO_OPCODE(ip) @ jump to next instruction 6247 /* 10-13 instructions */ 6248 6249 6250 /* ------------------------------ */ 6251 .balign 64 6252 .L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 6253 /* File: armv5te/OP_SUB_FLOAT_2ADDR.S */ 6254 /* File: armv5te/binop2addr.S */ 6255 /* 6256 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6257 * that specifies an instruction that performs "result = r0 op r1". 6258 * This could be an ARM instruction or a function call. (If the result 6259 * comes back in a register other than r0, you can override "result".) 6260 * 6261 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6262 * vCC (r1). Useful for integer division and modulus. 6263 * 6264 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6265 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6266 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6267 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6268 */ 6269 /* binop/2addr vA, vB */ 6270 mov r9, rINST, lsr #8 @ r9<- A+ 6271 mov r3, rINST, lsr #12 @ r3<- B 6272 and r9, r9, #15 6273 GET_VREG(r1, r3) @ r1<- vB 6274 GET_VREG(r0, r9) @ r0<- vA 6275 .if 0 6276 cmp r1, #0 @ is second operand zero? 6277 beq common_errDivideByZero 6278 .endif 6279 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6280 6281 @ optional op; may set condition codes 6282 bl __aeabi_fsub @ r0<- op, r0-r3 changed 6283 GET_INST_OPCODE(ip) @ extract opcode from rINST 6284 SET_VREG(r0, r9) @ vAA<- r0 6285 GOTO_OPCODE(ip) @ jump to next instruction 6286 /* 10-13 instructions */ 6287 6288 6289 /* ------------------------------ */ 6290 .balign 64 6291 .L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 6292 /* File: armv5te/OP_MUL_FLOAT_2ADDR.S */ 6293 /* File: armv5te/binop2addr.S */ 6294 /* 6295 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6296 * that specifies an instruction that performs "result = r0 op r1". 6297 * This could be an ARM instruction or a function call. (If the result 6298 * comes back in a register other than r0, you can override "result".) 6299 * 6300 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6301 * vCC (r1). Useful for integer division and modulus. 6302 * 6303 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6304 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6305 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6306 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6307 */ 6308 /* binop/2addr vA, vB */ 6309 mov r9, rINST, lsr #8 @ r9<- A+ 6310 mov r3, rINST, lsr #12 @ r3<- B 6311 and r9, r9, #15 6312 GET_VREG(r1, r3) @ r1<- vB 6313 GET_VREG(r0, r9) @ r0<- vA 6314 .if 0 6315 cmp r1, #0 @ is second operand zero? 6316 beq common_errDivideByZero 6317 .endif 6318 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6319 6320 @ optional op; may set condition codes 6321 bl __aeabi_fmul @ 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_DIV_FLOAT_2ADDR: /* 0xc9 */ 6331 /* File: armv5te/OP_DIV_FLOAT_2ADDR.S */ 6332 /* File: armv5te/binop2addr.S */ 6333 /* 6334 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6335 * that specifies an instruction that performs "result = r0 op r1". 6336 * This could be an ARM instruction or a function call. (If the result 6337 * comes back in a register other than r0, you can override "result".) 6338 * 6339 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6340 * vCC (r1). Useful for integer division and modulus. 6341 * 6342 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6343 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6344 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6345 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6346 */ 6347 /* binop/2addr vA, vB */ 6348 mov r9, rINST, lsr #8 @ r9<- A+ 6349 mov r3, rINST, lsr #12 @ r3<- B 6350 and r9, r9, #15 6351 GET_VREG(r1, r3) @ r1<- vB 6352 GET_VREG(r0, r9) @ r0<- vA 6353 .if 0 6354 cmp r1, #0 @ is second operand zero? 6355 beq common_errDivideByZero 6356 .endif 6357 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6358 6359 @ optional op; may set condition codes 6360 bl __aeabi_fdiv @ r0<- op, r0-r3 changed 6361 GET_INST_OPCODE(ip) @ extract opcode from rINST 6362 SET_VREG(r0, r9) @ vAA<- r0 6363 GOTO_OPCODE(ip) @ jump to next instruction 6364 /* 10-13 instructions */ 6365 6366 6367 /* ------------------------------ */ 6368 .balign 64 6369 .L_OP_REM_FLOAT_2ADDR: /* 0xca */ 6370 /* File: armv5te/OP_REM_FLOAT_2ADDR.S */ 6371 /* EABI doesn't define a float remainder function, but libm does */ 6372 /* File: armv5te/binop2addr.S */ 6373 /* 6374 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6375 * that specifies an instruction that performs "result = r0 op r1". 6376 * This could be an ARM instruction or a function call. (If the result 6377 * comes back in a register other than r0, you can override "result".) 6378 * 6379 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6380 * vCC (r1). Useful for integer division and modulus. 6381 * 6382 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6383 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6384 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6385 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6386 */ 6387 /* binop/2addr vA, vB */ 6388 mov r9, rINST, lsr #8 @ r9<- A+ 6389 mov r3, rINST, lsr #12 @ r3<- B 6390 and r9, r9, #15 6391 GET_VREG(r1, r3) @ r1<- vB 6392 GET_VREG(r0, r9) @ r0<- vA 6393 .if 0 6394 cmp r1, #0 @ is second operand zero? 6395 beq common_errDivideByZero 6396 .endif 6397 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6398 6399 @ optional op; may set condition codes 6400 bl fmodf @ r0<- op, r0-r3 changed 6401 GET_INST_OPCODE(ip) @ extract opcode from rINST 6402 SET_VREG(r0, r9) @ vAA<- r0 6403 GOTO_OPCODE(ip) @ jump to next instruction 6404 /* 10-13 instructions */ 6405 6406 6407 /* ------------------------------ */ 6408 .balign 64 6409 .L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 6410 /* File: armv5te/OP_ADD_DOUBLE_2ADDR.S */ 6411 /* File: armv5te/binopWide2addr.S */ 6412 /* 6413 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6414 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6415 * This could be an ARM instruction or a function call. (If the result 6416 * comes back in a register other than r0, you can override "result".) 6417 * 6418 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6419 * vCC (r1). Useful for integer division and modulus. 6420 * 6421 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6422 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6423 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6424 * rem-double/2addr 6425 */ 6426 /* binop/2addr vA, vB */ 6427 mov r9, rINST, lsr #8 @ r9<- A+ 6428 mov r1, rINST, lsr #12 @ r1<- B 6429 and r9, r9, #15 6430 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6431 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6432 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6433 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6434 .if 0 6435 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6436 beq common_errDivideByZero 6437 .endif 6438 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6439 6440 @ optional op; may set condition codes 6441 bl __aeabi_dadd @ result<- op, r0-r3 changed 6442 GET_INST_OPCODE(ip) @ extract opcode from rINST 6443 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6444 GOTO_OPCODE(ip) @ jump to next instruction 6445 /* 12-15 instructions */ 6446 6447 6448 /* ------------------------------ */ 6449 .balign 64 6450 .L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 6451 /* File: armv5te/OP_SUB_DOUBLE_2ADDR.S */ 6452 /* File: armv5te/binopWide2addr.S */ 6453 /* 6454 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6455 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6456 * This could be an ARM instruction or a function call. (If the result 6457 * comes back in a register other than r0, you can override "result".) 6458 * 6459 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6460 * vCC (r1). Useful for integer division and modulus. 6461 * 6462 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6463 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6464 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6465 * rem-double/2addr 6466 */ 6467 /* binop/2addr vA, vB */ 6468 mov r9, rINST, lsr #8 @ r9<- A+ 6469 mov r1, rINST, lsr #12 @ r1<- B 6470 and r9, r9, #15 6471 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6472 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6473 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6474 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6475 .if 0 6476 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6477 beq common_errDivideByZero 6478 .endif 6479 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6480 6481 @ optional op; may set condition codes 6482 bl __aeabi_dsub @ result<- op, r0-r3 changed 6483 GET_INST_OPCODE(ip) @ extract opcode from rINST 6484 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6485 GOTO_OPCODE(ip) @ jump to next instruction 6486 /* 12-15 instructions */ 6487 6488 6489 /* ------------------------------ */ 6490 .balign 64 6491 .L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 6492 /* File: armv5te/OP_MUL_DOUBLE_2ADDR.S */ 6493 /* File: armv5te/binopWide2addr.S */ 6494 /* 6495 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6496 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6497 * This could be an ARM instruction or a function call. (If the result 6498 * comes back in a register other than r0, you can override "result".) 6499 * 6500 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6501 * vCC (r1). Useful for integer division and modulus. 6502 * 6503 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6504 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6505 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6506 * rem-double/2addr 6507 */ 6508 /* binop/2addr vA, vB */ 6509 mov r9, rINST, lsr #8 @ r9<- A+ 6510 mov r1, rINST, lsr #12 @ r1<- B 6511 and r9, r9, #15 6512 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6513 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6514 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6515 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6516 .if 0 6517 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6518 beq common_errDivideByZero 6519 .endif 6520 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6521 6522 @ optional op; may set condition codes 6523 bl __aeabi_dmul @ result<- op, r0-r3 changed 6524 GET_INST_OPCODE(ip) @ extract opcode from rINST 6525 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6526 GOTO_OPCODE(ip) @ jump to next instruction 6527 /* 12-15 instructions */ 6528 6529 6530 /* ------------------------------ */ 6531 .balign 64 6532 .L_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 6533 /* File: armv5te/OP_DIV_DOUBLE_2ADDR.S */ 6534 /* File: armv5te/binopWide2addr.S */ 6535 /* 6536 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6537 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6538 * This could be an ARM instruction or a function call. (If the result 6539 * comes back in a register other than r0, you can override "result".) 6540 * 6541 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6542 * vCC (r1). Useful for integer division and modulus. 6543 * 6544 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6545 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6546 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6547 * rem-double/2addr 6548 */ 6549 /* binop/2addr vA, vB */ 6550 mov r9, rINST, lsr #8 @ r9<- A+ 6551 mov r1, rINST, lsr #12 @ r1<- B 6552 and r9, r9, #15 6553 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6554 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6555 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6556 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6557 .if 0 6558 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6559 beq common_errDivideByZero 6560 .endif 6561 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6562 6563 @ optional op; may set condition codes 6564 bl __aeabi_ddiv @ result<- op, r0-r3 changed 6565 GET_INST_OPCODE(ip) @ extract opcode from rINST 6566 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6567 GOTO_OPCODE(ip) @ jump to next instruction 6568 /* 12-15 instructions */ 6569 6570 6571 /* ------------------------------ */ 6572 .balign 64 6573 .L_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 6574 /* File: armv5te/OP_REM_DOUBLE_2ADDR.S */ 6575 /* EABI doesn't define a double remainder function, but libm does */ 6576 /* File: armv5te/binopWide2addr.S */ 6577 /* 6578 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6579 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6580 * This could be an ARM instruction or a function call. (If the result 6581 * comes back in a register other than r0, you can override "result".) 6582 * 6583 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6584 * vCC (r1). Useful for integer division and modulus. 6585 * 6586 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6587 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6588 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6589 * rem-double/2addr 6590 */ 6591 /* binop/2addr vA, vB */ 6592 mov r9, rINST, lsr #8 @ r9<- A+ 6593 mov r1, rINST, lsr #12 @ r1<- B 6594 and r9, r9, #15 6595 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6596 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6597 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6598 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6599 .if 0 6600 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6601 beq common_errDivideByZero 6602 .endif 6603 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6604 6605 @ optional op; may set condition codes 6606 bl fmod @ result<- op, r0-r3 changed 6607 GET_INST_OPCODE(ip) @ extract opcode from rINST 6608 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6609 GOTO_OPCODE(ip) @ jump to next instruction 6610 /* 12-15 instructions */ 6611 6612 6613 /* ------------------------------ */ 6614 .balign 64 6615 .L_OP_ADD_INT_LIT16: /* 0xd0 */ 6616 /* File: armv5te/OP_ADD_INT_LIT16.S */ 6617 /* File: armv5te/binopLit16.S */ 6618 /* 6619 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6620 * that specifies an instruction that performs "result = r0 op r1". 6621 * This could be an ARM instruction or a function call. (If the result 6622 * comes back in a register other than r0, you can override "result".) 6623 * 6624 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6625 * vCC (r1). Useful for integer division and modulus. 6626 * 6627 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6628 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6629 */ 6630 /* binop/lit16 vA, vB, #+CCCC */ 6631 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6632 mov r2, rINST, lsr #12 @ r2<- B 6633 mov r9, rINST, lsr #8 @ r9<- A+ 6634 GET_VREG(r0, r2) @ r0<- vB 6635 and r9, r9, #15 6636 .if 0 6637 cmp r1, #0 @ is second operand zero? 6638 beq common_errDivideByZero 6639 .endif 6640 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6641 6642 add r0, r0, r1 @ r0<- op, r0-r3 changed 6643 GET_INST_OPCODE(ip) @ extract opcode from rINST 6644 SET_VREG(r0, r9) @ vAA<- r0 6645 GOTO_OPCODE(ip) @ jump to next instruction 6646 /* 10-13 instructions */ 6647 6648 6649 /* ------------------------------ */ 6650 .balign 64 6651 .L_OP_RSUB_INT: /* 0xd1 */ 6652 /* File: armv5te/OP_RSUB_INT.S */ 6653 /* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */ 6654 /* File: armv5te/binopLit16.S */ 6655 /* 6656 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6657 * that specifies an instruction that performs "result = r0 op r1". 6658 * This could be an ARM instruction or a function call. (If the result 6659 * comes back in a register other than r0, you can override "result".) 6660 * 6661 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6662 * vCC (r1). Useful for integer division and modulus. 6663 * 6664 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6665 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6666 */ 6667 /* binop/lit16 vA, vB, #+CCCC */ 6668 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6669 mov r2, rINST, lsr #12 @ r2<- B 6670 mov r9, rINST, lsr #8 @ r9<- A+ 6671 GET_VREG(r0, r2) @ r0<- vB 6672 and r9, r9, #15 6673 .if 0 6674 cmp r1, #0 @ is second operand zero? 6675 beq common_errDivideByZero 6676 .endif 6677 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6678 6679 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6680 GET_INST_OPCODE(ip) @ extract opcode from rINST 6681 SET_VREG(r0, r9) @ vAA<- r0 6682 GOTO_OPCODE(ip) @ jump to next instruction 6683 /* 10-13 instructions */ 6684 6685 6686 /* ------------------------------ */ 6687 .balign 64 6688 .L_OP_MUL_INT_LIT16: /* 0xd2 */ 6689 /* File: armv5te/OP_MUL_INT_LIT16.S */ 6690 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6691 /* File: armv5te/binopLit16.S */ 6692 /* 6693 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6694 * that specifies an instruction that performs "result = r0 op r1". 6695 * This could be an ARM instruction or a function call. (If the result 6696 * comes back in a register other than r0, you can override "result".) 6697 * 6698 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6699 * vCC (r1). Useful for integer division and modulus. 6700 * 6701 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6702 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6703 */ 6704 /* binop/lit16 vA, vB, #+CCCC */ 6705 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6706 mov r2, rINST, lsr #12 @ r2<- B 6707 mov r9, rINST, lsr #8 @ r9<- A+ 6708 GET_VREG(r0, r2) @ r0<- vB 6709 and r9, r9, #15 6710 .if 0 6711 cmp r1, #0 @ is second operand zero? 6712 beq common_errDivideByZero 6713 .endif 6714 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6715 6716 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6717 GET_INST_OPCODE(ip) @ extract opcode from rINST 6718 SET_VREG(r0, r9) @ vAA<- r0 6719 GOTO_OPCODE(ip) @ jump to next instruction 6720 /* 10-13 instructions */ 6721 6722 6723 /* ------------------------------ */ 6724 .balign 64 6725 .L_OP_DIV_INT_LIT16: /* 0xd3 */ 6726 /* File: armv5te/OP_DIV_INT_LIT16.S */ 6727 /* File: armv5te/binopLit16.S */ 6728 /* 6729 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6730 * that specifies an instruction that performs "result = r0 op r1". 6731 * This could be an ARM instruction or a function call. (If the result 6732 * comes back in a register other than r0, you can override "result".) 6733 * 6734 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6735 * vCC (r1). Useful for integer division and modulus. 6736 * 6737 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6738 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6739 */ 6740 /* binop/lit16 vA, vB, #+CCCC */ 6741 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6742 mov r2, rINST, lsr #12 @ r2<- B 6743 mov r9, rINST, lsr #8 @ r9<- A+ 6744 GET_VREG(r0, r2) @ r0<- vB 6745 and r9, r9, #15 6746 .if 1 6747 cmp r1, #0 @ is second operand zero? 6748 beq common_errDivideByZero 6749 .endif 6750 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6751 6752 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6753 GET_INST_OPCODE(ip) @ extract opcode from rINST 6754 SET_VREG(r0, r9) @ vAA<- r0 6755 GOTO_OPCODE(ip) @ jump to next instruction 6756 /* 10-13 instructions */ 6757 6758 6759 /* ------------------------------ */ 6760 .balign 64 6761 .L_OP_REM_INT_LIT16: /* 0xd4 */ 6762 /* File: armv5te/OP_REM_INT_LIT16.S */ 6763 /* idivmod returns quotient in r0 and remainder in r1 */ 6764 /* File: armv5te/binopLit16.S */ 6765 /* 6766 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6767 * that specifies an instruction that performs "result = r0 op r1". 6768 * This could be an ARM instruction or a function call. (If the result 6769 * comes back in a register other than r0, you can override "result".) 6770 * 6771 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6772 * vCC (r1). Useful for integer division and modulus. 6773 * 6774 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6775 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6776 */ 6777 /* binop/lit16 vA, vB, #+CCCC */ 6778 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6779 mov r2, rINST, lsr #12 @ r2<- B 6780 mov r9, rINST, lsr #8 @ r9<- A+ 6781 GET_VREG(r0, r2) @ r0<- vB 6782 and r9, r9, #15 6783 .if 1 6784 cmp r1, #0 @ is second operand zero? 6785 beq common_errDivideByZero 6786 .endif 6787 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6788 6789 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6790 GET_INST_OPCODE(ip) @ extract opcode from rINST 6791 SET_VREG(r1, r9) @ vAA<- r1 6792 GOTO_OPCODE(ip) @ jump to next instruction 6793 /* 10-13 instructions */ 6794 6795 6796 /* ------------------------------ */ 6797 .balign 64 6798 .L_OP_AND_INT_LIT16: /* 0xd5 */ 6799 /* File: armv5te/OP_AND_INT_LIT16.S */ 6800 /* File: armv5te/binopLit16.S */ 6801 /* 6802 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6803 * that specifies an instruction that performs "result = r0 op r1". 6804 * This could be an ARM instruction or a function call. (If the result 6805 * comes back in a register other than r0, you can override "result".) 6806 * 6807 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6808 * vCC (r1). Useful for integer division and modulus. 6809 * 6810 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6811 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6812 */ 6813 /* binop/lit16 vA, vB, #+CCCC */ 6814 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6815 mov r2, rINST, lsr #12 @ r2<- B 6816 mov r9, rINST, lsr #8 @ r9<- A+ 6817 GET_VREG(r0, r2) @ r0<- vB 6818 and r9, r9, #15 6819 .if 0 6820 cmp r1, #0 @ is second operand zero? 6821 beq common_errDivideByZero 6822 .endif 6823 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6824 6825 and r0, r0, r1 @ r0<- op, r0-r3 changed 6826 GET_INST_OPCODE(ip) @ extract opcode from rINST 6827 SET_VREG(r0, r9) @ vAA<- r0 6828 GOTO_OPCODE(ip) @ jump to next instruction 6829 /* 10-13 instructions */ 6830 6831 6832 /* ------------------------------ */ 6833 .balign 64 6834 .L_OP_OR_INT_LIT16: /* 0xd6 */ 6835 /* File: armv5te/OP_OR_INT_LIT16.S */ 6836 /* File: armv5te/binopLit16.S */ 6837 /* 6838 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6839 * that specifies an instruction that performs "result = r0 op r1". 6840 * This could be an ARM instruction or a function call. (If the result 6841 * comes back in a register other than r0, you can override "result".) 6842 * 6843 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6844 * vCC (r1). Useful for integer division and modulus. 6845 * 6846 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6847 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6848 */ 6849 /* binop/lit16 vA, vB, #+CCCC */ 6850 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6851 mov r2, rINST, lsr #12 @ r2<- B 6852 mov r9, rINST, lsr #8 @ r9<- A+ 6853 GET_VREG(r0, r2) @ r0<- vB 6854 and r9, r9, #15 6855 .if 0 6856 cmp r1, #0 @ is second operand zero? 6857 beq common_errDivideByZero 6858 .endif 6859 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6860 6861 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6862 GET_INST_OPCODE(ip) @ extract opcode from rINST 6863 SET_VREG(r0, r9) @ vAA<- r0 6864 GOTO_OPCODE(ip) @ jump to next instruction 6865 /* 10-13 instructions */ 6866 6867 6868 /* ------------------------------ */ 6869 .balign 64 6870 .L_OP_XOR_INT_LIT16: /* 0xd7 */ 6871 /* File: armv5te/OP_XOR_INT_LIT16.S */ 6872 /* File: armv5te/binopLit16.S */ 6873 /* 6874 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6875 * that specifies an instruction that performs "result = r0 op r1". 6876 * This could be an ARM instruction or a function call. (If the result 6877 * comes back in a register other than r0, you can override "result".) 6878 * 6879 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6880 * vCC (r1). Useful for integer division and modulus. 6881 * 6882 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6883 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6884 */ 6885 /* binop/lit16 vA, vB, #+CCCC */ 6886 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6887 mov r2, rINST, lsr #12 @ r2<- B 6888 mov r9, rINST, lsr #8 @ r9<- A+ 6889 GET_VREG(r0, r2) @ r0<- vB 6890 and r9, r9, #15 6891 .if 0 6892 cmp r1, #0 @ is second operand zero? 6893 beq common_errDivideByZero 6894 .endif 6895 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6896 6897 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6898 GET_INST_OPCODE(ip) @ extract opcode from rINST 6899 SET_VREG(r0, r9) @ vAA<- r0 6900 GOTO_OPCODE(ip) @ jump to next instruction 6901 /* 10-13 instructions */ 6902 6903 6904 /* ------------------------------ */ 6905 .balign 64 6906 .L_OP_ADD_INT_LIT8: /* 0xd8 */ 6907 /* File: armv5te/OP_ADD_INT_LIT8.S */ 6908 /* File: armv5te/binopLit8.S */ 6909 /* 6910 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6911 * that specifies an instruction that performs "result = r0 op r1". 6912 * This could be an ARM instruction or a function call. (If the result 6913 * comes back in a register other than r0, you can override "result".) 6914 * 6915 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6916 * vCC (r1). Useful for integer division and modulus. 6917 * 6918 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6919 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6920 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6921 */ 6922 /* binop/lit8 vAA, vBB, #+CC */ 6923 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6924 mov r9, rINST, lsr #8 @ r9<- AA 6925 and r2, r3, #255 @ r2<- BB 6926 GET_VREG(r0, r2) @ r0<- vBB 6927 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6928 .if 0 6929 @cmp r1, #0 @ is second operand zero? 6930 beq common_errDivideByZero 6931 .endif 6932 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6933 6934 @ optional op; may set condition codes 6935 add r0, r0, r1 @ r0<- op, r0-r3 changed 6936 GET_INST_OPCODE(ip) @ extract opcode from rINST 6937 SET_VREG(r0, r9) @ vAA<- r0 6938 GOTO_OPCODE(ip) @ jump to next instruction 6939 /* 10-12 instructions */ 6940 6941 6942 /* ------------------------------ */ 6943 .balign 64 6944 .L_OP_RSUB_INT_LIT8: /* 0xd9 */ 6945 /* File: armv5te/OP_RSUB_INT_LIT8.S */ 6946 /* File: armv5te/binopLit8.S */ 6947 /* 6948 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6949 * that specifies an instruction that performs "result = r0 op r1". 6950 * This could be an ARM instruction or a function call. (If the result 6951 * comes back in a register other than r0, you can override "result".) 6952 * 6953 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6954 * vCC (r1). Useful for integer division and modulus. 6955 * 6956 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6957 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6958 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6959 */ 6960 /* binop/lit8 vAA, vBB, #+CC */ 6961 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6962 mov r9, rINST, lsr #8 @ r9<- AA 6963 and r2, r3, #255 @ r2<- BB 6964 GET_VREG(r0, r2) @ r0<- vBB 6965 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6966 .if 0 6967 @cmp r1, #0 @ is second operand zero? 6968 beq common_errDivideByZero 6969 .endif 6970 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6971 6972 @ optional op; may set condition codes 6973 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6974 GET_INST_OPCODE(ip) @ extract opcode from rINST 6975 SET_VREG(r0, r9) @ vAA<- r0 6976 GOTO_OPCODE(ip) @ jump to next instruction 6977 /* 10-12 instructions */ 6978 6979 6980 /* ------------------------------ */ 6981 .balign 64 6982 .L_OP_MUL_INT_LIT8: /* 0xda */ 6983 /* File: armv5te/OP_MUL_INT_LIT8.S */ 6984 /* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6985 /* File: armv5te/binopLit8.S */ 6986 /* 6987 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6988 * that specifies an instruction that performs "result = r0 op r1". 6989 * This could be an ARM instruction or a function call. (If the result 6990 * comes back in a register other than r0, you can override "result".) 6991 * 6992 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6993 * vCC (r1). Useful for integer division and modulus. 6994 * 6995 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6996 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6997 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6998 */ 6999 /* binop/lit8 vAA, vBB, #+CC */ 7000 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7001 mov r9, rINST, lsr #8 @ r9<- AA 7002 and r2, r3, #255 @ r2<- BB 7003 GET_VREG(r0, r2) @ r0<- vBB 7004 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7005 .if 0 7006 @cmp r1, #0 @ is second operand zero? 7007 beq common_errDivideByZero 7008 .endif 7009 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7010 7011 @ optional op; may set condition codes 7012 mul r0, r1, r0 @ r0<- op, r0-r3 changed 7013 GET_INST_OPCODE(ip) @ extract opcode from rINST 7014 SET_VREG(r0, r9) @ vAA<- r0 7015 GOTO_OPCODE(ip) @ jump to next instruction 7016 /* 10-12 instructions */ 7017 7018 7019 /* ------------------------------ */ 7020 .balign 64 7021 .L_OP_DIV_INT_LIT8: /* 0xdb */ 7022 /* File: armv5te/OP_DIV_INT_LIT8.S */ 7023 /* File: armv5te/binopLit8.S */ 7024 /* 7025 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7026 * that specifies an instruction that performs "result = r0 op r1". 7027 * This could be an ARM instruction or a function call. (If the result 7028 * comes back in a register other than r0, you can override "result".) 7029 * 7030 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7031 * vCC (r1). Useful for integer division and modulus. 7032 * 7033 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7034 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7035 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7036 */ 7037 /* binop/lit8 vAA, vBB, #+CC */ 7038 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7039 mov r9, rINST, lsr #8 @ r9<- AA 7040 and r2, r3, #255 @ r2<- BB 7041 GET_VREG(r0, r2) @ r0<- vBB 7042 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7043 .if 1 7044 @cmp r1, #0 @ is second operand zero? 7045 beq common_errDivideByZero 7046 .endif 7047 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7048 7049 @ optional op; may set condition codes 7050 bl __aeabi_idiv @ r0<- op, r0-r3 changed 7051 GET_INST_OPCODE(ip) @ extract opcode from rINST 7052 SET_VREG(r0, r9) @ vAA<- r0 7053 GOTO_OPCODE(ip) @ jump to next instruction 7054 /* 10-12 instructions */ 7055 7056 7057 /* ------------------------------ */ 7058 .balign 64 7059 .L_OP_REM_INT_LIT8: /* 0xdc */ 7060 /* File: armv5te/OP_REM_INT_LIT8.S */ 7061 /* idivmod returns quotient in r0 and remainder in r1 */ 7062 /* File: armv5te/binopLit8.S */ 7063 /* 7064 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7065 * that specifies an instruction that performs "result = r0 op r1". 7066 * This could be an ARM instruction or a function call. (If the result 7067 * comes back in a register other than r0, you can override "result".) 7068 * 7069 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7070 * vCC (r1). Useful for integer division and modulus. 7071 * 7072 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7073 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7074 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7075 */ 7076 /* binop/lit8 vAA, vBB, #+CC */ 7077 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7078 mov r9, rINST, lsr #8 @ r9<- AA 7079 and r2, r3, #255 @ r2<- BB 7080 GET_VREG(r0, r2) @ r0<- vBB 7081 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7082 .if 1 7083 @cmp r1, #0 @ is second operand zero? 7084 beq common_errDivideByZero 7085 .endif 7086 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7087 7088 @ optional op; may set condition codes 7089 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 7090 GET_INST_OPCODE(ip) @ extract opcode from rINST 7091 SET_VREG(r1, r9) @ vAA<- r1 7092 GOTO_OPCODE(ip) @ jump to next instruction 7093 /* 10-12 instructions */ 7094 7095 7096 /* ------------------------------ */ 7097 .balign 64 7098 .L_OP_AND_INT_LIT8: /* 0xdd */ 7099 /* File: armv5te/OP_AND_INT_LIT8.S */ 7100 /* File: armv5te/binopLit8.S */ 7101 /* 7102 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7103 * that specifies an instruction that performs "result = r0 op r1". 7104 * This could be an ARM instruction or a function call. (If the result 7105 * comes back in a register other than r0, you can override "result".) 7106 * 7107 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7108 * vCC (r1). Useful for integer division and modulus. 7109 * 7110 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7111 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7112 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7113 */ 7114 /* binop/lit8 vAA, vBB, #+CC */ 7115 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7116 mov r9, rINST, lsr #8 @ r9<- AA 7117 and r2, r3, #255 @ r2<- BB 7118 GET_VREG(r0, r2) @ r0<- vBB 7119 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7120 .if 0 7121 @cmp r1, #0 @ is second operand zero? 7122 beq common_errDivideByZero 7123 .endif 7124 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7125 7126 @ optional op; may set condition codes 7127 and r0, r0, r1 @ r0<- op, r0-r3 changed 7128 GET_INST_OPCODE(ip) @ extract opcode from rINST 7129 SET_VREG(r0, r9) @ vAA<- r0 7130 GOTO_OPCODE(ip) @ jump to next instruction 7131 /* 10-12 instructions */ 7132 7133 7134 /* ------------------------------ */ 7135 .balign 64 7136 .L_OP_OR_INT_LIT8: /* 0xde */ 7137 /* File: armv5te/OP_OR_INT_LIT8.S */ 7138 /* File: armv5te/binopLit8.S */ 7139 /* 7140 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7141 * that specifies an instruction that performs "result = r0 op r1". 7142 * This could be an ARM instruction or a function call. (If the result 7143 * comes back in a register other than r0, you can override "result".) 7144 * 7145 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7146 * vCC (r1). Useful for integer division and modulus. 7147 * 7148 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7149 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7150 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7151 */ 7152 /* binop/lit8 vAA, vBB, #+CC */ 7153 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7154 mov r9, rINST, lsr #8 @ r9<- AA 7155 and r2, r3, #255 @ r2<- BB 7156 GET_VREG(r0, r2) @ r0<- vBB 7157 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7158 .if 0 7159 @cmp r1, #0 @ is second operand zero? 7160 beq common_errDivideByZero 7161 .endif 7162 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7163 7164 @ optional op; may set condition codes 7165 orr r0, r0, r1 @ r0<- op, r0-r3 changed 7166 GET_INST_OPCODE(ip) @ extract opcode from rINST 7167 SET_VREG(r0, r9) @ vAA<- r0 7168 GOTO_OPCODE(ip) @ jump to next instruction 7169 /* 10-12 instructions */ 7170 7171 7172 /* ------------------------------ */ 7173 .balign 64 7174 .L_OP_XOR_INT_LIT8: /* 0xdf */ 7175 /* File: armv5te/OP_XOR_INT_LIT8.S */ 7176 /* File: armv5te/binopLit8.S */ 7177 /* 7178 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7179 * that specifies an instruction that performs "result = r0 op r1". 7180 * This could be an ARM instruction or a function call. (If the result 7181 * comes back in a register other than r0, you can override "result".) 7182 * 7183 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7184 * vCC (r1). Useful for integer division and modulus. 7185 * 7186 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7187 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7188 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7189 */ 7190 /* binop/lit8 vAA, vBB, #+CC */ 7191 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7192 mov r9, rINST, lsr #8 @ r9<- AA 7193 and r2, r3, #255 @ r2<- BB 7194 GET_VREG(r0, r2) @ r0<- vBB 7195 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7196 .if 0 7197 @cmp r1, #0 @ is second operand zero? 7198 beq common_errDivideByZero 7199 .endif 7200 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7201 7202 @ optional op; may set condition codes 7203 eor r0, r0, r1 @ r0<- op, r0-r3 changed 7204 GET_INST_OPCODE(ip) @ extract opcode from rINST 7205 SET_VREG(r0, r9) @ vAA<- r0 7206 GOTO_OPCODE(ip) @ jump to next instruction 7207 /* 10-12 instructions */ 7208 7209 7210 /* ------------------------------ */ 7211 .balign 64 7212 .L_OP_SHL_INT_LIT8: /* 0xe0 */ 7213 /* File: armv5te/OP_SHL_INT_LIT8.S */ 7214 /* File: armv5te/binopLit8.S */ 7215 /* 7216 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7217 * that specifies an instruction that performs "result = r0 op r1". 7218 * This could be an ARM instruction or a function call. (If the result 7219 * comes back in a register other than r0, you can override "result".) 7220 * 7221 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7222 * vCC (r1). Useful for integer division and modulus. 7223 * 7224 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7225 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7226 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7227 */ 7228 /* binop/lit8 vAA, vBB, #+CC */ 7229 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7230 mov r9, rINST, lsr #8 @ r9<- AA 7231 and r2, r3, #255 @ r2<- BB 7232 GET_VREG(r0, r2) @ r0<- vBB 7233 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7234 .if 0 7235 @cmp r1, #0 @ is second operand zero? 7236 beq common_errDivideByZero 7237 .endif 7238 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7239 7240 and r1, r1, #31 @ optional op; may set condition codes 7241 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 7242 GET_INST_OPCODE(ip) @ extract opcode from rINST 7243 SET_VREG(r0, r9) @ vAA<- r0 7244 GOTO_OPCODE(ip) @ jump to next instruction 7245 /* 10-12 instructions */ 7246 7247 7248 /* ------------------------------ */ 7249 .balign 64 7250 .L_OP_SHR_INT_LIT8: /* 0xe1 */ 7251 /* File: armv5te/OP_SHR_INT_LIT8.S */ 7252 /* File: armv5te/binopLit8.S */ 7253 /* 7254 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7255 * that specifies an instruction that performs "result = r0 op r1". 7256 * This could be an ARM instruction or a function call. (If the result 7257 * comes back in a register other than r0, you can override "result".) 7258 * 7259 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7260 * vCC (r1). Useful for integer division and modulus. 7261 * 7262 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7263 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7264 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7265 */ 7266 /* binop/lit8 vAA, vBB, #+CC */ 7267 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7268 mov r9, rINST, lsr #8 @ r9<- AA 7269 and r2, r3, #255 @ r2<- BB 7270 GET_VREG(r0, r2) @ r0<- vBB 7271 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7272 .if 0 7273 @cmp r1, #0 @ is second operand zero? 7274 beq common_errDivideByZero 7275 .endif 7276 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7277 7278 and r1, r1, #31 @ optional op; may set condition codes 7279 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 7280 GET_INST_OPCODE(ip) @ extract opcode from rINST 7281 SET_VREG(r0, r9) @ vAA<- r0 7282 GOTO_OPCODE(ip) @ jump to next instruction 7283 /* 10-12 instructions */ 7284 7285 7286 /* ------------------------------ */ 7287 .balign 64 7288 .L_OP_USHR_INT_LIT8: /* 0xe2 */ 7289 /* File: armv5te/OP_USHR_INT_LIT8.S */ 7290 /* File: armv5te/binopLit8.S */ 7291 /* 7292 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7293 * that specifies an instruction that performs "result = r0 op r1". 7294 * This could be an ARM instruction or a function call. (If the result 7295 * comes back in a register other than r0, you can override "result".) 7296 * 7297 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7298 * vCC (r1). Useful for integer division and modulus. 7299 * 7300 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7301 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7302 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7303 */ 7304 /* binop/lit8 vAA, vBB, #+CC */ 7305 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7306 mov r9, rINST, lsr #8 @ r9<- AA 7307 and r2, r3, #255 @ r2<- BB 7308 GET_VREG(r0, r2) @ r0<- vBB 7309 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7310 .if 0 7311 @cmp r1, #0 @ is second operand zero? 7312 beq common_errDivideByZero 7313 .endif 7314 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7315 7316 and r1, r1, #31 @ optional op; may set condition codes 7317 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 7318 GET_INST_OPCODE(ip) @ extract opcode from rINST 7319 SET_VREG(r0, r9) @ vAA<- r0 7320 GOTO_OPCODE(ip) @ jump to next instruction 7321 /* 10-12 instructions */ 7322 7323 7324 /* ------------------------------ */ 7325 .balign 64 7326 .L_OP_IGET_VOLATILE: /* 0xe3 */ 7327 /* File: armv5te/OP_IGET_VOLATILE.S */ 7328 /* File: armv5te/OP_IGET.S */ 7329 /* 7330 * General 32-bit instance field get. 7331 * 7332 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7333 */ 7334 /* op vA, vB, field@CCCC */ 7335 mov r0, rINST, lsr #12 @ r0<- B 7336 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7337 FETCH(r1, 1) @ r1<- field ref CCCC 7338 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7339 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7340 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7341 cmp r0, #0 @ is resolved entry null? 7342 bne .LOP_IGET_VOLATILE_finish @ no, already resolved 7343 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7344 EXPORT_PC() @ resolve() could throw 7345 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7346 bl dvmResolveInstField @ r0<- resolved InstField ptr 7347 cmp r0, #0 7348 bne .LOP_IGET_VOLATILE_finish 7349 b common_exceptionThrown 7350 7351 7352 /* ------------------------------ */ 7353 .balign 64 7354 .L_OP_IPUT_VOLATILE: /* 0xe4 */ 7355 /* File: armv5te/OP_IPUT_VOLATILE.S */ 7356 /* File: armv5te/OP_IPUT.S */ 7357 /* 7358 * General 32-bit instance field put. 7359 * 7360 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 7361 */ 7362 /* op vA, vB, field@CCCC */ 7363 mov r0, rINST, lsr #12 @ r0<- B 7364 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7365 FETCH(r1, 1) @ r1<- field ref CCCC 7366 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7367 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7368 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7369 cmp r0, #0 @ is resolved entry null? 7370 bne .LOP_IPUT_VOLATILE_finish @ no, already resolved 7371 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7372 EXPORT_PC() @ resolve() could throw 7373 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7374 bl dvmResolveInstField @ r0<- resolved InstField ptr 7375 cmp r0, #0 @ success? 7376 bne .LOP_IPUT_VOLATILE_finish @ yes, finish up 7377 b common_exceptionThrown 7378 7379 7380 /* ------------------------------ */ 7381 .balign 64 7382 .L_OP_SGET_VOLATILE: /* 0xe5 */ 7383 /* File: armv5te/OP_SGET_VOLATILE.S */ 7384 /* File: armv5te/OP_SGET.S */ 7385 /* 7386 * General 32-bit SGET handler. 7387 * 7388 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7389 */ 7390 /* op vAA, field@BBBB */ 7391 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7392 FETCH(r1, 1) @ r1<- field ref BBBB 7393 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7394 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7395 cmp r0, #0 @ is resolved entry null? 7396 beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve 7397 .LOP_SGET_VOLATILE_finish: @ field ptr in r0 7398 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7399 SMP_DMB @ acquiring load 7400 mov r2, rINST, lsr #8 @ r2<- AA 7401 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7402 SET_VREG(r1, r2) @ fp[AA]<- r1 7403 GET_INST_OPCODE(ip) @ extract opcode from rINST 7404 GOTO_OPCODE(ip) @ jump to next instruction 7405 7406 7407 /* ------------------------------ */ 7408 .balign 64 7409 .L_OP_SPUT_VOLATILE: /* 0xe6 */ 7410 /* File: armv5te/OP_SPUT_VOLATILE.S */ 7411 /* File: armv5te/OP_SPUT.S */ 7412 /* 7413 * General 32-bit SPUT handler. 7414 * 7415 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 7416 */ 7417 /* op vAA, field@BBBB */ 7418 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7419 FETCH(r1, 1) @ r1<- field ref BBBB 7420 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7421 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7422 cmp r0, #0 @ is resolved entry null? 7423 beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve 7424 .LOP_SPUT_VOLATILE_finish: @ field ptr in r0 7425 mov r2, rINST, lsr #8 @ r2<- AA 7426 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7427 GET_VREG(r1, r2) @ r1<- fp[AA] 7428 GET_INST_OPCODE(ip) @ extract opcode from rINST 7429 SMP_DMB_ST @ releasing store 7430 str r1, [r0, #offStaticField_value] @ field<- vAA 7431 SMP_DMB 7432 GOTO_OPCODE(ip) @ jump to next instruction 7433 7434 7435 /* ------------------------------ */ 7436 .balign 64 7437 .L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 7438 /* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */ 7439 /* File: armv5te/OP_IGET.S */ 7440 /* 7441 * General 32-bit instance field get. 7442 * 7443 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7444 */ 7445 /* op vA, vB, field@CCCC */ 7446 mov r0, rINST, lsr #12 @ r0<- B 7447 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7448 FETCH(r1, 1) @ r1<- field ref CCCC 7449 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7450 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7451 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7452 cmp r0, #0 @ is resolved entry null? 7453 bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved 7454 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7455 EXPORT_PC() @ resolve() could throw 7456 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7457 bl dvmResolveInstField @ r0<- resolved InstField ptr 7458 cmp r0, #0 7459 bne .LOP_IGET_OBJECT_VOLATILE_finish 7460 b common_exceptionThrown 7461 7462 7463 /* ------------------------------ */ 7464 .balign 64 7465 .L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 7466 /* File: armv5te/OP_IGET_WIDE_VOLATILE.S */ 7467 /* File: armv5te/OP_IGET_WIDE.S */ 7468 /* 7469 * Wide 32-bit instance field get. 7470 */ 7471 /* iget-wide vA, vB, field@CCCC */ 7472 mov r0, rINST, lsr #12 @ r0<- B 7473 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7474 FETCH(r1, 1) @ r1<- field ref CCCC 7475 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7476 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7477 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7478 cmp r0, #0 @ is resolved entry null? 7479 bne .LOP_IGET_WIDE_VOLATILE_finish @ no, already resolved 7480 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7481 EXPORT_PC() @ resolve() could throw 7482 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7483 bl dvmResolveInstField @ r0<- resolved InstField ptr 7484 cmp r0, #0 7485 bne .LOP_IGET_WIDE_VOLATILE_finish 7486 b common_exceptionThrown 7487 7488 7489 /* ------------------------------ */ 7490 .balign 64 7491 .L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 7492 /* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */ 7493 /* File: armv5te/OP_IPUT_WIDE.S */ 7494 /* iput-wide vA, vB, field@CCCC */ 7495 mov r0, rINST, lsr #12 @ r0<- B 7496 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7497 FETCH(r1, 1) @ r1<- field ref CCCC 7498 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7499 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7500 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7501 cmp r0, #0 @ is resolved entry null? 7502 bne .LOP_IPUT_WIDE_VOLATILE_finish @ no, already resolved 7503 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7504 EXPORT_PC() @ resolve() could throw 7505 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7506 bl dvmResolveInstField @ r0<- resolved InstField ptr 7507 cmp r0, #0 @ success? 7508 bne .LOP_IPUT_WIDE_VOLATILE_finish @ yes, finish up 7509 b common_exceptionThrown 7510 7511 7512 /* ------------------------------ */ 7513 .balign 64 7514 .L_OP_SGET_WIDE_VOLATILE: /* 0xea */ 7515 /* File: armv5te/OP_SGET_WIDE_VOLATILE.S */ 7516 /* File: armv5te/OP_SGET_WIDE.S */ 7517 /* 7518 * 64-bit SGET handler. 7519 */ 7520 /* sget-wide vAA, field@BBBB */ 7521 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7522 FETCH(r1, 1) @ r1<- field ref BBBB 7523 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7524 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7525 cmp r0, #0 @ is resolved entry null? 7526 beq .LOP_SGET_WIDE_VOLATILE_resolve @ yes, do resolve 7527 .LOP_SGET_WIDE_VOLATILE_finish: 7528 mov r9, rINST, lsr #8 @ r9<- AA 7529 .if 1 7530 add r0, r0, #offStaticField_value @ r0<- pointer to data 7531 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 7532 .else 7533 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 7534 .endif 7535 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7536 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7537 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 7538 GET_INST_OPCODE(ip) @ extract opcode from rINST 7539 GOTO_OPCODE(ip) @ jump to next instruction 7540 7541 7542 /* ------------------------------ */ 7543 .balign 64 7544 .L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 7545 /* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */ 7546 /* File: armv5te/OP_SPUT_WIDE.S */ 7547 /* 7548 * 64-bit SPUT handler. 7549 */ 7550 /* sput-wide vAA, field@BBBB */ 7551 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- DvmDex 7552 FETCH(r1, 1) @ r1<- field ref BBBB 7553 ldr r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7554 mov r9, rINST, lsr #8 @ r9<- AA 7555 ldr r2, [r10, r1, lsl #2] @ r2<- resolved StaticField ptr 7556 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7557 cmp r2, #0 @ is resolved entry null? 7558 beq .LOP_SPUT_WIDE_VOLATILE_resolve @ yes, do resolve 7559 .LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9 7560 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7561 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 7562 GET_INST_OPCODE(r10) @ extract opcode from rINST 7563 .if 1 7564 add r2, r2, #offStaticField_value @ r2<- pointer to data 7565 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 7566 .else 7567 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 7568 .endif 7569 GOTO_OPCODE(r10) @ jump to next instruction 7570 7571 7572 /* ------------------------------ */ 7573 .balign 64 7574 .L_OP_BREAKPOINT: /* 0xec */ 7575 /* File: armv5te/OP_BREAKPOINT.S */ 7576 /* 7577 * Breakpoint handler. 7578 * 7579 * Restart this instruction with the original opcode. By 7580 * the time we get here, the breakpoint will have already been 7581 * handled. 7582 */ 7583 mov r0, rPC 7584 bl dvmGetOriginalOpcode @ (rPC) 7585 FETCH(rINST, 0) @ reload OP_BREAKPOINT + rest of inst 7586 ldr r1, [rSELF, #offThread_mainHandlerTable] 7587 and rINST, #0xff00 7588 orr rINST, rINST, r0 7589 GOTO_OPCODE_BASE(r1, r0) 7590 7591 /* ------------------------------ */ 7592 .balign 64 7593 .L_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 7594 /* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */ 7595 /* 7596 * Handle a throw-verification-error instruction. This throws an 7597 * exception for an error discovered during verification. The 7598 * exception is indicated by AA, with some detail provided by BBBB. 7599 */ 7600 /* op AA, ref@BBBB */ 7601 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7602 FETCH(r2, 1) @ r2<- BBBB 7603 EXPORT_PC() @ export the PC 7604 mov r1, rINST, lsr #8 @ r1<- AA 7605 bl dvmThrowVerificationError @ always throws 7606 b common_exceptionThrown @ handle exception 7607 7608 /* ------------------------------ */ 7609 .balign 64 7610 .L_OP_EXECUTE_INLINE: /* 0xee */ 7611 /* File: armv5te/OP_EXECUTE_INLINE.S */ 7612 /* 7613 * Execute a "native inline" instruction. 7614 * 7615 * We need to call an InlineOp4Func: 7616 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7617 * 7618 * The first four args are in r0-r3, pointer to return value storage 7619 * is on the stack. The function's return value is a flag that tells 7620 * us if an exception was thrown. 7621 * 7622 * TUNING: could maintain two tables, pointer in Thread and 7623 * swap if profiler/debuggger active. 7624 */ 7625 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 7626 ldrh r2, [rSELF, #offThread_subMode] 7627 FETCH(r10, 1) @ r10<- BBBB 7628 EXPORT_PC() @ can throw 7629 ands r2, #kSubModeDebugProfile @ Any going on? 7630 bne .LOP_EXECUTE_INLINE_debugmode @ yes - take slow path 7631 .LOP_EXECUTE_INLINE_resume: 7632 add r1, rSELF, #offThread_retval @ r1<- &self->retval 7633 sub sp, sp, #8 @ make room for arg, +64 bit align 7634 mov r0, rINST, lsr #12 @ r0<- B 7635 str r1, [sp] @ push &self->retval 7636 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 7637 add sp, sp, #8 @ pop stack 7638 cmp r0, #0 @ test boolean result of inline 7639 beq common_exceptionThrown @ returned false, handle exception 7640 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7641 GET_INST_OPCODE(ip) @ extract opcode from rINST 7642 GOTO_OPCODE(ip) @ jump to next instruction 7643 7644 /* ------------------------------ */ 7645 .balign 64 7646 .L_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 7647 /* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */ 7648 /* 7649 * Execute a "native inline" instruction, using "/range" semantics. 7650 * Same idea as execute-inline, but we get the args differently. 7651 * 7652 * We need to call an InlineOp4Func: 7653 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7654 * 7655 * The first four args are in r0-r3, pointer to return value storage 7656 * is on the stack. The function's return value is a flag that tells 7657 * us if an exception was thrown. 7658 */ 7659 /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */ 7660 ldrh r2, [rSELF, #offThread_subMode] 7661 FETCH(r10, 1) @ r10<- BBBB 7662 EXPORT_PC() @ can throw 7663 ands r2, #kSubModeDebugProfile @ Any going on? 7664 bne .LOP_EXECUTE_INLINE_RANGE_debugmode @ yes - take slow path 7665 .LOP_EXECUTE_INLINE_RANGE_resume: 7666 add r1, rSELF, #offThread_retval @ r1<- &self->retval 7667 sub sp, sp, #8 @ make room for arg, +64 bit align 7668 mov r0, rINST, lsr #8 @ r0<- AA 7669 str r1, [sp] @ push &self->retval 7670 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 7671 add sp, sp, #8 @ pop stack 7672 cmp r0, #0 @ test boolean result of inline 7673 beq common_exceptionThrown @ returned false, handle exception 7674 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7675 GET_INST_OPCODE(ip) @ extract opcode from rINST 7676 GOTO_OPCODE(ip) @ jump to next instruction 7677 7678 /* ------------------------------ */ 7679 .balign 64 7680 .L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */ 7681 /* File: armv5te/OP_INVOKE_OBJECT_INIT_RANGE.S */ 7682 /* 7683 * Invoke Object.<init> on an object. In practice we know that 7684 * Object's nullary constructor doesn't do anything, so we just 7685 * skip it unless a debugger is active. 7686 */ 7687 FETCH(r1, 2) @ r1<- CCCC 7688 GET_VREG(r0, r1) @ r0<- "this" ptr 7689 cmp r0, #0 @ check for NULL 7690 beq common_errNullObject @ export PC and throw NPE 7691 ldr r1, [r0, #offObject_clazz] @ r1<- obj->clazz 7692 ldr r2, [r1, #offClassObject_accessFlags] @ r2<- clazz->accessFlags 7693 tst r2, #CLASS_ISFINALIZABLE @ is this class finalizable? 7694 bne .LOP_INVOKE_OBJECT_INIT_RANGE_setFinal @ yes, go 7695 .LOP_INVOKE_OBJECT_INIT_RANGE_finish: 7696 ldrh r1, [rSELF, #offThread_subMode] 7697 ands r1, #kSubModeDebuggerActive @ debugger active? 7698 bne .LOP_INVOKE_OBJECT_INIT_RANGE_debugger @ Yes - skip optimization 7699 FETCH_ADVANCE_INST(2+1) @ advance to next instr, load rINST 7700 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 7701 GOTO_OPCODE(ip) @ execute it 7702 7703 /* ------------------------------ */ 7704 .balign 64 7705 .L_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 7706 /* File: armv5te/OP_RETURN_VOID_BARRIER.S */ 7707 SMP_DMB_ST 7708 b common_returnFromMethod 7709 7710 /* ------------------------------ */ 7711 .balign 64 7712 .L_OP_IGET_QUICK: /* 0xf2 */ 7713 /* File: armv5te/OP_IGET_QUICK.S */ 7714 /* For: iget-quick, iget-object-quick */ 7715 /* op vA, vB, offset@CCCC */ 7716 mov r2, rINST, lsr #12 @ r2<- B 7717 GET_VREG(r3, r2) @ r3<- object we're operating on 7718 FETCH(r1, 1) @ r1<- field byte offset 7719 cmp r3, #0 @ check object for null 7720 mov r2, rINST, lsr #8 @ r2<- A(+) 7721 beq common_errNullObject @ object was null 7722 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7723 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7724 and r2, r2, #15 7725 GET_INST_OPCODE(ip) @ extract opcode from rINST 7726 SET_VREG(r0, r2) @ fp[A]<- r0 7727 GOTO_OPCODE(ip) @ jump to next instruction 7728 7729 /* ------------------------------ */ 7730 .balign 64 7731 .L_OP_IGET_WIDE_QUICK: /* 0xf3 */ 7732 /* File: armv5te/OP_IGET_WIDE_QUICK.S */ 7733 /* iget-wide-quick vA, vB, offset@CCCC */ 7734 mov r2, rINST, lsr #12 @ r2<- B 7735 GET_VREG(r3, r2) @ r3<- object we're operating on 7736 FETCH(ip, 1) @ ip<- field byte offset 7737 cmp r3, #0 @ check object for null 7738 mov r2, rINST, lsr #8 @ r2<- A(+) 7739 beq common_errNullObject @ object was null 7740 ldrd r0, [r3, ip] @ r0<- obj.field (64 bits, aligned) 7741 and r2, r2, #15 7742 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7743 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 7744 GET_INST_OPCODE(ip) @ extract opcode from rINST 7745 stmia r3, {r0-r1} @ fp[A]<- r0/r1 7746 GOTO_OPCODE(ip) @ jump to next instruction 7747 7748 /* ------------------------------ */ 7749 .balign 64 7750 .L_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 7751 /* File: armv5te/OP_IGET_OBJECT_QUICK.S */ 7752 /* File: armv5te/OP_IGET_QUICK.S */ 7753 /* For: iget-quick, iget-object-quick */ 7754 /* op vA, vB, offset@CCCC */ 7755 mov r2, rINST, lsr #12 @ r2<- B 7756 GET_VREG(r3, r2) @ r3<- object we're operating on 7757 FETCH(r1, 1) @ r1<- field byte offset 7758 cmp r3, #0 @ check object for null 7759 mov r2, rINST, lsr #8 @ r2<- A(+) 7760 beq common_errNullObject @ object was null 7761 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7762 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7763 and r2, r2, #15 7764 GET_INST_OPCODE(ip) @ extract opcode from rINST 7765 SET_VREG(r0, r2) @ fp[A]<- r0 7766 GOTO_OPCODE(ip) @ jump to next instruction 7767 7768 7769 /* ------------------------------ */ 7770 .balign 64 7771 .L_OP_IPUT_QUICK: /* 0xf5 */ 7772 /* File: armv5te/OP_IPUT_QUICK.S */ 7773 /* For: iput-quick */ 7774 /* op vA, vB, offset@CCCC */ 7775 mov r2, rINST, lsr #12 @ r2<- B 7776 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7777 FETCH(r1, 1) @ r1<- field byte offset 7778 cmp r3, #0 @ check object for null 7779 mov r2, rINST, lsr #8 @ r2<- A(+) 7780 beq common_errNullObject @ object was null 7781 and r2, r2, #15 7782 GET_VREG(r0, r2) @ r0<- fp[A] 7783 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7784 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7785 GET_INST_OPCODE(ip) @ extract opcode from rINST 7786 GOTO_OPCODE(ip) @ jump to next instruction 7787 7788 /* ------------------------------ */ 7789 .balign 64 7790 .L_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 7791 /* File: armv5te/OP_IPUT_WIDE_QUICK.S */ 7792 /* iput-wide-quick vA, vB, offset@CCCC */ 7793 mov r0, rINST, lsr #8 @ r0<- A(+) 7794 mov r1, rINST, lsr #12 @ r1<- B 7795 and r0, r0, #15 7796 GET_VREG(r2, r1) @ r2<- fp[B], the object pointer 7797 add r3, rFP, r0, lsl #2 @ r3<- &fp[A] 7798 cmp r2, #0 @ check object for null 7799 ldmia r3, {r0-r1} @ r0/r1<- fp[A] 7800 beq common_errNullObject @ object was null 7801 FETCH(r3, 1) @ r3<- field byte offset 7802 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7803 strd r0, [r2, r3] @ obj.field (64 bits, aligned)<- r0/r1 7804 GET_INST_OPCODE(ip) @ extract opcode from rINST 7805 GOTO_OPCODE(ip) @ jump to next instruction 7806 7807 /* ------------------------------ */ 7808 .balign 64 7809 .L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 7810 /* File: armv5te/OP_IPUT_OBJECT_QUICK.S */ 7811 /* For: iput-object-quick */ 7812 /* op vA, vB, offset@CCCC */ 7813 mov r2, rINST, lsr #12 @ r2<- B 7814 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7815 FETCH(r1, 1) @ r1<- field byte offset 7816 cmp r3, #0 @ check object for null 7817 mov r2, rINST, lsr #8 @ r2<- A(+) 7818 beq common_errNullObject @ object was null 7819 and r2, r2, #15 7820 GET_VREG(r0, r2) @ r0<- fp[A] 7821 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 7822 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7823 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7824 cmp r0, #0 7825 strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head 7826 GET_INST_OPCODE(ip) @ extract opcode from rINST 7827 GOTO_OPCODE(ip) @ jump to next instruction 7828 7829 /* ------------------------------ */ 7830 .balign 64 7831 .L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 7832 /* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7833 /* 7834 * Handle an optimized virtual method call. 7835 * 7836 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7837 */ 7838 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7839 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7840 FETCH(r3, 2) @ r3<- FEDC or CCCC 7841 FETCH(r1, 1) @ r1<- BBBB 7842 .if (!0) 7843 and r3, r3, #15 @ r3<- C (or stays CCCC) 7844 .endif 7845 GET_VREG(r9, r3) @ r9<- vC ("this" ptr) 7846 cmp r9, #0 @ is "this" null? 7847 beq common_errNullObject @ null "this", throw exception 7848 ldr r2, [r9, #offObject_clazz] @ r2<- thisPtr->clazz 7849 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7850 EXPORT_PC() @ invoke must export 7851 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7852 bl common_invokeMethodNoRange @ (r0=method, r9="this") 7853 7854 /* ------------------------------ */ 7855 .balign 64 7856 .L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 7857 /* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */ 7858 /* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7859 /* 7860 * Handle an optimized virtual method call. 7861 * 7862 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7863 */ 7864 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7865 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7866 FETCH(r3, 2) @ r3<- FEDC or CCCC 7867 FETCH(r1, 1) @ r1<- BBBB 7868 .if (!1) 7869 and r3, r3, #15 @ r3<- C (or stays CCCC) 7870 .endif 7871 GET_VREG(r9, r3) @ r9<- vC ("this" ptr) 7872 cmp r9, #0 @ is "this" null? 7873 beq common_errNullObject @ null "this", throw exception 7874 ldr r2, [r9, #offObject_clazz] @ r2<- thisPtr->clazz 7875 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7876 EXPORT_PC() @ invoke must export 7877 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7878 bl common_invokeMethodRange @ (r0=method, r9="this") 7879 7880 7881 /* ------------------------------ */ 7882 .balign 64 7883 .L_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 7884 /* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7885 /* 7886 * Handle an optimized "super" method call. 7887 * 7888 * for: [opt] invoke-super-quick, invoke-super-quick/range 7889 */ 7890 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7891 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7892 FETCH(r10, 2) @ r10<- GFED or CCCC 7893 ldr r2, [rSELF, #offThread_method] @ r2<- current method 7894 .if (!0) 7895 and r10, r10, #15 @ r10<- D (or stays CCCC) 7896 .endif 7897 FETCH(r1, 1) @ r1<- BBBB 7898 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7899 EXPORT_PC() @ must export for invoke 7900 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7901 GET_VREG(r9, r10) @ r9<- "this" 7902 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7903 cmp r9, #0 @ null "this" ref? 7904 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7905 beq common_errNullObject @ "this" is null, throw exception 7906 bl common_invokeMethodNoRange @ (r0=method, r9="this") 7907 7908 /* ------------------------------ */ 7909 .balign 64 7910 .L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 7911 /* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */ 7912 /* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7913 /* 7914 * Handle an optimized "super" method call. 7915 * 7916 * for: [opt] invoke-super-quick, invoke-super-quick/range 7917 */ 7918 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7919 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7920 FETCH(r10, 2) @ r10<- GFED or CCCC 7921 ldr r2, [rSELF, #offThread_method] @ r2<- current method 7922 .if (!1) 7923 and r10, r10, #15 @ r10<- D (or stays CCCC) 7924 .endif 7925 FETCH(r1, 1) @ r1<- BBBB 7926 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7927 EXPORT_PC() @ must export for invoke 7928 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7929 GET_VREG(r9, r10) @ r9<- "this" 7930 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7931 cmp r9, #0 @ null "this" ref? 7932 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7933 beq common_errNullObject @ "this" is null, throw exception 7934 bl common_invokeMethodRange @ (r0=method, r9="this") 7935 7936 7937 /* ------------------------------ */ 7938 .balign 64 7939 .L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 7940 /* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */ 7941 /* File: armv5te/OP_IPUT_OBJECT.S */ 7942 /* 7943 * 32-bit instance field put. 7944 * 7945 * for: iput-object, iput-object-volatile 7946 */ 7947 /* op vA, vB, field@CCCC */ 7948 mov r0, rINST, lsr #12 @ r0<- B 7949 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7950 FETCH(r1, 1) @ r1<- field ref CCCC 7951 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7952 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7953 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7954 cmp r0, #0 @ is resolved entry null? 7955 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved 7956 8: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7957 EXPORT_PC() @ resolve() could throw 7958 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7959 bl dvmResolveInstField @ r0<- resolved InstField ptr 7960 cmp r0, #0 @ success? 7961 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up 7962 b common_exceptionThrown 7963 7964 7965 /* ------------------------------ */ 7966 .balign 64 7967 .L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 7968 /* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */ 7969 /* File: armv5te/OP_SGET.S */ 7970 /* 7971 * General 32-bit SGET handler. 7972 * 7973 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7974 */ 7975 /* op vAA, field@BBBB */ 7976 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7977 FETCH(r1, 1) @ r1<- field ref BBBB 7978 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7979 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7980 cmp r0, #0 @ is resolved entry null? 7981 beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve 7982 .LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0 7983 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7984 SMP_DMB @ acquiring load 7985 mov r2, rINST, lsr #8 @ r2<- AA 7986 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7987 SET_VREG(r1, r2) @ fp[AA]<- r1 7988 GET_INST_OPCODE(ip) @ extract opcode from rINST 7989 GOTO_OPCODE(ip) @ jump to next instruction 7990 7991 7992 /* ------------------------------ */ 7993 .balign 64 7994 .L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 7995 /* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */ 7996 /* File: armv5te/OP_SPUT_OBJECT.S */ 7997 /* 7998 * 32-bit SPUT handler for objects 7999 * 8000 * for: sput-object, sput-object-volatile 8001 */ 8002 /* op vAA, field@BBBB */ 8003 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8004 FETCH(r1, 1) @ r1<- field ref BBBB 8005 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 8006 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 8007 cmp r0, #0 @ is resolved entry null? 8008 beq .LOP_SPUT_OBJECT_VOLATILE_resolve @ yes, do resolve 8009 .LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0 8010 mov r2, rINST, lsr #8 @ r2<- AA 8011 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8012 GET_VREG(r1, r2) @ r1<- fp[AA] 8013 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8014 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 8015 GET_INST_OPCODE(ip) @ extract opcode from rINST 8016 SMP_DMB_ST @ releasing store 8017 b .LOP_SPUT_OBJECT_VOLATILE_end 8018 8019 8020 /* ------------------------------ */ 8021 .balign 64 8022 .L_OP_UNUSED_FF: /* 0xff */ 8023 /* File: armv5te/OP_UNUSED_FF.S */ 8024 /* File: armv5te/unused.S */ 8025 bl common_abort 8026 8027 8028 .balign 64 8029 .size dvmAsmInstructionStart, .-dvmAsmInstructionStart 8030 .global dvmAsmInstructionEnd 8031 dvmAsmInstructionEnd: 8032 8033 /* 8034 * =========================================================================== 8035 * Sister implementations 8036 * =========================================================================== 8037 */ 8038 .global dvmAsmSisterStart 8039 .type dvmAsmSisterStart, %function 8040 .text 8041 .balign 4 8042 dvmAsmSisterStart: 8043 8044 /* continuation for OP_CONST_STRING */ 8045 8046 /* 8047 * Continuation if the String has not yet been resolved. 8048 * r1: BBBB (String ref) 8049 * r9: target register 8050 */ 8051 .LOP_CONST_STRING_resolve: 8052 EXPORT_PC() 8053 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 8054 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 8055 bl dvmResolveString @ r0<- String reference 8056 cmp r0, #0 @ failed? 8057 beq common_exceptionThrown @ yup, handle the exception 8058 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8059 SET_VREG(r0, r9) @ vAA<- r0 8060 GET_INST_OPCODE(ip) @ extract opcode from rINST 8061 GOTO_OPCODE(ip) @ jump to next instruction 8062 8063 /* continuation for OP_CONST_STRING_JUMBO */ 8064 8065 /* 8066 * Continuation if the String has not yet been resolved. 8067 * r1: BBBBBBBB (String ref) 8068 * r9: target register 8069 */ 8070 .LOP_CONST_STRING_JUMBO_resolve: 8071 EXPORT_PC() 8072 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 8073 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 8074 bl dvmResolveString @ r0<- String reference 8075 cmp r0, #0 @ failed? 8076 beq common_exceptionThrown @ yup, handle the exception 8077 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 8078 SET_VREG(r0, r9) @ vAA<- r0 8079 GET_INST_OPCODE(ip) @ extract opcode from rINST 8080 GOTO_OPCODE(ip) @ jump to next instruction 8081 8082 /* continuation for OP_CONST_CLASS */ 8083 8084 /* 8085 * Continuation if the Class has not yet been resolved. 8086 * r1: BBBB (Class ref) 8087 * r9: target register 8088 */ 8089 .LOP_CONST_CLASS_resolve: 8090 EXPORT_PC() 8091 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 8092 mov r2, #1 @ r2<- true 8093 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 8094 bl dvmResolveClass @ r0<- Class reference 8095 cmp r0, #0 @ failed? 8096 beq common_exceptionThrown @ yup, handle the exception 8097 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8098 SET_VREG(r0, r9) @ vAA<- r0 8099 GET_INST_OPCODE(ip) @ extract opcode from rINST 8100 GOTO_OPCODE(ip) @ jump to next instruction 8101 8102 /* continuation for OP_CHECK_CAST */ 8103 8104 /* 8105 * Trivial test failed, need to perform full check. This is common. 8106 * r0 holds obj->clazz 8107 * r1 holds desired class resolved from BBBB 8108 * r9 holds object 8109 */ 8110 .LOP_CHECK_CAST_fullcheck: 8111 mov r10, r1 @ avoid ClassObject getting clobbered 8112 bl dvmInstanceofNonTrivial @ r0<- boolean result 8113 cmp r0, #0 @ failed? 8114 bne .LOP_CHECK_CAST_okay @ no, success 8115 8116 @ A cast has failed. We need to throw a ClassCastException. 8117 EXPORT_PC() @ about to throw 8118 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 8119 mov r1, r10 @ r1<- desired class 8120 bl dvmThrowClassCastException 8121 b common_exceptionThrown 8122 8123 /* 8124 * Resolution required. This is the least-likely path. 8125 * 8126 * r2 holds BBBB 8127 * r9 holds object 8128 */ 8129 .LOP_CHECK_CAST_resolve: 8130 EXPORT_PC() @ resolve() could throw 8131 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 8132 mov r1, r2 @ r1<- BBBB 8133 mov r2, #0 @ r2<- false 8134 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8135 bl dvmResolveClass @ r0<- resolved ClassObject ptr 8136 cmp r0, #0 @ got null? 8137 beq common_exceptionThrown @ yes, handle exception 8138 mov r1, r0 @ r1<- class resolved from BBB 8139 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 8140 b .LOP_CHECK_CAST_resolved @ pick up where we left off 8141 8142 /* continuation for OP_INSTANCE_OF */ 8143 8144 /* 8145 * Trivial test failed, need to perform full check. This is common. 8146 * r0 holds obj->clazz 8147 * r1 holds class resolved from BBBB 8148 * r9 holds A 8149 */ 8150 .LOP_INSTANCE_OF_fullcheck: 8151 bl dvmInstanceofNonTrivial @ r0<- boolean result 8152 @ fall through to OP_INSTANCE_OF_store 8153 8154 /* 8155 * r0 holds boolean result 8156 * r9 holds A 8157 */ 8158 .LOP_INSTANCE_OF_store: 8159 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8160 SET_VREG(r0, r9) @ vA<- r0 8161 GET_INST_OPCODE(ip) @ extract opcode from rINST 8162 GOTO_OPCODE(ip) @ jump to next instruction 8163 8164 /* 8165 * Trivial test succeeded, save and bail. 8166 * r9 holds A 8167 */ 8168 .LOP_INSTANCE_OF_trivial: 8169 mov r0, #1 @ indicate success 8170 @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper 8171 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8172 SET_VREG(r0, r9) @ vA<- r0 8173 GET_INST_OPCODE(ip) @ extract opcode from rINST 8174 GOTO_OPCODE(ip) @ jump to next instruction 8175 8176 /* 8177 * Resolution required. This is the least-likely path. 8178 * 8179 * r3 holds BBBB 8180 * r9 holds A 8181 */ 8182 .LOP_INSTANCE_OF_resolve: 8183 EXPORT_PC() @ resolve() could throw 8184 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 8185 mov r1, r3 @ r1<- BBBB 8186 mov r2, #1 @ r2<- true 8187 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 8188 bl dvmResolveClass @ r0<- resolved ClassObject ptr 8189 cmp r0, #0 @ got null? 8190 beq common_exceptionThrown @ yes, handle exception 8191 mov r1, r0 @ r1<- class resolved from BBB 8192 mov r3, rINST, lsr #12 @ r3<- B 8193 GET_VREG(r0, r3) @ r0<- vB (object) 8194 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 8195 b .LOP_INSTANCE_OF_resolved @ pick up where we left off 8196 8197 /* continuation for OP_NEW_INSTANCE */ 8198 8199 .balign 32 @ minimize cache lines 8200 .LOP_NEW_INSTANCE_finish: @ r0=new object 8201 mov r3, rINST, lsr #8 @ r3<- AA 8202 cmp r0, #0 @ failed? 8203 #if defined(WITH_JIT) 8204 /* 8205 * The JIT needs the class to be fully resolved before it can 8206 * include this instruction in a trace. 8207 */ 8208 ldrh r1, [rSELF, #offThread_subMode] 8209 beq common_exceptionThrown @ yes, handle the exception 8210 ands r1, #kSubModeJitTraceBuild @ under construction? 8211 bne .LOP_NEW_INSTANCE_jitCheck 8212 #else 8213 beq common_exceptionThrown @ yes, handle the exception 8214 #endif 8215 .LOP_NEW_INSTANCE_end: 8216 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8217 SET_VREG(r0, r3) @ vAA<- r0 8218 GET_INST_OPCODE(ip) @ extract opcode from rINST 8219 GOTO_OPCODE(ip) @ jump to next instruction 8220 8221 #if defined(WITH_JIT) 8222 /* 8223 * Check to see if we need to stop the trace building early. 8224 * r0: new object 8225 * r3: vAA 8226 */ 8227 .LOP_NEW_INSTANCE_jitCheck: 8228 ldr r1, [r10] @ reload resolved class 8229 cmp r1, #0 @ okay? 8230 bne .LOP_NEW_INSTANCE_end @ yes, finish 8231 mov r9, r0 @ preserve new object 8232 mov r10, r3 @ preserve vAA 8233 mov r0, rSELF 8234 mov r1, rPC 8235 bl dvmJitEndTraceSelect @ (self, pc) 8236 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8237 SET_VREG(r9, r10) @ vAA<- new object 8238 GET_INST_OPCODE(ip) @ extract opcode from rINST 8239 GOTO_OPCODE(ip) @ jump to next instruction 8240 #endif 8241 8242 /* 8243 * Class initialization required. 8244 * 8245 * r0 holds class object 8246 */ 8247 .LOP_NEW_INSTANCE_needinit: 8248 mov r9, r0 @ save r0 8249 bl dvmInitClass @ initialize class 8250 cmp r0, #0 @ check boolean result 8251 mov r0, r9 @ restore r0 8252 bne .LOP_NEW_INSTANCE_initialized @ success, continue 8253 b common_exceptionThrown @ failed, deal with init exception 8254 8255 /* 8256 * Resolution required. This is the least-likely path. 8257 * 8258 * r1 holds BBBB 8259 */ 8260 .LOP_NEW_INSTANCE_resolve: 8261 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 8262 mov r2, #0 @ r2<- false 8263 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8264 bl dvmResolveClass @ r0<- resolved ClassObject ptr 8265 cmp r0, #0 @ got null? 8266 bne .LOP_NEW_INSTANCE_resolved @ no, continue 8267 b common_exceptionThrown @ yes, handle exception 8268 8269 /* continuation for OP_NEW_ARRAY */ 8270 8271 8272 /* 8273 * Resolve class. (This is an uncommon case.) 8274 * 8275 * r1 holds array length 8276 * r2 holds class ref CCCC 8277 */ 8278 .LOP_NEW_ARRAY_resolve: 8279 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 8280 mov r9, r1 @ r9<- length (save) 8281 mov r1, r2 @ r1<- CCCC 8282 mov r2, #0 @ r2<- false 8283 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8284 bl dvmResolveClass @ r0<- call(clazz, ref) 8285 cmp r0, #0 @ got null? 8286 mov r1, r9 @ r1<- length (restore) 8287 beq common_exceptionThrown @ yes, handle exception 8288 @ fall through to OP_NEW_ARRAY_finish 8289 8290 /* 8291 * Finish allocation. 8292 * 8293 * r0 holds class 8294 * r1 holds array length 8295 */ 8296 .LOP_NEW_ARRAY_finish: 8297 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 8298 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 8299 cmp r0, #0 @ failed? 8300 mov r2, rINST, lsr #8 @ r2<- A+ 8301 beq common_exceptionThrown @ yes, handle the exception 8302 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8303 and r2, r2, #15 @ r2<- A 8304 GET_INST_OPCODE(ip) @ extract opcode from rINST 8305 SET_VREG(r0, r2) @ vA<- r0 8306 GOTO_OPCODE(ip) @ jump to next instruction 8307 8308 /* continuation for OP_FILLED_NEW_ARRAY */ 8309 8310 /* 8311 * On entry: 8312 * r0 holds array class 8313 * r10 holds AA or BA 8314 */ 8315 .LOP_FILLED_NEW_ARRAY_continue: 8316 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 8317 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 8318 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 8319 .if 0 8320 mov r1, r10 @ r1<- AA (length) 8321 .else 8322 mov r1, r10, lsr #4 @ r1<- B (length) 8323 .endif 8324 cmp rINST, #'I' @ array of ints? 8325 cmpne rINST, #'L' @ array of objects? 8326 cmpne rINST, #'[' @ array of arrays? 8327 mov r9, r1 @ save length in r9 8328 bne .LOP_FILLED_NEW_ARRAY_notimpl @ no, not handled yet 8329 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 8330 cmp r0, #0 @ null return? 8331 beq common_exceptionThrown @ alloc failed, handle exception 8332 8333 FETCH(r1, 2) @ r1<- FEDC or CCCC 8334 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 8335 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 8336 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 8337 subs r9, r9, #1 @ length--, check for neg 8338 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 8339 bmi 2f @ was zero, bail 8340 8341 @ copy values from registers into the array 8342 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 8343 .if 0 8344 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 8345 1: ldr r3, [r2], #4 @ r3<- *r2++ 8346 subs r9, r9, #1 @ count-- 8347 str r3, [r0], #4 @ *contents++ = vX 8348 bpl 1b 8349 @ continue at 2 8350 .else 8351 cmp r9, #4 @ length was initially 5? 8352 and r2, r10, #15 @ r2<- A 8353 bne 1f @ <= 4 args, branch 8354 GET_VREG(r3, r2) @ r3<- vA 8355 sub r9, r9, #1 @ count-- 8356 str r3, [r0, #16] @ contents[4] = vA 8357 1: and r2, r1, #15 @ r2<- F/E/D/C 8358 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 8359 mov r1, r1, lsr #4 @ r1<- next reg in low 4 8360 subs r9, r9, #1 @ count-- 8361 str r3, [r0], #4 @ *contents++ = vX 8362 bpl 1b 8363 @ continue at 2 8364 .endif 8365 8366 2: 8367 ldr r0, [rSELF, #offThread_retval] @ r0<- object 8368 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 8369 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8370 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 8371 cmp r1, #'I' @ Is int array? 8372 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 8373 GOTO_OPCODE(ip) @ execute it 8374 8375 /* 8376 * Throw an exception indicating that we have not implemented this 8377 * mode of filled-new-array. 8378 */ 8379 .LOP_FILLED_NEW_ARRAY_notimpl: 8380 ldr r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY 8381 3: add r0, pc 8382 bl dvmThrowInternalError 8383 b common_exceptionThrown 8384 8385 /* 8386 * Ideally we'd only define this once, but depending on layout we can 8387 * exceed the range of the load above. 8388 */ 8389 8390 .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY: 8391 .word PCREL_REF(.LstrFilledNewArrayNotImpl,3b) 8392 8393 /* continuation for OP_FILLED_NEW_ARRAY_RANGE */ 8394 8395 /* 8396 * On entry: 8397 * r0 holds array class 8398 * r10 holds AA or BA 8399 */ 8400 .LOP_FILLED_NEW_ARRAY_RANGE_continue: 8401 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 8402 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 8403 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 8404 .if 1 8405 mov r1, r10 @ r1<- AA (length) 8406 .else 8407 mov r1, r10, lsr #4 @ r1<- B (length) 8408 .endif 8409 cmp rINST, #'I' @ array of ints? 8410 cmpne rINST, #'L' @ array of objects? 8411 cmpne rINST, #'[' @ array of arrays? 8412 mov r9, r1 @ save length in r9 8413 bne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl @ no, not handled yet 8414 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 8415 cmp r0, #0 @ null return? 8416 beq common_exceptionThrown @ alloc failed, handle exception 8417 8418 FETCH(r1, 2) @ r1<- FEDC or CCCC 8419 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 8420 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 8421 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 8422 subs r9, r9, #1 @ length--, check for neg 8423 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 8424 bmi 2f @ was zero, bail 8425 8426 @ copy values from registers into the array 8427 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 8428 .if 1 8429 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 8430 1: ldr r3, [r2], #4 @ r3<- *r2++ 8431 subs r9, r9, #1 @ count-- 8432 str r3, [r0], #4 @ *contents++ = vX 8433 bpl 1b 8434 @ continue at 2 8435 .else 8436 cmp r9, #4 @ length was initially 5? 8437 and r2, r10, #15 @ r2<- A 8438 bne 1f @ <= 4 args, branch 8439 GET_VREG(r3, r2) @ r3<- vA 8440 sub r9, r9, #1 @ count-- 8441 str r3, [r0, #16] @ contents[4] = vA 8442 1: and r2, r1, #15 @ r2<- F/E/D/C 8443 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 8444 mov r1, r1, lsr #4 @ r1<- next reg in low 4 8445 subs r9, r9, #1 @ count-- 8446 str r3, [r0], #4 @ *contents++ = vX 8447 bpl 1b 8448 @ continue at 2 8449 .endif 8450 8451 2: 8452 ldr r0, [rSELF, #offThread_retval] @ r0<- object 8453 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 8454 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8455 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 8456 cmp r1, #'I' @ Is int array? 8457 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 8458 GOTO_OPCODE(ip) @ execute it 8459 8460 /* 8461 * Throw an exception indicating that we have not implemented this 8462 * mode of filled-new-array. 8463 */ 8464 .LOP_FILLED_NEW_ARRAY_RANGE_notimpl: 8465 ldr r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE 8466 3: add r0, pc 8467 bl dvmThrowInternalError 8468 b common_exceptionThrown 8469 8470 /* 8471 * Ideally we'd only define this once, but depending on layout we can 8472 * exceed the range of the load above. 8473 */ 8474 8475 .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE: 8476 .word PCREL_REF(.LstrFilledNewArrayNotImpl,3b) 8477 8478 /* continuation for OP_CMPL_FLOAT */ 8479 8480 @ Test for NaN with a second comparison. EABI forbids testing bit 8481 @ patterns, and we can't represent 0x7fc00000 in immediate form, so 8482 @ make the library call. 8483 .LOP_CMPL_FLOAT_gt_or_nan: 8484 mov r1, r9 @ reverse order 8485 mov r0, r10 8486 bl __aeabi_cfcmple @ r0<- Z set if eq, C clear if < 8487 @bleq common_abort 8488 movcc r1, #1 @ (greater than) r1<- 1 8489 bcc .LOP_CMPL_FLOAT_finish 8490 mvn r1, #0 @ r1<- 1 or -1 for NaN 8491 b .LOP_CMPL_FLOAT_finish 8492 8493 8494 #if 0 /* "clasic" form */ 8495 FETCH(r0, 1) @ r0<- CCBB 8496 and r2, r0, #255 @ r2<- BB 8497 mov r3, r0, lsr #8 @ r3<- CC 8498 GET_VREG(r9, r2) @ r9<- vBB 8499 GET_VREG(r10, r3) @ r10<- vCC 8500 mov r0, r9 @ r0<- vBB 8501 mov r1, r10 @ r1<- vCC 8502 bl __aeabi_fcmpeq @ r0<- (vBB == vCC) 8503 cmp r0, #0 @ equal? 8504 movne r1, #0 @ yes, result is 0 8505 bne OP_CMPL_FLOAT_finish 8506 mov r0, r9 @ r0<- vBB 8507 mov r1, r10 @ r1<- vCC 8508 bl __aeabi_fcmplt @ r0<- (vBB < vCC) 8509 cmp r0, #0 @ less than? 8510 b OP_CMPL_FLOAT_continue 8511 @%break 8512 8513 OP_CMPL_FLOAT_continue: 8514 mvnne r1, #0 @ yes, result is -1 8515 bne OP_CMPL_FLOAT_finish 8516 mov r0, r9 @ r0<- vBB 8517 mov r1, r10 @ r1<- vCC 8518 bl __aeabi_fcmpgt @ r0<- (vBB > vCC) 8519 cmp r0, #0 @ greater than? 8520 beq OP_CMPL_FLOAT_nan @ no, must be NaN 8521 mov r1, #1 @ yes, result is 1 8522 @ fall through to _finish 8523 8524 OP_CMPL_FLOAT_finish: 8525 mov r3, rINST, lsr #8 @ r3<- AA 8526 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8527 SET_VREG(r1, r3) @ vAA<- r1 8528 GET_INST_OPCODE(ip) @ extract opcode from rINST 8529 GOTO_OPCODE(ip) @ jump to next instruction 8530 8531 /* 8532 * This is expected to be uncommon, so we double-branch (once to here, 8533 * again back to _finish). 8534 */ 8535 OP_CMPL_FLOAT_nan: 8536 mvn r1, #0 @ r1<- 1 or -1 for NaN 8537 b OP_CMPL_FLOAT_finish 8538 8539 #endif 8540 8541 /* continuation for OP_CMPG_FLOAT */ 8542 8543 @ Test for NaN with a second comparison. EABI forbids testing bit 8544 @ patterns, and we can't represent 0x7fc00000 in immediate form, so 8545 @ make the library call. 8546 .LOP_CMPG_FLOAT_gt_or_nan: 8547 mov r1, r9 @ reverse order 8548 mov r0, r10 8549 bl __aeabi_cfcmple @ r0<- Z set if eq, C clear if < 8550 @bleq common_abort 8551 movcc r1, #1 @ (greater than) r1<- 1 8552 bcc .LOP_CMPG_FLOAT_finish 8553 mov r1, #1 @ r1<- 1 or -1 for NaN 8554 b .LOP_CMPG_FLOAT_finish 8555 8556 8557 #if 0 /* "clasic" form */ 8558 FETCH(r0, 1) @ r0<- CCBB 8559 and r2, r0, #255 @ r2<- BB 8560 mov r3, r0, lsr #8 @ r3<- CC 8561 GET_VREG(r9, r2) @ r9<- vBB 8562 GET_VREG(r10, r3) @ r10<- vCC 8563 mov r0, r9 @ r0<- vBB 8564 mov r1, r10 @ r1<- vCC 8565 bl __aeabi_fcmpeq @ r0<- (vBB == vCC) 8566 cmp r0, #0 @ equal? 8567 movne r1, #0 @ yes, result is 0 8568 bne OP_CMPG_FLOAT_finish 8569 mov r0, r9 @ r0<- vBB 8570 mov r1, r10 @ r1<- vCC 8571 bl __aeabi_fcmplt @ r0<- (vBB < vCC) 8572 cmp r0, #0 @ less than? 8573 b OP_CMPG_FLOAT_continue 8574 @%break 8575 8576 OP_CMPG_FLOAT_continue: 8577 mvnne r1, #0 @ yes, result is -1 8578 bne OP_CMPG_FLOAT_finish 8579 mov r0, r9 @ r0<- vBB 8580 mov r1, r10 @ r1<- vCC 8581 bl __aeabi_fcmpgt @ r0<- (vBB > vCC) 8582 cmp r0, #0 @ greater than? 8583 beq OP_CMPG_FLOAT_nan @ no, must be NaN 8584 mov r1, #1 @ yes, result is 1 8585 @ fall through to _finish 8586 8587 OP_CMPG_FLOAT_finish: 8588 mov r3, rINST, lsr #8 @ r3<- AA 8589 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8590 SET_VREG(r1, r3) @ vAA<- r1 8591 GET_INST_OPCODE(ip) @ extract opcode from rINST 8592 GOTO_OPCODE(ip) @ jump to next instruction 8593 8594 /* 8595 * This is expected to be uncommon, so we double-branch (once to here, 8596 * again back to _finish). 8597 */ 8598 OP_CMPG_FLOAT_nan: 8599 mov r1, #1 @ r1<- 1 or -1 for NaN 8600 b OP_CMPG_FLOAT_finish 8601 8602 #endif 8603 8604 /* continuation for OP_CMPL_DOUBLE */ 8605 8606 @ Test for NaN with a second comparison. EABI forbids testing bit 8607 @ patterns, and we can't represent 0x7fc00000 in immediate form, so 8608 @ make the library call. 8609 .LOP_CMPL_DOUBLE_gt_or_nan: 8610 ldmia r10, {r0-r1} @ reverse order 8611 ldmia r9, {r2-r3} 8612 bl __aeabi_cdcmple @ r0<- Z set if eq, C clear if < 8613 @bleq common_abort 8614 movcc r1, #1 @ (greater than) r1<- 1 8615 bcc .LOP_CMPL_DOUBLE_finish 8616 mvn r1, #0 @ r1<- 1 or -1 for NaN 8617 b .LOP_CMPL_DOUBLE_finish 8618 8619 /* continuation for OP_CMPG_DOUBLE */ 8620 8621 @ Test for NaN with a second comparison. EABI forbids testing bit 8622 @ patterns, and we can't represent 0x7fc00000 in immediate form, so 8623 @ make the library call. 8624 .LOP_CMPG_DOUBLE_gt_or_nan: 8625 ldmia r10, {r0-r1} @ reverse order 8626 ldmia r9, {r2-r3} 8627 bl __aeabi_cdcmple @ r0<- Z set if eq, C clear if < 8628 @bleq common_abort 8629 movcc r1, #1 @ (greater than) r1<- 1 8630 bcc .LOP_CMPG_DOUBLE_finish 8631 mov r1, #1 @ r1<- 1 or -1 for NaN 8632 b .LOP_CMPG_DOUBLE_finish 8633 8634 /* continuation for OP_CMP_LONG */ 8635 8636 .LOP_CMP_LONG_less: 8637 mvn r1, #0 @ r1<- -1 8638 @ Want to cond code the next mov so we can avoid branch, but don't see it; 8639 @ instead, we just replicate the tail end. 8640 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8641 SET_VREG(r1, r9) @ vAA<- r1 8642 GET_INST_OPCODE(ip) @ extract opcode from rINST 8643 GOTO_OPCODE(ip) @ jump to next instruction 8644 8645 .LOP_CMP_LONG_greater: 8646 mov r1, #1 @ r1<- 1 8647 @ fall through to _finish 8648 8649 .LOP_CMP_LONG_finish: 8650 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8651 SET_VREG(r1, r9) @ vAA<- r1 8652 GET_INST_OPCODE(ip) @ extract opcode from rINST 8653 GOTO_OPCODE(ip) @ jump to next instruction 8654 8655 /* continuation for OP_AGET_WIDE */ 8656 8657 .LOP_AGET_WIDE_finish: 8658 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8659 ldrd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 8660 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 8661 GET_INST_OPCODE(ip) @ extract opcode from rINST 8662 stmia r9, {r2-r3} @ vAA/vAA+1<- r2/r3 8663 GOTO_OPCODE(ip) @ jump to next instruction 8664 8665 /* continuation for OP_APUT_WIDE */ 8666 8667 .LOP_APUT_WIDE_finish: 8668 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8669 ldmia r9, {r2-r3} @ r2/r3<- vAA/vAA+1 8670 GET_INST_OPCODE(ip) @ extract opcode from rINST 8671 strd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 8672 GOTO_OPCODE(ip) @ jump to next instruction 8673 8674 /* continuation for OP_APUT_OBJECT */ 8675 /* 8676 * On entry: 8677 * rINST = vBB (arrayObj) 8678 * r9 = vAA (obj) 8679 * r10 = offset into array (vBB + vCC * width) 8680 */ 8681 .LOP_APUT_OBJECT_finish: 8682 cmp r9, #0 @ storing null reference? 8683 beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks 8684 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 8685 ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz 8686 bl dvmCanPutArrayElement @ test object type vs. array type 8687 cmp r0, #0 @ okay? 8688 beq .LOP_APUT_OBJECT_throw @ no 8689 mov r1, rINST @ r1<- arrayObj 8690 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8691 ldr r2, [rSELF, #offThread_cardTable] @ get biased CT base 8692 add r10, #offArrayObject_contents @ r0<- pointer to slot 8693 GET_INST_OPCODE(ip) @ extract opcode from rINST 8694 str r9, [r10] @ vBB[vCC]<- vAA 8695 strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head 8696 GOTO_OPCODE(ip) @ jump to next instruction 8697 .LOP_APUT_OBJECT_skip_check: 8698 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8699 str r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA 8700 GET_INST_OPCODE(ip) @ extract opcode from rINST 8701 GOTO_OPCODE(ip) @ jump to next instruction 8702 .LOP_APUT_OBJECT_throw: 8703 @ The types don't match. We need to throw an ArrayStoreException. 8704 ldr r0, [r9, #offObject_clazz] 8705 ldr r1, [rINST, #offObject_clazz] 8706 EXPORT_PC() 8707 bl dvmThrowArrayStoreExceptionIncompatibleElement 8708 b common_exceptionThrown 8709 8710 /* continuation for OP_IGET */ 8711 8712 /* 8713 * Currently: 8714 * r0 holds resolved field 8715 * r9 holds object 8716 */ 8717 .LOP_IGET_finish: 8718 @bl common_squeak0 8719 cmp r9, #0 @ check object for null 8720 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8721 beq common_errNullObject @ object was null 8722 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8723 @ no-op @ acquiring load 8724 mov r2, rINST, lsr #8 @ r2<- A+ 8725 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8726 and r2, r2, #15 @ r2<- A 8727 GET_INST_OPCODE(ip) @ extract opcode from rINST 8728 SET_VREG(r0, r2) @ fp[A]<- r0 8729 GOTO_OPCODE(ip) @ jump to next instruction 8730 8731 /* continuation for OP_IGET_WIDE */ 8732 8733 /* 8734 * Currently: 8735 * r0 holds resolved field 8736 * r9 holds object 8737 */ 8738 .LOP_IGET_WIDE_finish: 8739 cmp r9, #0 @ check object for null 8740 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8741 beq common_errNullObject @ object was null 8742 .if 0 8743 add r0, r9, r3 @ r0<- address of field 8744 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 8745 .else 8746 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 8747 .endif 8748 mov r2, rINST, lsr #8 @ r2<- A+ 8749 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8750 and r2, r2, #15 @ r2<- A 8751 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 8752 GET_INST_OPCODE(ip) @ extract opcode from rINST 8753 stmia r3, {r0-r1} @ fp[A]<- r0/r1 8754 GOTO_OPCODE(ip) @ jump to next instruction 8755 8756 /* continuation for OP_IGET_OBJECT */ 8757 8758 /* 8759 * Currently: 8760 * r0 holds resolved field 8761 * r9 holds object 8762 */ 8763 .LOP_IGET_OBJECT_finish: 8764 @bl common_squeak0 8765 cmp r9, #0 @ check object for null 8766 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8767 beq common_errNullObject @ object was null 8768 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8769 @ no-op @ acquiring load 8770 mov r2, rINST, lsr #8 @ r2<- A+ 8771 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8772 and r2, r2, #15 @ r2<- A 8773 GET_INST_OPCODE(ip) @ extract opcode from rINST 8774 SET_VREG(r0, r2) @ fp[A]<- r0 8775 GOTO_OPCODE(ip) @ jump to next instruction 8776 8777 /* continuation for OP_IGET_BOOLEAN */ 8778 8779 /* 8780 * Currently: 8781 * r0 holds resolved field 8782 * r9 holds object 8783 */ 8784 .LOP_IGET_BOOLEAN_finish: 8785 @bl common_squeak1 8786 cmp r9, #0 @ check object for null 8787 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8788 beq common_errNullObject @ object was null 8789 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8790 @ no-op @ acquiring load 8791 mov r2, rINST, lsr #8 @ r2<- A+ 8792 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8793 and r2, r2, #15 @ r2<- A 8794 GET_INST_OPCODE(ip) @ extract opcode from rINST 8795 SET_VREG(r0, r2) @ fp[A]<- r0 8796 GOTO_OPCODE(ip) @ jump to next instruction 8797 8798 /* continuation for OP_IGET_BYTE */ 8799 8800 /* 8801 * Currently: 8802 * r0 holds resolved field 8803 * r9 holds object 8804 */ 8805 .LOP_IGET_BYTE_finish: 8806 @bl common_squeak2 8807 cmp r9, #0 @ check object for null 8808 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8809 beq common_errNullObject @ object was null 8810 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8811 @ no-op @ acquiring load 8812 mov r2, rINST, lsr #8 @ r2<- A+ 8813 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8814 and r2, r2, #15 @ r2<- A 8815 GET_INST_OPCODE(ip) @ extract opcode from rINST 8816 SET_VREG(r0, r2) @ fp[A]<- r0 8817 GOTO_OPCODE(ip) @ jump to next instruction 8818 8819 /* continuation for OP_IGET_CHAR */ 8820 8821 /* 8822 * Currently: 8823 * r0 holds resolved field 8824 * r9 holds object 8825 */ 8826 .LOP_IGET_CHAR_finish: 8827 @bl common_squeak3 8828 cmp r9, #0 @ check object for null 8829 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8830 beq common_errNullObject @ object was null 8831 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8832 @ no-op @ acquiring load 8833 mov r2, rINST, lsr #8 @ r2<- A+ 8834 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8835 and r2, r2, #15 @ r2<- A 8836 GET_INST_OPCODE(ip) @ extract opcode from rINST 8837 SET_VREG(r0, r2) @ fp[A]<- r0 8838 GOTO_OPCODE(ip) @ jump to next instruction 8839 8840 /* continuation for OP_IGET_SHORT */ 8841 8842 /* 8843 * Currently: 8844 * r0 holds resolved field 8845 * r9 holds object 8846 */ 8847 .LOP_IGET_SHORT_finish: 8848 @bl common_squeak4 8849 cmp r9, #0 @ check object for null 8850 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8851 beq common_errNullObject @ object was null 8852 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8853 @ no-op @ acquiring load 8854 mov r2, rINST, lsr #8 @ r2<- A+ 8855 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8856 and r2, r2, #15 @ r2<- A 8857 GET_INST_OPCODE(ip) @ extract opcode from rINST 8858 SET_VREG(r0, r2) @ fp[A]<- r0 8859 GOTO_OPCODE(ip) @ jump to next instruction 8860 8861 /* continuation for OP_IPUT */ 8862 8863 /* 8864 * Currently: 8865 * r0 holds resolved field 8866 * r9 holds object 8867 */ 8868 .LOP_IPUT_finish: 8869 @bl common_squeak0 8870 mov r1, rINST, lsr #8 @ r1<- A+ 8871 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8872 and r1, r1, #15 @ r1<- A 8873 cmp r9, #0 @ check object for null 8874 GET_VREG(r0, r1) @ r0<- fp[A] 8875 beq common_errNullObject @ object was null 8876 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8877 @ no-op @ releasing store 8878 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8879 @ no-op 8880 GET_INST_OPCODE(ip) @ extract opcode from rINST 8881 GOTO_OPCODE(ip) @ jump to next instruction 8882 8883 /* continuation for OP_IPUT_WIDE */ 8884 8885 /* 8886 * Currently: 8887 * r0 holds resolved field 8888 * r9 holds object 8889 */ 8890 .LOP_IPUT_WIDE_finish: 8891 mov r2, rINST, lsr #8 @ r2<- A+ 8892 cmp r9, #0 @ check object for null 8893 and r2, r2, #15 @ r2<- A 8894 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8895 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 8896 beq common_errNullObject @ object was null 8897 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8898 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 8899 GET_INST_OPCODE(r10) @ extract opcode from rINST 8900 .if 0 8901 add r2, r9, r3 @ r2<- target address 8902 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 8903 .else 8904 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 8905 .endif 8906 GOTO_OPCODE(r10) @ jump to next instruction 8907 8908 /* continuation for OP_IPUT_OBJECT */ 8909 8910 /* 8911 * Currently: 8912 * r0 holds resolved field 8913 * r9 holds object 8914 */ 8915 .LOP_IPUT_OBJECT_finish: 8916 @bl common_squeak0 8917 mov r1, rINST, lsr #8 @ r1<- A+ 8918 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8919 and r1, r1, #15 @ r1<- A 8920 cmp r9, #0 @ check object for null 8921 GET_VREG(r0, r1) @ r0<- fp[A] 8922 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8923 beq common_errNullObject @ object was null 8924 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8925 @ no-op @ releasing store 8926 str r0, [r9, r3] @ obj.field (32 bits)<- r0 8927 @ no-op 8928 GET_INST_OPCODE(ip) @ extract opcode from rINST 8929 cmp r0, #0 @ stored a null reference? 8930 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 8931 GOTO_OPCODE(ip) @ jump to next instruction 8932 8933 /* continuation for OP_IPUT_BOOLEAN */ 8934 8935 /* 8936 * Currently: 8937 * r0 holds resolved field 8938 * r9 holds object 8939 */ 8940 .LOP_IPUT_BOOLEAN_finish: 8941 @bl common_squeak1 8942 mov r1, rINST, lsr #8 @ r1<- A+ 8943 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8944 and r1, r1, #15 @ r1<- A 8945 cmp r9, #0 @ check object for null 8946 GET_VREG(r0, r1) @ r0<- fp[A] 8947 beq common_errNullObject @ object was null 8948 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8949 @ no-op @ releasing store 8950 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8951 @ no-op 8952 GET_INST_OPCODE(ip) @ extract opcode from rINST 8953 GOTO_OPCODE(ip) @ jump to next instruction 8954 8955 /* continuation for OP_IPUT_BYTE */ 8956 8957 /* 8958 * Currently: 8959 * r0 holds resolved field 8960 * r9 holds object 8961 */ 8962 .LOP_IPUT_BYTE_finish: 8963 @bl common_squeak2 8964 mov r1, rINST, lsr #8 @ r1<- A+ 8965 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8966 and r1, r1, #15 @ r1<- A 8967 cmp r9, #0 @ check object for null 8968 GET_VREG(r0, r1) @ r0<- fp[A] 8969 beq common_errNullObject @ object was null 8970 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8971 @ no-op @ releasing store 8972 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8973 @ no-op 8974 GET_INST_OPCODE(ip) @ extract opcode from rINST 8975 GOTO_OPCODE(ip) @ jump to next instruction 8976 8977 /* continuation for OP_IPUT_CHAR */ 8978 8979 /* 8980 * Currently: 8981 * r0 holds resolved field 8982 * r9 holds object 8983 */ 8984 .LOP_IPUT_CHAR_finish: 8985 @bl common_squeak3 8986 mov r1, rINST, lsr #8 @ r1<- A+ 8987 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8988 and r1, r1, #15 @ r1<- A 8989 cmp r9, #0 @ check object for null 8990 GET_VREG(r0, r1) @ r0<- fp[A] 8991 beq common_errNullObject @ object was null 8992 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8993 @ no-op @ releasing store 8994 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8995 @ no-op 8996 GET_INST_OPCODE(ip) @ extract opcode from rINST 8997 GOTO_OPCODE(ip) @ jump to next instruction 8998 8999 /* continuation for OP_IPUT_SHORT */ 9000 9001 /* 9002 * Currently: 9003 * r0 holds resolved field 9004 * r9 holds object 9005 */ 9006 .LOP_IPUT_SHORT_finish: 9007 @bl common_squeak4 9008 mov r1, rINST, lsr #8 @ r1<- A+ 9009 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9010 and r1, r1, #15 @ r1<- A 9011 cmp r9, #0 @ check object for null 9012 GET_VREG(r0, r1) @ r0<- fp[A] 9013 beq common_errNullObject @ object was null 9014 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9015 @ no-op @ releasing store 9016 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 9017 @ no-op 9018 GET_INST_OPCODE(ip) @ extract opcode from rINST 9019 GOTO_OPCODE(ip) @ jump to next instruction 9020 9021 /* continuation for OP_SGET */ 9022 9023 /* 9024 * Continuation if the field has not yet been resolved. 9025 * r1: BBBB field ref 9026 * r10: dvmDex->pResFields 9027 */ 9028 .LOP_SGET_resolve: 9029 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9030 #if defined(WITH_JIT) 9031 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9032 #endif 9033 EXPORT_PC() @ resolve() could throw, so export now 9034 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9035 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9036 cmp r0, #0 @ success? 9037 beq common_exceptionThrown @ no, handle exception 9038 #if defined(WITH_JIT) 9039 /* 9040 * If the JIT is actively building a trace we need to make sure 9041 * that the field is fully resolved before including this instruction. 9042 */ 9043 bl common_verifyField 9044 #endif 9045 b .LOP_SGET_finish 9046 9047 /* continuation for OP_SGET_WIDE */ 9048 9049 /* 9050 * Continuation if the field has not yet been resolved. 9051 * r1: BBBB field ref 9052 * r10: dvmDex->pResFields 9053 * 9054 * Returns StaticField pointer in r0. 9055 */ 9056 .LOP_SGET_WIDE_resolve: 9057 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9058 #if defined(WITH_JIT) 9059 add r10, r10, r1, lsl #2 @ r1<- &dvmDex->pResFields[field] 9060 #endif 9061 EXPORT_PC() @ resolve() could throw, so export now 9062 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9063 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9064 cmp r0, #0 @ success? 9065 beq common_exceptionThrown @ no, handle exception 9066 #if defined(WITH_JIT) 9067 /* 9068 * If the JIT is actively building a trace we need to make sure 9069 * that the field is fully resolved before including this instruction. 9070 */ 9071 bl common_verifyField 9072 #endif 9073 b .LOP_SGET_WIDE_finish @ resume 9074 9075 /* continuation for OP_SGET_OBJECT */ 9076 9077 /* 9078 * Continuation if the field has not yet been resolved. 9079 * r1: BBBB field ref 9080 * r10: dvmDex->pResFields 9081 */ 9082 .LOP_SGET_OBJECT_resolve: 9083 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9084 #if defined(WITH_JIT) 9085 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9086 #endif 9087 EXPORT_PC() @ resolve() could throw, so export now 9088 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9089 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9090 cmp r0, #0 @ success? 9091 beq common_exceptionThrown @ no, handle exception 9092 #if defined(WITH_JIT) 9093 /* 9094 * If the JIT is actively building a trace we need to make sure 9095 * that the field is fully resolved before including this instruction. 9096 */ 9097 bl common_verifyField 9098 #endif 9099 b .LOP_SGET_OBJECT_finish 9100 9101 /* continuation for OP_SGET_BOOLEAN */ 9102 9103 /* 9104 * Continuation if the field has not yet been resolved. 9105 * r1: BBBB field ref 9106 * r10: dvmDex->pResFields 9107 */ 9108 .LOP_SGET_BOOLEAN_resolve: 9109 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9110 #if defined(WITH_JIT) 9111 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9112 #endif 9113 EXPORT_PC() @ resolve() could throw, so export now 9114 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9115 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9116 cmp r0, #0 @ success? 9117 beq common_exceptionThrown @ no, handle exception 9118 #if defined(WITH_JIT) 9119 /* 9120 * If the JIT is actively building a trace we need to make sure 9121 * that the field is fully resolved before including this instruction. 9122 */ 9123 bl common_verifyField 9124 #endif 9125 b .LOP_SGET_BOOLEAN_finish 9126 9127 /* continuation for OP_SGET_BYTE */ 9128 9129 /* 9130 * Continuation if the field has not yet been resolved. 9131 * r1: BBBB field ref 9132 * r10: dvmDex->pResFields 9133 */ 9134 .LOP_SGET_BYTE_resolve: 9135 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9136 #if defined(WITH_JIT) 9137 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9138 #endif 9139 EXPORT_PC() @ resolve() could throw, so export now 9140 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9141 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9142 cmp r0, #0 @ success? 9143 beq common_exceptionThrown @ no, handle exception 9144 #if defined(WITH_JIT) 9145 /* 9146 * If the JIT is actively building a trace we need to make sure 9147 * that the field is fully resolved before including this instruction. 9148 */ 9149 bl common_verifyField 9150 #endif 9151 b .LOP_SGET_BYTE_finish 9152 9153 /* continuation for OP_SGET_CHAR */ 9154 9155 /* 9156 * Continuation if the field has not yet been resolved. 9157 * r1: BBBB field ref 9158 * r10: dvmDex->pResFields 9159 */ 9160 .LOP_SGET_CHAR_resolve: 9161 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9162 #if defined(WITH_JIT) 9163 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9164 #endif 9165 EXPORT_PC() @ resolve() could throw, so export now 9166 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9167 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9168 cmp r0, #0 @ success? 9169 beq common_exceptionThrown @ no, handle exception 9170 #if defined(WITH_JIT) 9171 /* 9172 * If the JIT is actively building a trace we need to make sure 9173 * that the field is fully resolved before including this instruction. 9174 */ 9175 bl common_verifyField 9176 #endif 9177 b .LOP_SGET_CHAR_finish 9178 9179 /* continuation for OP_SGET_SHORT */ 9180 9181 /* 9182 * Continuation if the field has not yet been resolved. 9183 * r1: BBBB field ref 9184 * r10: dvmDex->pResFields 9185 */ 9186 .LOP_SGET_SHORT_resolve: 9187 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9188 #if defined(WITH_JIT) 9189 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9190 #endif 9191 EXPORT_PC() @ resolve() could throw, so export now 9192 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9193 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9194 cmp r0, #0 @ success? 9195 beq common_exceptionThrown @ no, handle exception 9196 #if defined(WITH_JIT) 9197 /* 9198 * If the JIT is actively building a trace we need to make sure 9199 * that the field is fully resolved before including this instruction. 9200 */ 9201 bl common_verifyField 9202 #endif 9203 b .LOP_SGET_SHORT_finish 9204 9205 /* continuation for OP_SPUT */ 9206 9207 /* 9208 * Continuation if the field has not yet been resolved. 9209 * r1: BBBB field ref 9210 * r10: dvmDex->pResFields 9211 */ 9212 .LOP_SPUT_resolve: 9213 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9214 #if defined(WITH_JIT) 9215 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9216 #endif 9217 EXPORT_PC() @ resolve() could throw, so export now 9218 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9219 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9220 cmp r0, #0 @ success? 9221 beq common_exceptionThrown @ no, handle exception 9222 #if defined(WITH_JIT) 9223 /* 9224 * If the JIT is actively building a trace we need to make sure 9225 * that the field is fully resolved before including this instruction. 9226 */ 9227 bl common_verifyField 9228 #endif 9229 b .LOP_SPUT_finish @ resume 9230 9231 /* continuation for OP_SPUT_WIDE */ 9232 9233 /* 9234 * Continuation if the field has not yet been resolved. 9235 * r1: BBBB field ref 9236 * r9: &fp[AA] 9237 * r10: dvmDex->pResFields 9238 * 9239 * Returns StaticField pointer in r2. 9240 */ 9241 .LOP_SPUT_WIDE_resolve: 9242 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9243 #if defined(WITH_JIT) 9244 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9245 #endif 9246 EXPORT_PC() @ resolve() could throw, so export now 9247 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9248 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9249 cmp r0, #0 @ success? 9250 mov r2, r0 @ copy to r2 9251 beq common_exceptionThrown @ no, handle exception 9252 #if defined(WITH_JIT) 9253 /* 9254 * If the JIT is actively building a trace we need to make sure 9255 * that the field is fully resolved before including this instruction. 9256 */ 9257 bl common_verifyField 9258 #endif 9259 b .LOP_SPUT_WIDE_finish @ resume 9260 9261 /* continuation for OP_SPUT_OBJECT */ 9262 9263 9264 .LOP_SPUT_OBJECT_end: 9265 str r1, [r0, #offStaticField_value] @ field<- vAA 9266 @ no-op 9267 cmp r1, #0 @ stored a null object? 9268 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 9269 GOTO_OPCODE(ip) @ jump to next instruction 9270 9271 /* Continuation if the field has not yet been resolved. 9272 * r1: BBBB field ref 9273 * r10: dvmDex->pResFields 9274 */ 9275 .LOP_SPUT_OBJECT_resolve: 9276 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9277 #if defined(WITH_JIT) 9278 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9279 #endif 9280 EXPORT_PC() @ resolve() could throw, so export now 9281 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9282 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9283 cmp r0, #0 @ success? 9284 beq common_exceptionThrown @ no, handle exception 9285 #if defined(WITH_JIT) 9286 /* 9287 * If the JIT is actively building a trace we need to make sure 9288 * that the field is fully resolved before including this instruction. 9289 */ 9290 bl common_verifyField 9291 #endif 9292 b .LOP_SPUT_OBJECT_finish @ resume 9293 9294 9295 /* continuation for OP_SPUT_BOOLEAN */ 9296 9297 /* 9298 * Continuation if the field has not yet been resolved. 9299 * r1: BBBB field ref 9300 * r10: dvmDex->pResFields 9301 */ 9302 .LOP_SPUT_BOOLEAN_resolve: 9303 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9304 #if defined(WITH_JIT) 9305 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9306 #endif 9307 EXPORT_PC() @ resolve() could throw, so export now 9308 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9309 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9310 cmp r0, #0 @ success? 9311 beq common_exceptionThrown @ no, handle exception 9312 #if defined(WITH_JIT) 9313 /* 9314 * If the JIT is actively building a trace we need to make sure 9315 * that the field is fully resolved before including this instruction. 9316 */ 9317 bl common_verifyField 9318 #endif 9319 b .LOP_SPUT_BOOLEAN_finish @ resume 9320 9321 /* continuation for OP_SPUT_BYTE */ 9322 9323 /* 9324 * Continuation if the field has not yet been resolved. 9325 * r1: BBBB field ref 9326 * r10: dvmDex->pResFields 9327 */ 9328 .LOP_SPUT_BYTE_resolve: 9329 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9330 #if defined(WITH_JIT) 9331 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9332 #endif 9333 EXPORT_PC() @ resolve() could throw, so export now 9334 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9335 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9336 cmp r0, #0 @ success? 9337 beq common_exceptionThrown @ no, handle exception 9338 #if defined(WITH_JIT) 9339 /* 9340 * If the JIT is actively building a trace we need to make sure 9341 * that the field is fully resolved before including this instruction. 9342 */ 9343 bl common_verifyField 9344 #endif 9345 b .LOP_SPUT_BYTE_finish @ resume 9346 9347 /* continuation for OP_SPUT_CHAR */ 9348 9349 /* 9350 * Continuation if the field has not yet been resolved. 9351 * r1: BBBB field ref 9352 * r10: dvmDex->pResFields 9353 */ 9354 .LOP_SPUT_CHAR_resolve: 9355 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9356 #if defined(WITH_JIT) 9357 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9358 #endif 9359 EXPORT_PC() @ resolve() could throw, so export now 9360 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9361 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9362 cmp r0, #0 @ success? 9363 beq common_exceptionThrown @ no, handle exception 9364 #if defined(WITH_JIT) 9365 /* 9366 * If the JIT is actively building a trace we need to make sure 9367 * that the field is fully resolved before including this instruction. 9368 */ 9369 bl common_verifyField 9370 #endif 9371 b .LOP_SPUT_CHAR_finish @ resume 9372 9373 /* continuation for OP_SPUT_SHORT */ 9374 9375 /* 9376 * Continuation if the field has not yet been resolved. 9377 * r1: BBBB field ref 9378 * r10: dvmDex->pResFields 9379 */ 9380 .LOP_SPUT_SHORT_resolve: 9381 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9382 #if defined(WITH_JIT) 9383 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9384 #endif 9385 EXPORT_PC() @ resolve() could throw, so export now 9386 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9387 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9388 cmp r0, #0 @ success? 9389 beq common_exceptionThrown @ no, handle exception 9390 #if defined(WITH_JIT) 9391 /* 9392 * If the JIT is actively building a trace we need to make sure 9393 * that the field is fully resolved before including this instruction. 9394 */ 9395 bl common_verifyField 9396 #endif 9397 b .LOP_SPUT_SHORT_finish @ resume 9398 9399 /* continuation for OP_INVOKE_VIRTUAL */ 9400 9401 /* 9402 * At this point: 9403 * r0 = resolved base method 9404 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 9405 */ 9406 .LOP_INVOKE_VIRTUAL_continue: 9407 GET_VREG(r9, r10) @ r9<- "this" ptr 9408 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 9409 cmp r9, #0 @ is "this" null? 9410 beq common_errNullObject @ null "this", throw exception 9411 ldr r3, [r9, #offObject_clazz] @ r3<- thisPtr->clazz 9412 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 9413 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 9414 bl common_invokeMethodNoRange @ (r0=method, r9="this") 9415 9416 /* continuation for OP_INVOKE_SUPER */ 9417 9418 /* 9419 * At this point: 9420 * r0 = resolved base method 9421 * r10 = method->clazz 9422 */ 9423 .LOP_INVOKE_SUPER_continue: 9424 ldr r1, [r10, #offClassObject_super] @ r1<- method->clazz->super 9425 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 9426 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 9427 EXPORT_PC() @ must export for invoke 9428 cmp r2, r3 @ compare (methodIndex, vtableCount) 9429 bcs .LOP_INVOKE_SUPER_nsm @ method not present in superclass 9430 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 9431 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 9432 bl common_invokeMethodNoRange @ continue on 9433 9434 .LOP_INVOKE_SUPER_resolve: 9435 mov r0, r10 @ r0<- method->clazz 9436 mov r2, #METHOD_VIRTUAL @ resolver method type 9437 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9438 cmp r0, #0 @ got null? 9439 bne .LOP_INVOKE_SUPER_continue @ no, continue 9440 b common_exceptionThrown @ yes, handle exception 9441 9442 /* 9443 * Throw a NoSuchMethodError with the method name as the message. 9444 * r0 = resolved base method 9445 */ 9446 .LOP_INVOKE_SUPER_nsm: 9447 ldr r1, [r0, #offMethod_name] @ r1<- method name 9448 b common_errNoSuchMethod 9449 9450 /* continuation for OP_INVOKE_DIRECT */ 9451 9452 /* 9453 * On entry: 9454 * r1 = reference (BBBB or CCCC) 9455 * r10 = "this" register 9456 */ 9457 .LOP_INVOKE_DIRECT_resolve: 9458 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9459 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9460 mov r2, #METHOD_DIRECT @ resolver method type 9461 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9462 cmp r0, #0 @ got null? 9463 bne .LOP_INVOKE_DIRECT_finish @ no, continue 9464 b common_exceptionThrown @ yes, handle exception 9465 9466 /* continuation for OP_INVOKE_STATIC */ 9467 9468 9469 .LOP_INVOKE_STATIC_resolve: 9470 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9471 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9472 mov r2, #METHOD_STATIC @ resolver method type 9473 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9474 cmp r0, #0 @ got null? 9475 #if defined(WITH_JIT) 9476 /* 9477 * Check to see if we're actively building a trace. If so, 9478 * we need to keep this instruction out of it. 9479 * r10: &resolved_methodToCall 9480 */ 9481 ldrh r2, [rSELF, #offThread_subMode] 9482 beq common_exceptionThrown @ null, handle exception 9483 ands r2, #kSubModeJitTraceBuild @ trace under construction? 9484 beq common_invokeMethodNoRange @ no (r0=method, r9="this") 9485 ldr r1, [r10] @ reload resolved method 9486 cmp r1, #0 @ finished resolving? 9487 bne common_invokeMethodNoRange @ yes (r0=method, r9="this") 9488 mov r10, r0 @ preserve method 9489 mov r0, rSELF 9490 mov r1, rPC 9491 bl dvmJitEndTraceSelect @ (self, pc) 9492 mov r0, r10 9493 b common_invokeMethodNoRange @ whew, finally! 9494 #else 9495 bne common_invokeMethodNoRange @ (r0=method, r9="this") 9496 b common_exceptionThrown @ yes, handle exception 9497 #endif 9498 9499 /* continuation for OP_INVOKE_VIRTUAL_RANGE */ 9500 9501 /* 9502 * At this point: 9503 * r0 = resolved base method 9504 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 9505 */ 9506 .LOP_INVOKE_VIRTUAL_RANGE_continue: 9507 GET_VREG(r9, r10) @ r9<- "this" ptr 9508 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 9509 cmp r9, #0 @ is "this" null? 9510 beq common_errNullObject @ null "this", throw exception 9511 ldr r3, [r9, #offObject_clazz] @ r3<- thisPtr->clazz 9512 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 9513 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 9514 bl common_invokeMethodRange @ (r0=method, r9="this") 9515 9516 /* continuation for OP_INVOKE_SUPER_RANGE */ 9517 9518 /* 9519 * At this point: 9520 * r0 = resolved base method 9521 * r10 = method->clazz 9522 */ 9523 .LOP_INVOKE_SUPER_RANGE_continue: 9524 ldr r1, [r10, #offClassObject_super] @ r1<- method->clazz->super 9525 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 9526 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 9527 EXPORT_PC() @ must export for invoke 9528 cmp r2, r3 @ compare (methodIndex, vtableCount) 9529 bcs .LOP_INVOKE_SUPER_RANGE_nsm @ method not present in superclass 9530 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 9531 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 9532 bl common_invokeMethodRange @ continue on 9533 9534 .LOP_INVOKE_SUPER_RANGE_resolve: 9535 mov r0, r10 @ r0<- method->clazz 9536 mov r2, #METHOD_VIRTUAL @ resolver method type 9537 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9538 cmp r0, #0 @ got null? 9539 bne .LOP_INVOKE_SUPER_RANGE_continue @ no, continue 9540 b common_exceptionThrown @ yes, handle exception 9541 9542 /* 9543 * Throw a NoSuchMethodError with the method name as the message. 9544 * r0 = resolved base method 9545 */ 9546 .LOP_INVOKE_SUPER_RANGE_nsm: 9547 ldr r1, [r0, #offMethod_name] @ r1<- method name 9548 b common_errNoSuchMethod 9549 9550 /* continuation for OP_INVOKE_DIRECT_RANGE */ 9551 9552 /* 9553 * On entry: 9554 * r1 = reference (BBBB or CCCC) 9555 * r10 = "this" register 9556 */ 9557 .LOP_INVOKE_DIRECT_RANGE_resolve: 9558 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9559 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9560 mov r2, #METHOD_DIRECT @ resolver method type 9561 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9562 cmp r0, #0 @ got null? 9563 bne .LOP_INVOKE_DIRECT_RANGE_finish @ no, continue 9564 b common_exceptionThrown @ yes, handle exception 9565 9566 /* continuation for OP_INVOKE_STATIC_RANGE */ 9567 9568 9569 .LOP_INVOKE_STATIC_RANGE_resolve: 9570 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9571 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9572 mov r2, #METHOD_STATIC @ resolver method type 9573 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9574 cmp r0, #0 @ got null? 9575 #if defined(WITH_JIT) 9576 /* 9577 * Check to see if we're actively building a trace. If so, 9578 * we need to keep this instruction out of it. 9579 * r10: &resolved_methodToCall 9580 */ 9581 ldrh r2, [rSELF, #offThread_subMode] 9582 beq common_exceptionThrown @ null, handle exception 9583 ands r2, #kSubModeJitTraceBuild @ trace under construction? 9584 beq common_invokeMethodRange @ no (r0=method, r9="this") 9585 ldr r1, [r10] @ reload resolved method 9586 cmp r1, #0 @ finished resolving? 9587 bne common_invokeMethodRange @ yes (r0=method, r9="this") 9588 mov r10, r0 @ preserve method 9589 mov r0, rSELF 9590 mov r1, rPC 9591 bl dvmJitEndTraceSelect @ (self, pc) 9592 mov r0, r10 9593 b common_invokeMethodRange @ whew, finally! 9594 #else 9595 bne common_invokeMethodRange @ (r0=method, r9="this") 9596 b common_exceptionThrown @ yes, handle exception 9597 #endif 9598 9599 /* continuation for OP_FLOAT_TO_LONG */ 9600 /* 9601 * Convert the float in r0 to a long in r0/r1. 9602 * 9603 * We have to clip values to long min/max per the specification. The 9604 * expected common case is a "reasonable" value that converts directly 9605 * to modest integer. The EABI convert function isn't doing this for us. 9606 */ 9607 f2l_doconv: 9608 stmfd sp!, {r4, lr} 9609 mov r1, #0x5f000000 @ (float)maxlong 9610 mov r4, r0 9611 bl __aeabi_fcmpge @ is arg >= maxlong? 9612 cmp r0, #0 @ nonzero == yes 9613 mvnne r0, #0 @ return maxlong (7fffffff) 9614 mvnne r1, #0x80000000 9615 ldmnefd sp!, {r4, pc} 9616 9617 mov r0, r4 @ recover arg 9618 mov r1, #0xdf000000 @ (float)minlong 9619 bl __aeabi_fcmple @ is arg <= minlong? 9620 cmp r0, #0 @ nonzero == yes 9621 movne r0, #0 @ return minlong (80000000) 9622 movne r1, #0x80000000 9623 ldmnefd sp!, {r4, pc} 9624 9625 mov r0, r4 @ recover arg 9626 mov r1, r4 9627 bl __aeabi_fcmpeq @ is arg == self? 9628 cmp r0, #0 @ zero == no 9629 moveq r1, #0 @ return zero for NaN 9630 ldmeqfd sp!, {r4, pc} 9631 9632 mov r0, r4 @ recover arg 9633 bl __aeabi_f2lz @ convert float to long 9634 ldmfd sp!, {r4, pc} 9635 9636 /* continuation for OP_DOUBLE_TO_LONG */ 9637 /* 9638 * Convert the double in r0/r1 to a long in r0/r1. 9639 * 9640 * We have to clip values to long min/max per the specification. The 9641 * expected common case is a "reasonable" value that converts directly 9642 * to modest integer. The EABI convert function isn't doing this for us. 9643 */ 9644 d2l_doconv: 9645 stmfd sp!, {r4, r5, lr} @ save regs 9646 mov r3, #0x43000000 @ maxlong, as a double (high word) 9647 add r3, #0x00e00000 @ 0x43e00000 9648 mov r2, #0 @ maxlong, as a double (low word) 9649 sub sp, sp, #4 @ align for EABI 9650 mov r4, r0 @ save a copy of r0 9651 mov r5, r1 @ and r1 9652 bl __aeabi_dcmpge @ is arg >= maxlong? 9653 cmp r0, #0 @ nonzero == yes 9654 mvnne r0, #0 @ return maxlong (7fffffffffffffff) 9655 mvnne r1, #0x80000000 9656 bne 1f 9657 9658 mov r0, r4 @ recover arg 9659 mov r1, r5 9660 mov r3, #0xc3000000 @ minlong, as a double (high word) 9661 add r3, #0x00e00000 @ 0xc3e00000 9662 mov r2, #0 @ minlong, as a double (low word) 9663 bl __aeabi_dcmple @ is arg <= minlong? 9664 cmp r0, #0 @ nonzero == yes 9665 movne r0, #0 @ return minlong (8000000000000000) 9666 movne r1, #0x80000000 9667 bne 1f 9668 9669 mov r0, r4 @ recover arg 9670 mov r1, r5 9671 mov r2, r4 @ compare against self 9672 mov r3, r5 9673 bl __aeabi_dcmpeq @ is arg == self? 9674 cmp r0, #0 @ zero == no 9675 moveq r1, #0 @ return zero for NaN 9676 beq 1f 9677 9678 mov r0, r4 @ recover arg 9679 mov r1, r5 9680 bl __aeabi_d2lz @ convert double to long 9681 9682 1: 9683 add sp, sp, #4 9684 ldmfd sp!, {r4, r5, pc} 9685 9686 /* continuation for OP_MUL_LONG */ 9687 9688 .LOP_MUL_LONG_finish: 9689 GET_INST_OPCODE(ip) @ extract opcode from rINST 9690 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 9691 GOTO_OPCODE(ip) @ jump to next instruction 9692 9693 /* continuation for OP_SHL_LONG */ 9694 9695 .LOP_SHL_LONG_finish: 9696 mov r0, r0, asl r2 @ r0<- r0 << r2 9697 GET_INST_OPCODE(ip) @ extract opcode from rINST 9698 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9699 GOTO_OPCODE(ip) @ jump to next instruction 9700 9701 /* continuation for OP_SHR_LONG */ 9702 9703 .LOP_SHR_LONG_finish: 9704 mov r1, r1, asr r2 @ r1<- r1 >> r2 9705 GET_INST_OPCODE(ip) @ extract opcode from rINST 9706 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9707 GOTO_OPCODE(ip) @ jump to next instruction 9708 9709 /* continuation for OP_USHR_LONG */ 9710 9711 .LOP_USHR_LONG_finish: 9712 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 9713 GET_INST_OPCODE(ip) @ extract opcode from rINST 9714 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9715 GOTO_OPCODE(ip) @ jump to next instruction 9716 9717 /* continuation for OP_SHL_LONG_2ADDR */ 9718 9719 .LOP_SHL_LONG_2ADDR_finish: 9720 GET_INST_OPCODE(ip) @ extract opcode from rINST 9721 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9722 GOTO_OPCODE(ip) @ jump to next instruction 9723 9724 /* continuation for OP_SHR_LONG_2ADDR */ 9725 9726 .LOP_SHR_LONG_2ADDR_finish: 9727 GET_INST_OPCODE(ip) @ extract opcode from rINST 9728 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9729 GOTO_OPCODE(ip) @ jump to next instruction 9730 9731 /* continuation for OP_USHR_LONG_2ADDR */ 9732 9733 .LOP_USHR_LONG_2ADDR_finish: 9734 GET_INST_OPCODE(ip) @ extract opcode from rINST 9735 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9736 GOTO_OPCODE(ip) @ jump to next instruction 9737 9738 /* continuation for OP_IGET_VOLATILE */ 9739 9740 /* 9741 * Currently: 9742 * r0 holds resolved field 9743 * r9 holds object 9744 */ 9745 .LOP_IGET_VOLATILE_finish: 9746 @bl common_squeak0 9747 cmp r9, #0 @ check object for null 9748 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9749 beq common_errNullObject @ object was null 9750 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 9751 SMP_DMB @ acquiring load 9752 mov r2, rINST, lsr #8 @ r2<- A+ 9753 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9754 and r2, r2, #15 @ r2<- A 9755 GET_INST_OPCODE(ip) @ extract opcode from rINST 9756 SET_VREG(r0, r2) @ fp[A]<- r0 9757 GOTO_OPCODE(ip) @ jump to next instruction 9758 9759 /* continuation for OP_IPUT_VOLATILE */ 9760 9761 /* 9762 * Currently: 9763 * r0 holds resolved field 9764 * r9 holds object 9765 */ 9766 .LOP_IPUT_VOLATILE_finish: 9767 @bl common_squeak0 9768 mov r1, rINST, lsr #8 @ r1<- A+ 9769 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9770 and r1, r1, #15 @ r1<- A 9771 cmp r9, #0 @ check object for null 9772 GET_VREG(r0, r1) @ r0<- fp[A] 9773 beq common_errNullObject @ object was null 9774 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9775 SMP_DMB_ST @ releasing store 9776 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 9777 SMP_DMB 9778 GET_INST_OPCODE(ip) @ extract opcode from rINST 9779 GOTO_OPCODE(ip) @ jump to next instruction 9780 9781 /* continuation for OP_SGET_VOLATILE */ 9782 9783 /* 9784 * Continuation if the field has not yet been resolved. 9785 * r1: BBBB field ref 9786 * r10: dvmDex->pResFields 9787 */ 9788 .LOP_SGET_VOLATILE_resolve: 9789 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9790 #if defined(WITH_JIT) 9791 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9792 #endif 9793 EXPORT_PC() @ resolve() could throw, so export now 9794 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9795 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9796 cmp r0, #0 @ success? 9797 beq common_exceptionThrown @ no, handle exception 9798 #if defined(WITH_JIT) 9799 /* 9800 * If the JIT is actively building a trace we need to make sure 9801 * that the field is fully resolved before including this instruction. 9802 */ 9803 bl common_verifyField 9804 #endif 9805 b .LOP_SGET_VOLATILE_finish 9806 9807 /* continuation for OP_SPUT_VOLATILE */ 9808 9809 /* 9810 * Continuation if the field has not yet been resolved. 9811 * r1: BBBB field ref 9812 * r10: dvmDex->pResFields 9813 */ 9814 .LOP_SPUT_VOLATILE_resolve: 9815 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9816 #if defined(WITH_JIT) 9817 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9818 #endif 9819 EXPORT_PC() @ resolve() could throw, so export now 9820 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9821 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9822 cmp r0, #0 @ success? 9823 beq common_exceptionThrown @ no, handle exception 9824 #if defined(WITH_JIT) 9825 /* 9826 * If the JIT is actively building a trace we need to make sure 9827 * that the field is fully resolved before including this instruction. 9828 */ 9829 bl common_verifyField 9830 #endif 9831 b .LOP_SPUT_VOLATILE_finish @ resume 9832 9833 /* continuation for OP_IGET_OBJECT_VOLATILE */ 9834 9835 /* 9836 * Currently: 9837 * r0 holds resolved field 9838 * r9 holds object 9839 */ 9840 .LOP_IGET_OBJECT_VOLATILE_finish: 9841 @bl common_squeak0 9842 cmp r9, #0 @ check object for null 9843 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9844 beq common_errNullObject @ object was null 9845 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 9846 SMP_DMB @ acquiring load 9847 mov r2, rINST, lsr #8 @ r2<- A+ 9848 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9849 and r2, r2, #15 @ r2<- A 9850 GET_INST_OPCODE(ip) @ extract opcode from rINST 9851 SET_VREG(r0, r2) @ fp[A]<- r0 9852 GOTO_OPCODE(ip) @ jump to next instruction 9853 9854 /* continuation for OP_IGET_WIDE_VOLATILE */ 9855 9856 /* 9857 * Currently: 9858 * r0 holds resolved field 9859 * r9 holds object 9860 */ 9861 .LOP_IGET_WIDE_VOLATILE_finish: 9862 cmp r9, #0 @ check object for null 9863 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9864 beq common_errNullObject @ object was null 9865 .if 1 9866 add r0, r9, r3 @ r0<- address of field 9867 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 9868 .else 9869 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 9870 .endif 9871 mov r2, rINST, lsr #8 @ r2<- A+ 9872 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9873 and r2, r2, #15 @ r2<- A 9874 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 9875 GET_INST_OPCODE(ip) @ extract opcode from rINST 9876 stmia r3, {r0-r1} @ fp[A]<- r0/r1 9877 GOTO_OPCODE(ip) @ jump to next instruction 9878 9879 /* continuation for OP_IPUT_WIDE_VOLATILE */ 9880 9881 /* 9882 * Currently: 9883 * r0 holds resolved field 9884 * r9 holds object 9885 */ 9886 .LOP_IPUT_WIDE_VOLATILE_finish: 9887 mov r2, rINST, lsr #8 @ r2<- A+ 9888 cmp r9, #0 @ check object for null 9889 and r2, r2, #15 @ r2<- A 9890 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9891 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 9892 beq common_errNullObject @ object was null 9893 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9894 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 9895 GET_INST_OPCODE(r10) @ extract opcode from rINST 9896 .if 1 9897 add r2, r9, r3 @ r2<- target address 9898 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 9899 .else 9900 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 9901 .endif 9902 GOTO_OPCODE(r10) @ jump to next instruction 9903 9904 /* continuation for OP_SGET_WIDE_VOLATILE */ 9905 9906 /* 9907 * Continuation if the field has not yet been resolved. 9908 * r1: BBBB field ref 9909 * r10: dvmDex->pResFields 9910 * 9911 * Returns StaticField pointer in r0. 9912 */ 9913 .LOP_SGET_WIDE_VOLATILE_resolve: 9914 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9915 #if defined(WITH_JIT) 9916 add r10, r10, r1, lsl #2 @ r1<- &dvmDex->pResFields[field] 9917 #endif 9918 EXPORT_PC() @ resolve() could throw, so export now 9919 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9920 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9921 cmp r0, #0 @ success? 9922 beq common_exceptionThrown @ no, handle exception 9923 #if defined(WITH_JIT) 9924 /* 9925 * If the JIT is actively building a trace we need to make sure 9926 * that the field is fully resolved before including this instruction. 9927 */ 9928 bl common_verifyField 9929 #endif 9930 b .LOP_SGET_WIDE_VOLATILE_finish @ resume 9931 9932 /* continuation for OP_SPUT_WIDE_VOLATILE */ 9933 9934 /* 9935 * Continuation if the field has not yet been resolved. 9936 * r1: BBBB field ref 9937 * r9: &fp[AA] 9938 * r10: dvmDex->pResFields 9939 * 9940 * Returns StaticField pointer in r2. 9941 */ 9942 .LOP_SPUT_WIDE_VOLATILE_resolve: 9943 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9944 #if defined(WITH_JIT) 9945 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9946 #endif 9947 EXPORT_PC() @ resolve() could throw, so export now 9948 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9949 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9950 cmp r0, #0 @ success? 9951 mov r2, r0 @ copy to r2 9952 beq common_exceptionThrown @ no, handle exception 9953 #if defined(WITH_JIT) 9954 /* 9955 * If the JIT is actively building a trace we need to make sure 9956 * that the field is fully resolved before including this instruction. 9957 */ 9958 bl common_verifyField 9959 #endif 9960 b .LOP_SPUT_WIDE_VOLATILE_finish @ resume 9961 9962 /* continuation for OP_EXECUTE_INLINE */ 9963 9964 /* 9965 * Extract args, call function. 9966 * r0 = #of args (0-4) 9967 * r10 = call index 9968 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 9969 * 9970 * Other ideas: 9971 * - Use a jump table from the main piece to jump directly into the 9972 * AND/LDR pairs. Costs a data load, saves a branch. 9973 * - Have five separate pieces that do the loading, so we can work the 9974 * interleave a little better. Increases code size. 9975 */ 9976 .LOP_EXECUTE_INLINE_continue: 9977 rsb r0, r0, #4 @ r0<- 4-r0 9978 FETCH(rINST, 2) @ rINST<- FEDC 9979 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 9980 bl common_abort @ (skipped due to ARM prefetch) 9981 4: and ip, rINST, #0xf000 @ isolate F 9982 ldr r3, [rFP, ip, lsr #10] @ r3<- vF (shift right 12, left 2) 9983 3: and ip, rINST, #0x0f00 @ isolate E 9984 ldr r2, [rFP, ip, lsr #6] @ r2<- vE 9985 2: and ip, rINST, #0x00f0 @ isolate D 9986 ldr r1, [rFP, ip, lsr #2] @ r1<- vD 9987 1: and ip, rINST, #0x000f @ isolate C 9988 ldr r0, [rFP, ip, lsl #2] @ r0<- vC 9989 0: 9990 ldr rINST, .LOP_EXECUTE_INLINE_table @ table of InlineOperation 9991 5: add rINST, pc 9992 ldr pc, [rINST, r10, lsl #4] @ sizeof=16, "func" is first entry 9993 @ (not reached) 9994 9995 /* 9996 * We're debugging or profiling. 9997 * r10: opIndex 9998 */ 9999 .LOP_EXECUTE_INLINE_debugmode: 10000 mov r0, r10 10001 bl dvmResolveInlineNative 10002 cmp r0, #0 @ did it resolve? 10003 beq .LOP_EXECUTE_INLINE_resume @ no, just move on 10004 mov r9, r0 @ remember method 10005 mov r1, rSELF 10006 bl dvmFastMethodTraceEnter @ (method, self) 10007 add r1, rSELF, #offThread_retval@ r1<- &self->retval 10008 sub sp, sp, #8 @ make room for arg, +64 bit align 10009 mov r0, rINST, lsr #12 @ r0<- B 10010 str r1, [sp] @ push &self->retval 10011 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 10012 mov rINST, r0 @ save result of inline 10013 add sp, sp, #8 @ pop stack 10014 mov r0, r9 @ r0<- method 10015 mov r1, rSELF 10016 bl dvmFastNativeMethodTraceExit @ (method, self) 10017 cmp rINST, #0 @ test boolean result of inline 10018 beq common_exceptionThrown @ returned false, handle exception 10019 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 10020 GET_INST_OPCODE(ip) @ extract opcode from rINST 10021 GOTO_OPCODE(ip) @ jump to next instruction 10022 10023 10024 10025 10026 .LOP_EXECUTE_INLINE_table: 10027 .word PCREL_REF(gDvmInlineOpsTable,5b) 10028 10029 /* continuation for OP_EXECUTE_INLINE_RANGE */ 10030 10031 /* 10032 * Extract args, call function. 10033 * r0 = #of args (0-4) 10034 * r10 = call index 10035 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 10036 */ 10037 .LOP_EXECUTE_INLINE_RANGE_continue: 10038 rsb r0, r0, #4 @ r0<- 4-r0 10039 FETCH(r9, 2) @ r9<- CCCC 10040 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 10041 bl common_abort @ (skipped due to ARM prefetch) 10042 4: add ip, r9, #3 @ base+3 10043 GET_VREG(r3, ip) @ r3<- vBase[3] 10044 3: add ip, r9, #2 @ base+2 10045 GET_VREG(r2, ip) @ r2<- vBase[2] 10046 2: add ip, r9, #1 @ base+1 10047 GET_VREG(r1, ip) @ r1<- vBase[1] 10048 1: add ip, r9, #0 @ (nop) 10049 GET_VREG(r0, ip) @ r0<- vBase[0] 10050 0: 10051 ldr r9, .LOP_EXECUTE_INLINE_RANGE_table @ table of InlineOperation 10052 5: add r9, pc 10053 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 10054 @ (not reached) 10055 10056 10057 /* 10058 * We're debugging or profiling. 10059 * r10: opIndex 10060 */ 10061 .LOP_EXECUTE_INLINE_RANGE_debugmode: 10062 mov r0, r10 10063 bl dvmResolveInlineNative 10064 cmp r0, #0 @ did it resolve? 10065 beq .LOP_EXECUTE_INLINE_RANGE_resume @ no, just move on 10066 mov r9, r0 @ remember method 10067 mov r1, rSELF 10068 bl dvmFastMethodTraceEnter @ (method, self) 10069 add r1, rSELF, #offThread_retval@ r1<- &self->retval 10070 sub sp, sp, #8 @ make room for arg, +64 bit align 10071 mov r0, rINST, lsr #8 @ r0<- B 10072 mov rINST, r9 @ rINST<- method 10073 str r1, [sp] @ push &self->retval 10074 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 10075 mov r9, r0 @ save result of inline 10076 add sp, sp, #8 @ pop stack 10077 mov r0, rINST @ r0<- method 10078 mov r1, rSELF 10079 bl dvmFastNativeMethodTraceExit @ (method, self) 10080 cmp r9, #0 @ test boolean result of inline 10081 beq common_exceptionThrown @ returned false, handle exception 10082 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 10083 GET_INST_OPCODE(ip) @ extract opcode from rINST 10084 GOTO_OPCODE(ip) @ jump to next instruction 10085 10086 10087 10088 10089 .LOP_EXECUTE_INLINE_RANGE_table: 10090 .word PCREL_REF(gDvmInlineOpsTable,5b) 10091 10092 10093 /* continuation for OP_INVOKE_OBJECT_INIT_RANGE */ 10094 10095 .LOP_INVOKE_OBJECT_INIT_RANGE_setFinal: 10096 EXPORT_PC() @ can throw 10097 bl dvmSetFinalizable @ call dvmSetFinalizable(obj) 10098 ldr r0, [rSELF, #offThread_exception] @ r0<- self->exception 10099 cmp r0, #0 @ exception pending? 10100 bne common_exceptionThrown @ yes, handle it 10101 b .LOP_INVOKE_OBJECT_INIT_RANGE_finish 10102 10103 /* 10104 * A debugger is attached, so we need to go ahead and do 10105 * this. For simplicity, we'll just jump directly to the 10106 * corresponding handler. Note that we can't use 10107 * rIBASE here because it may be in single-step mode. 10108 * Load the primary table base directly. 10109 */ 10110 .LOP_INVOKE_OBJECT_INIT_RANGE_debugger: 10111 ldr r1, [rSELF, #offThread_mainHandlerTable] 10112 mov ip, #OP_INVOKE_DIRECT_RANGE 10113 GOTO_OPCODE_BASE(r1,ip) @ execute it 10114 10115 /* continuation for OP_IPUT_OBJECT_VOLATILE */ 10116 10117 /* 10118 * Currently: 10119 * r0 holds resolved field 10120 * r9 holds object 10121 */ 10122 .LOP_IPUT_OBJECT_VOLATILE_finish: 10123 @bl common_squeak0 10124 mov r1, rINST, lsr #8 @ r1<- A+ 10125 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 10126 and r1, r1, #15 @ r1<- A 10127 cmp r9, #0 @ check object for null 10128 GET_VREG(r0, r1) @ r0<- fp[A] 10129 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 10130 beq common_errNullObject @ object was null 10131 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10132 SMP_DMB_ST @ releasing store 10133 str r0, [r9, r3] @ obj.field (32 bits)<- r0 10134 SMP_DMB 10135 GET_INST_OPCODE(ip) @ extract opcode from rINST 10136 cmp r0, #0 @ stored a null reference? 10137 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 10138 GOTO_OPCODE(ip) @ jump to next instruction 10139 10140 /* continuation for OP_SGET_OBJECT_VOLATILE */ 10141 10142 /* 10143 * Continuation if the field has not yet been resolved. 10144 * r1: BBBB field ref 10145 * r10: dvmDex->pResFields 10146 */ 10147 .LOP_SGET_OBJECT_VOLATILE_resolve: 10148 ldr r2, [rSELF, #offThread_method] @ r2<- current method 10149 #if defined(WITH_JIT) 10150 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 10151 #endif 10152 EXPORT_PC() @ resolve() could throw, so export now 10153 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 10154 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 10155 cmp r0, #0 @ success? 10156 beq common_exceptionThrown @ no, handle exception 10157 #if defined(WITH_JIT) 10158 /* 10159 * If the JIT is actively building a trace we need to make sure 10160 * that the field is fully resolved before including this instruction. 10161 */ 10162 bl common_verifyField 10163 #endif 10164 b .LOP_SGET_OBJECT_VOLATILE_finish 10165 10166 /* continuation for OP_SPUT_OBJECT_VOLATILE */ 10167 10168 10169 .LOP_SPUT_OBJECT_VOLATILE_end: 10170 str r1, [r0, #offStaticField_value] @ field<- vAA 10171 SMP_DMB 10172 cmp r1, #0 @ stored a null object? 10173 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 10174 GOTO_OPCODE(ip) @ jump to next instruction 10175 10176 /* Continuation if the field has not yet been resolved. 10177 * r1: BBBB field ref 10178 * r10: dvmDex->pResFields 10179 */ 10180 .LOP_SPUT_OBJECT_VOLATILE_resolve: 10181 ldr r2, [rSELF, #offThread_method] @ r2<- current method 10182 #if defined(WITH_JIT) 10183 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 10184 #endif 10185 EXPORT_PC() @ resolve() could throw, so export now 10186 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 10187 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 10188 cmp r0, #0 @ success? 10189 beq common_exceptionThrown @ no, handle exception 10190 #if defined(WITH_JIT) 10191 /* 10192 * If the JIT is actively building a trace we need to make sure 10193 * that the field is fully resolved before including this instruction. 10194 */ 10195 bl common_verifyField 10196 #endif 10197 b .LOP_SPUT_OBJECT_VOLATILE_finish @ resume 10198 10199 10200 .size dvmAsmSisterStart, .-dvmAsmSisterStart 10201 .global dvmAsmSisterEnd 10202 dvmAsmSisterEnd: 10203 10204 10205 .global dvmAsmAltInstructionStart 10206 .type dvmAsmAltInstructionStart, %function 10207 .text 10208 10209 dvmAsmAltInstructionStart = .L_ALT_OP_NOP 10210 /* ------------------------------ */ 10211 .balign 64 10212 .L_ALT_OP_NOP: /* 0x00 */ 10213 /* File: armv5te/alt_stub.S */ 10214 /* 10215 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10216 * any interesting requests and then jump to the real instruction 10217 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10218 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10219 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10220 * bail to the real handler if breakFlags==0. 10221 */ 10222 ldrb r3, [rSELF, #offThread_breakFlags] 10223 adrl lr, dvmAsmInstructionStart + (0 * 64) 10224 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10225 cmp r3, #0 10226 bxeq lr @ nothing to do - jump to real handler 10227 EXPORT_PC() 10228 mov r0, rPC @ arg0 10229 mov r1, rFP @ arg1 10230 mov r2, rSELF @ arg2 10231 b dvmCheckBefore @ (dPC,dFP,self) tail call 10232 10233 /* ------------------------------ */ 10234 .balign 64 10235 .L_ALT_OP_MOVE: /* 0x01 */ 10236 /* File: armv5te/alt_stub.S */ 10237 /* 10238 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10239 * any interesting requests and then jump to the real instruction 10240 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10241 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10242 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10243 * bail to the real handler if breakFlags==0. 10244 */ 10245 ldrb r3, [rSELF, #offThread_breakFlags] 10246 adrl lr, dvmAsmInstructionStart + (1 * 64) 10247 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10248 cmp r3, #0 10249 bxeq lr @ nothing to do - jump to real handler 10250 EXPORT_PC() 10251 mov r0, rPC @ arg0 10252 mov r1, rFP @ arg1 10253 mov r2, rSELF @ arg2 10254 b dvmCheckBefore @ (dPC,dFP,self) tail call 10255 10256 /* ------------------------------ */ 10257 .balign 64 10258 .L_ALT_OP_MOVE_FROM16: /* 0x02 */ 10259 /* File: armv5te/alt_stub.S */ 10260 /* 10261 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10262 * any interesting requests and then jump to the real instruction 10263 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10264 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10265 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10266 * bail to the real handler if breakFlags==0. 10267 */ 10268 ldrb r3, [rSELF, #offThread_breakFlags] 10269 adrl lr, dvmAsmInstructionStart + (2 * 64) 10270 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10271 cmp r3, #0 10272 bxeq lr @ nothing to do - jump to real handler 10273 EXPORT_PC() 10274 mov r0, rPC @ arg0 10275 mov r1, rFP @ arg1 10276 mov r2, rSELF @ arg2 10277 b dvmCheckBefore @ (dPC,dFP,self) tail call 10278 10279 /* ------------------------------ */ 10280 .balign 64 10281 .L_ALT_OP_MOVE_16: /* 0x03 */ 10282 /* File: armv5te/alt_stub.S */ 10283 /* 10284 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10285 * any interesting requests and then jump to the real instruction 10286 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10287 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10288 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10289 * bail to the real handler if breakFlags==0. 10290 */ 10291 ldrb r3, [rSELF, #offThread_breakFlags] 10292 adrl lr, dvmAsmInstructionStart + (3 * 64) 10293 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10294 cmp r3, #0 10295 bxeq lr @ nothing to do - jump to real handler 10296 EXPORT_PC() 10297 mov r0, rPC @ arg0 10298 mov r1, rFP @ arg1 10299 mov r2, rSELF @ arg2 10300 b dvmCheckBefore @ (dPC,dFP,self) tail call 10301 10302 /* ------------------------------ */ 10303 .balign 64 10304 .L_ALT_OP_MOVE_WIDE: /* 0x04 */ 10305 /* File: armv5te/alt_stub.S */ 10306 /* 10307 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10308 * any interesting requests and then jump to the real instruction 10309 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10310 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10311 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10312 * bail to the real handler if breakFlags==0. 10313 */ 10314 ldrb r3, [rSELF, #offThread_breakFlags] 10315 adrl lr, dvmAsmInstructionStart + (4 * 64) 10316 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10317 cmp r3, #0 10318 bxeq lr @ nothing to do - jump to real handler 10319 EXPORT_PC() 10320 mov r0, rPC @ arg0 10321 mov r1, rFP @ arg1 10322 mov r2, rSELF @ arg2 10323 b dvmCheckBefore @ (dPC,dFP,self) tail call 10324 10325 /* ------------------------------ */ 10326 .balign 64 10327 .L_ALT_OP_MOVE_WIDE_FROM16: /* 0x05 */ 10328 /* File: armv5te/alt_stub.S */ 10329 /* 10330 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10331 * any interesting requests and then jump to the real instruction 10332 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10333 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10334 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10335 * bail to the real handler if breakFlags==0. 10336 */ 10337 ldrb r3, [rSELF, #offThread_breakFlags] 10338 adrl lr, dvmAsmInstructionStart + (5 * 64) 10339 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10340 cmp r3, #0 10341 bxeq lr @ nothing to do - jump to real handler 10342 EXPORT_PC() 10343 mov r0, rPC @ arg0 10344 mov r1, rFP @ arg1 10345 mov r2, rSELF @ arg2 10346 b dvmCheckBefore @ (dPC,dFP,self) tail call 10347 10348 /* ------------------------------ */ 10349 .balign 64 10350 .L_ALT_OP_MOVE_WIDE_16: /* 0x06 */ 10351 /* File: armv5te/alt_stub.S */ 10352 /* 10353 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10354 * any interesting requests and then jump to the real instruction 10355 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10356 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10357 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10358 * bail to the real handler if breakFlags==0. 10359 */ 10360 ldrb r3, [rSELF, #offThread_breakFlags] 10361 adrl lr, dvmAsmInstructionStart + (6 * 64) 10362 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10363 cmp r3, #0 10364 bxeq lr @ nothing to do - jump to real handler 10365 EXPORT_PC() 10366 mov r0, rPC @ arg0 10367 mov r1, rFP @ arg1 10368 mov r2, rSELF @ arg2 10369 b dvmCheckBefore @ (dPC,dFP,self) tail call 10370 10371 /* ------------------------------ */ 10372 .balign 64 10373 .L_ALT_OP_MOVE_OBJECT: /* 0x07 */ 10374 /* File: armv5te/alt_stub.S */ 10375 /* 10376 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10377 * any interesting requests and then jump to the real instruction 10378 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10379 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10380 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10381 * bail to the real handler if breakFlags==0. 10382 */ 10383 ldrb r3, [rSELF, #offThread_breakFlags] 10384 adrl lr, dvmAsmInstructionStart + (7 * 64) 10385 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10386 cmp r3, #0 10387 bxeq lr @ nothing to do - jump to real handler 10388 EXPORT_PC() 10389 mov r0, rPC @ arg0 10390 mov r1, rFP @ arg1 10391 mov r2, rSELF @ arg2 10392 b dvmCheckBefore @ (dPC,dFP,self) tail call 10393 10394 /* ------------------------------ */ 10395 .balign 64 10396 .L_ALT_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 10397 /* File: armv5te/alt_stub.S */ 10398 /* 10399 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10400 * any interesting requests and then jump to the real instruction 10401 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10402 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10403 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10404 * bail to the real handler if breakFlags==0. 10405 */ 10406 ldrb r3, [rSELF, #offThread_breakFlags] 10407 adrl lr, dvmAsmInstructionStart + (8 * 64) 10408 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10409 cmp r3, #0 10410 bxeq lr @ nothing to do - jump to real handler 10411 EXPORT_PC() 10412 mov r0, rPC @ arg0 10413 mov r1, rFP @ arg1 10414 mov r2, rSELF @ arg2 10415 b dvmCheckBefore @ (dPC,dFP,self) tail call 10416 10417 /* ------------------------------ */ 10418 .balign 64 10419 .L_ALT_OP_MOVE_OBJECT_16: /* 0x09 */ 10420 /* File: armv5te/alt_stub.S */ 10421 /* 10422 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10423 * any interesting requests and then jump to the real instruction 10424 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10425 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10426 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10427 * bail to the real handler if breakFlags==0. 10428 */ 10429 ldrb r3, [rSELF, #offThread_breakFlags] 10430 adrl lr, dvmAsmInstructionStart + (9 * 64) 10431 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10432 cmp r3, #0 10433 bxeq lr @ nothing to do - jump to real handler 10434 EXPORT_PC() 10435 mov r0, rPC @ arg0 10436 mov r1, rFP @ arg1 10437 mov r2, rSELF @ arg2 10438 b dvmCheckBefore @ (dPC,dFP,self) tail call 10439 10440 /* ------------------------------ */ 10441 .balign 64 10442 .L_ALT_OP_MOVE_RESULT: /* 0x0a */ 10443 /* File: armv5te/alt_stub.S */ 10444 /* 10445 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10446 * any interesting requests and then jump to the real instruction 10447 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10448 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10449 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10450 * bail to the real handler if breakFlags==0. 10451 */ 10452 ldrb r3, [rSELF, #offThread_breakFlags] 10453 adrl lr, dvmAsmInstructionStart + (10 * 64) 10454 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10455 cmp r3, #0 10456 bxeq lr @ nothing to do - jump to real handler 10457 EXPORT_PC() 10458 mov r0, rPC @ arg0 10459 mov r1, rFP @ arg1 10460 mov r2, rSELF @ arg2 10461 b dvmCheckBefore @ (dPC,dFP,self) tail call 10462 10463 /* ------------------------------ */ 10464 .balign 64 10465 .L_ALT_OP_MOVE_RESULT_WIDE: /* 0x0b */ 10466 /* File: armv5te/alt_stub.S */ 10467 /* 10468 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10469 * any interesting requests and then jump to the real instruction 10470 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10471 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10472 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10473 * bail to the real handler if breakFlags==0. 10474 */ 10475 ldrb r3, [rSELF, #offThread_breakFlags] 10476 adrl lr, dvmAsmInstructionStart + (11 * 64) 10477 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10478 cmp r3, #0 10479 bxeq lr @ nothing to do - jump to real handler 10480 EXPORT_PC() 10481 mov r0, rPC @ arg0 10482 mov r1, rFP @ arg1 10483 mov r2, rSELF @ arg2 10484 b dvmCheckBefore @ (dPC,dFP,self) tail call 10485 10486 /* ------------------------------ */ 10487 .balign 64 10488 .L_ALT_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 10489 /* File: armv5te/alt_stub.S */ 10490 /* 10491 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10492 * any interesting requests and then jump to the real instruction 10493 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10494 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10495 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10496 * bail to the real handler if breakFlags==0. 10497 */ 10498 ldrb r3, [rSELF, #offThread_breakFlags] 10499 adrl lr, dvmAsmInstructionStart + (12 * 64) 10500 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10501 cmp r3, #0 10502 bxeq lr @ nothing to do - jump to real handler 10503 EXPORT_PC() 10504 mov r0, rPC @ arg0 10505 mov r1, rFP @ arg1 10506 mov r2, rSELF @ arg2 10507 b dvmCheckBefore @ (dPC,dFP,self) tail call 10508 10509 /* ------------------------------ */ 10510 .balign 64 10511 .L_ALT_OP_MOVE_EXCEPTION: /* 0x0d */ 10512 /* File: armv5te/alt_stub.S */ 10513 /* 10514 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10515 * any interesting requests and then jump to the real instruction 10516 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10517 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10518 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10519 * bail to the real handler if breakFlags==0. 10520 */ 10521 ldrb r3, [rSELF, #offThread_breakFlags] 10522 adrl lr, dvmAsmInstructionStart + (13 * 64) 10523 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10524 cmp r3, #0 10525 bxeq lr @ nothing to do - jump to real handler 10526 EXPORT_PC() 10527 mov r0, rPC @ arg0 10528 mov r1, rFP @ arg1 10529 mov r2, rSELF @ arg2 10530 b dvmCheckBefore @ (dPC,dFP,self) tail call 10531 10532 /* ------------------------------ */ 10533 .balign 64 10534 .L_ALT_OP_RETURN_VOID: /* 0x0e */ 10535 /* File: armv5te/alt_stub.S */ 10536 /* 10537 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10538 * any interesting requests and then jump to the real instruction 10539 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10540 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10541 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10542 * bail to the real handler if breakFlags==0. 10543 */ 10544 ldrb r3, [rSELF, #offThread_breakFlags] 10545 adrl lr, dvmAsmInstructionStart + (14 * 64) 10546 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10547 cmp r3, #0 10548 bxeq lr @ nothing to do - jump to real handler 10549 EXPORT_PC() 10550 mov r0, rPC @ arg0 10551 mov r1, rFP @ arg1 10552 mov r2, rSELF @ arg2 10553 b dvmCheckBefore @ (dPC,dFP,self) tail call 10554 10555 /* ------------------------------ */ 10556 .balign 64 10557 .L_ALT_OP_RETURN: /* 0x0f */ 10558 /* File: armv5te/alt_stub.S */ 10559 /* 10560 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10561 * any interesting requests and then jump to the real instruction 10562 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10563 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10564 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10565 * bail to the real handler if breakFlags==0. 10566 */ 10567 ldrb r3, [rSELF, #offThread_breakFlags] 10568 adrl lr, dvmAsmInstructionStart + (15 * 64) 10569 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10570 cmp r3, #0 10571 bxeq lr @ nothing to do - jump to real handler 10572 EXPORT_PC() 10573 mov r0, rPC @ arg0 10574 mov r1, rFP @ arg1 10575 mov r2, rSELF @ arg2 10576 b dvmCheckBefore @ (dPC,dFP,self) tail call 10577 10578 /* ------------------------------ */ 10579 .balign 64 10580 .L_ALT_OP_RETURN_WIDE: /* 0x10 */ 10581 /* File: armv5te/alt_stub.S */ 10582 /* 10583 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10584 * any interesting requests and then jump to the real instruction 10585 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10586 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10587 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10588 * bail to the real handler if breakFlags==0. 10589 */ 10590 ldrb r3, [rSELF, #offThread_breakFlags] 10591 adrl lr, dvmAsmInstructionStart + (16 * 64) 10592 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10593 cmp r3, #0 10594 bxeq lr @ nothing to do - jump to real handler 10595 EXPORT_PC() 10596 mov r0, rPC @ arg0 10597 mov r1, rFP @ arg1 10598 mov r2, rSELF @ arg2 10599 b dvmCheckBefore @ (dPC,dFP,self) tail call 10600 10601 /* ------------------------------ */ 10602 .balign 64 10603 .L_ALT_OP_RETURN_OBJECT: /* 0x11 */ 10604 /* File: armv5te/alt_stub.S */ 10605 /* 10606 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10607 * any interesting requests and then jump to the real instruction 10608 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10609 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10610 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10611 * bail to the real handler if breakFlags==0. 10612 */ 10613 ldrb r3, [rSELF, #offThread_breakFlags] 10614 adrl lr, dvmAsmInstructionStart + (17 * 64) 10615 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10616 cmp r3, #0 10617 bxeq lr @ nothing to do - jump to real handler 10618 EXPORT_PC() 10619 mov r0, rPC @ arg0 10620 mov r1, rFP @ arg1 10621 mov r2, rSELF @ arg2 10622 b dvmCheckBefore @ (dPC,dFP,self) tail call 10623 10624 /* ------------------------------ */ 10625 .balign 64 10626 .L_ALT_OP_CONST_4: /* 0x12 */ 10627 /* File: armv5te/alt_stub.S */ 10628 /* 10629 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10630 * any interesting requests and then jump to the real instruction 10631 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10632 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10633 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10634 * bail to the real handler if breakFlags==0. 10635 */ 10636 ldrb r3, [rSELF, #offThread_breakFlags] 10637 adrl lr, dvmAsmInstructionStart + (18 * 64) 10638 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10639 cmp r3, #0 10640 bxeq lr @ nothing to do - jump to real handler 10641 EXPORT_PC() 10642 mov r0, rPC @ arg0 10643 mov r1, rFP @ arg1 10644 mov r2, rSELF @ arg2 10645 b dvmCheckBefore @ (dPC,dFP,self) tail call 10646 10647 /* ------------------------------ */ 10648 .balign 64 10649 .L_ALT_OP_CONST_16: /* 0x13 */ 10650 /* File: armv5te/alt_stub.S */ 10651 /* 10652 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10653 * any interesting requests and then jump to the real instruction 10654 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10655 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10656 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10657 * bail to the real handler if breakFlags==0. 10658 */ 10659 ldrb r3, [rSELF, #offThread_breakFlags] 10660 adrl lr, dvmAsmInstructionStart + (19 * 64) 10661 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10662 cmp r3, #0 10663 bxeq lr @ nothing to do - jump to real handler 10664 EXPORT_PC() 10665 mov r0, rPC @ arg0 10666 mov r1, rFP @ arg1 10667 mov r2, rSELF @ arg2 10668 b dvmCheckBefore @ (dPC,dFP,self) tail call 10669 10670 /* ------------------------------ */ 10671 .balign 64 10672 .L_ALT_OP_CONST: /* 0x14 */ 10673 /* File: armv5te/alt_stub.S */ 10674 /* 10675 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10676 * any interesting requests and then jump to the real instruction 10677 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10678 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10679 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10680 * bail to the real handler if breakFlags==0. 10681 */ 10682 ldrb r3, [rSELF, #offThread_breakFlags] 10683 adrl lr, dvmAsmInstructionStart + (20 * 64) 10684 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10685 cmp r3, #0 10686 bxeq lr @ nothing to do - jump to real handler 10687 EXPORT_PC() 10688 mov r0, rPC @ arg0 10689 mov r1, rFP @ arg1 10690 mov r2, rSELF @ arg2 10691 b dvmCheckBefore @ (dPC,dFP,self) tail call 10692 10693 /* ------------------------------ */ 10694 .balign 64 10695 .L_ALT_OP_CONST_HIGH16: /* 0x15 */ 10696 /* File: armv5te/alt_stub.S */ 10697 /* 10698 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10699 * any interesting requests and then jump to the real instruction 10700 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10701 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10702 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10703 * bail to the real handler if breakFlags==0. 10704 */ 10705 ldrb r3, [rSELF, #offThread_breakFlags] 10706 adrl lr, dvmAsmInstructionStart + (21 * 64) 10707 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10708 cmp r3, #0 10709 bxeq lr @ nothing to do - jump to real handler 10710 EXPORT_PC() 10711 mov r0, rPC @ arg0 10712 mov r1, rFP @ arg1 10713 mov r2, rSELF @ arg2 10714 b dvmCheckBefore @ (dPC,dFP,self) tail call 10715 10716 /* ------------------------------ */ 10717 .balign 64 10718 .L_ALT_OP_CONST_WIDE_16: /* 0x16 */ 10719 /* File: armv5te/alt_stub.S */ 10720 /* 10721 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10722 * any interesting requests and then jump to the real instruction 10723 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10724 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10725 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10726 * bail to the real handler if breakFlags==0. 10727 */ 10728 ldrb r3, [rSELF, #offThread_breakFlags] 10729 adrl lr, dvmAsmInstructionStart + (22 * 64) 10730 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10731 cmp r3, #0 10732 bxeq lr @ nothing to do - jump to real handler 10733 EXPORT_PC() 10734 mov r0, rPC @ arg0 10735 mov r1, rFP @ arg1 10736 mov r2, rSELF @ arg2 10737 b dvmCheckBefore @ (dPC,dFP,self) tail call 10738 10739 /* ------------------------------ */ 10740 .balign 64 10741 .L_ALT_OP_CONST_WIDE_32: /* 0x17 */ 10742 /* File: armv5te/alt_stub.S */ 10743 /* 10744 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10745 * any interesting requests and then jump to the real instruction 10746 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10747 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10748 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10749 * bail to the real handler if breakFlags==0. 10750 */ 10751 ldrb r3, [rSELF, #offThread_breakFlags] 10752 adrl lr, dvmAsmInstructionStart + (23 * 64) 10753 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10754 cmp r3, #0 10755 bxeq lr @ nothing to do - jump to real handler 10756 EXPORT_PC() 10757 mov r0, rPC @ arg0 10758 mov r1, rFP @ arg1 10759 mov r2, rSELF @ arg2 10760 b dvmCheckBefore @ (dPC,dFP,self) tail call 10761 10762 /* ------------------------------ */ 10763 .balign 64 10764 .L_ALT_OP_CONST_WIDE: /* 0x18 */ 10765 /* File: armv5te/alt_stub.S */ 10766 /* 10767 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10768 * any interesting requests and then jump to the real instruction 10769 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10770 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10771 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10772 * bail to the real handler if breakFlags==0. 10773 */ 10774 ldrb r3, [rSELF, #offThread_breakFlags] 10775 adrl lr, dvmAsmInstructionStart + (24 * 64) 10776 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10777 cmp r3, #0 10778 bxeq lr @ nothing to do - jump to real handler 10779 EXPORT_PC() 10780 mov r0, rPC @ arg0 10781 mov r1, rFP @ arg1 10782 mov r2, rSELF @ arg2 10783 b dvmCheckBefore @ (dPC,dFP,self) tail call 10784 10785 /* ------------------------------ */ 10786 .balign 64 10787 .L_ALT_OP_CONST_WIDE_HIGH16: /* 0x19 */ 10788 /* File: armv5te/alt_stub.S */ 10789 /* 10790 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10791 * any interesting requests and then jump to the real instruction 10792 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10793 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10794 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10795 * bail to the real handler if breakFlags==0. 10796 */ 10797 ldrb r3, [rSELF, #offThread_breakFlags] 10798 adrl lr, dvmAsmInstructionStart + (25 * 64) 10799 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10800 cmp r3, #0 10801 bxeq lr @ nothing to do - jump to real handler 10802 EXPORT_PC() 10803 mov r0, rPC @ arg0 10804 mov r1, rFP @ arg1 10805 mov r2, rSELF @ arg2 10806 b dvmCheckBefore @ (dPC,dFP,self) tail call 10807 10808 /* ------------------------------ */ 10809 .balign 64 10810 .L_ALT_OP_CONST_STRING: /* 0x1a */ 10811 /* File: armv5te/alt_stub.S */ 10812 /* 10813 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10814 * any interesting requests and then jump to the real instruction 10815 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10816 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10817 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10818 * bail to the real handler if breakFlags==0. 10819 */ 10820 ldrb r3, [rSELF, #offThread_breakFlags] 10821 adrl lr, dvmAsmInstructionStart + (26 * 64) 10822 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10823 cmp r3, #0 10824 bxeq lr @ nothing to do - jump to real handler 10825 EXPORT_PC() 10826 mov r0, rPC @ arg0 10827 mov r1, rFP @ arg1 10828 mov r2, rSELF @ arg2 10829 b dvmCheckBefore @ (dPC,dFP,self) tail call 10830 10831 /* ------------------------------ */ 10832 .balign 64 10833 .L_ALT_OP_CONST_STRING_JUMBO: /* 0x1b */ 10834 /* File: armv5te/alt_stub.S */ 10835 /* 10836 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10837 * any interesting requests and then jump to the real instruction 10838 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10839 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10840 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10841 * bail to the real handler if breakFlags==0. 10842 */ 10843 ldrb r3, [rSELF, #offThread_breakFlags] 10844 adrl lr, dvmAsmInstructionStart + (27 * 64) 10845 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10846 cmp r3, #0 10847 bxeq lr @ nothing to do - jump to real handler 10848 EXPORT_PC() 10849 mov r0, rPC @ arg0 10850 mov r1, rFP @ arg1 10851 mov r2, rSELF @ arg2 10852 b dvmCheckBefore @ (dPC,dFP,self) tail call 10853 10854 /* ------------------------------ */ 10855 .balign 64 10856 .L_ALT_OP_CONST_CLASS: /* 0x1c */ 10857 /* File: armv5te/alt_stub.S */ 10858 /* 10859 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10860 * any interesting requests and then jump to the real instruction 10861 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10862 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10863 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10864 * bail to the real handler if breakFlags==0. 10865 */ 10866 ldrb r3, [rSELF, #offThread_breakFlags] 10867 adrl lr, dvmAsmInstructionStart + (28 * 64) 10868 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10869 cmp r3, #0 10870 bxeq lr @ nothing to do - jump to real handler 10871 EXPORT_PC() 10872 mov r0, rPC @ arg0 10873 mov r1, rFP @ arg1 10874 mov r2, rSELF @ arg2 10875 b dvmCheckBefore @ (dPC,dFP,self) tail call 10876 10877 /* ------------------------------ */ 10878 .balign 64 10879 .L_ALT_OP_MONITOR_ENTER: /* 0x1d */ 10880 /* File: armv5te/alt_stub.S */ 10881 /* 10882 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10883 * any interesting requests and then jump to the real instruction 10884 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10885 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10886 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10887 * bail to the real handler if breakFlags==0. 10888 */ 10889 ldrb r3, [rSELF, #offThread_breakFlags] 10890 adrl lr, dvmAsmInstructionStart + (29 * 64) 10891 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10892 cmp r3, #0 10893 bxeq lr @ nothing to do - jump to real handler 10894 EXPORT_PC() 10895 mov r0, rPC @ arg0 10896 mov r1, rFP @ arg1 10897 mov r2, rSELF @ arg2 10898 b dvmCheckBefore @ (dPC,dFP,self) tail call 10899 10900 /* ------------------------------ */ 10901 .balign 64 10902 .L_ALT_OP_MONITOR_EXIT: /* 0x1e */ 10903 /* File: armv5te/alt_stub.S */ 10904 /* 10905 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10906 * any interesting requests and then jump to the real instruction 10907 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10908 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10909 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10910 * bail to the real handler if breakFlags==0. 10911 */ 10912 ldrb r3, [rSELF, #offThread_breakFlags] 10913 adrl lr, dvmAsmInstructionStart + (30 * 64) 10914 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10915 cmp r3, #0 10916 bxeq lr @ nothing to do - jump to real handler 10917 EXPORT_PC() 10918 mov r0, rPC @ arg0 10919 mov r1, rFP @ arg1 10920 mov r2, rSELF @ arg2 10921 b dvmCheckBefore @ (dPC,dFP,self) tail call 10922 10923 /* ------------------------------ */ 10924 .balign 64 10925 .L_ALT_OP_CHECK_CAST: /* 0x1f */ 10926 /* File: armv5te/alt_stub.S */ 10927 /* 10928 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10929 * any interesting requests and then jump to the real instruction 10930 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10931 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10932 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10933 * bail to the real handler if breakFlags==0. 10934 */ 10935 ldrb r3, [rSELF, #offThread_breakFlags] 10936 adrl lr, dvmAsmInstructionStart + (31 * 64) 10937 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10938 cmp r3, #0 10939 bxeq lr @ nothing to do - jump to real handler 10940 EXPORT_PC() 10941 mov r0, rPC @ arg0 10942 mov r1, rFP @ arg1 10943 mov r2, rSELF @ arg2 10944 b dvmCheckBefore @ (dPC,dFP,self) tail call 10945 10946 /* ------------------------------ */ 10947 .balign 64 10948 .L_ALT_OP_INSTANCE_OF: /* 0x20 */ 10949 /* File: armv5te/alt_stub.S */ 10950 /* 10951 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10952 * any interesting requests and then jump to the real instruction 10953 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10954 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10955 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10956 * bail to the real handler if breakFlags==0. 10957 */ 10958 ldrb r3, [rSELF, #offThread_breakFlags] 10959 adrl lr, dvmAsmInstructionStart + (32 * 64) 10960 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10961 cmp r3, #0 10962 bxeq lr @ nothing to do - jump to real handler 10963 EXPORT_PC() 10964 mov r0, rPC @ arg0 10965 mov r1, rFP @ arg1 10966 mov r2, rSELF @ arg2 10967 b dvmCheckBefore @ (dPC,dFP,self) tail call 10968 10969 /* ------------------------------ */ 10970 .balign 64 10971 .L_ALT_OP_ARRAY_LENGTH: /* 0x21 */ 10972 /* File: armv5te/alt_stub.S */ 10973 /* 10974 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10975 * any interesting requests and then jump to the real instruction 10976 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10977 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10978 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10979 * bail to the real handler if breakFlags==0. 10980 */ 10981 ldrb r3, [rSELF, #offThread_breakFlags] 10982 adrl lr, dvmAsmInstructionStart + (33 * 64) 10983 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10984 cmp r3, #0 10985 bxeq lr @ nothing to do - jump to real handler 10986 EXPORT_PC() 10987 mov r0, rPC @ arg0 10988 mov r1, rFP @ arg1 10989 mov r2, rSELF @ arg2 10990 b dvmCheckBefore @ (dPC,dFP,self) tail call 10991 10992 /* ------------------------------ */ 10993 .balign 64 10994 .L_ALT_OP_NEW_INSTANCE: /* 0x22 */ 10995 /* File: armv5te/alt_stub.S */ 10996 /* 10997 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10998 * any interesting requests and then jump to the real instruction 10999 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11000 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11001 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11002 * bail to the real handler if breakFlags==0. 11003 */ 11004 ldrb r3, [rSELF, #offThread_breakFlags] 11005 adrl lr, dvmAsmInstructionStart + (34 * 64) 11006 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11007 cmp r3, #0 11008 bxeq lr @ nothing to do - jump to real handler 11009 EXPORT_PC() 11010 mov r0, rPC @ arg0 11011 mov r1, rFP @ arg1 11012 mov r2, rSELF @ arg2 11013 b dvmCheckBefore @ (dPC,dFP,self) tail call 11014 11015 /* ------------------------------ */ 11016 .balign 64 11017 .L_ALT_OP_NEW_ARRAY: /* 0x23 */ 11018 /* File: armv5te/alt_stub.S */ 11019 /* 11020 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11021 * any interesting requests and then jump to the real instruction 11022 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11023 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11024 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11025 * bail to the real handler if breakFlags==0. 11026 */ 11027 ldrb r3, [rSELF, #offThread_breakFlags] 11028 adrl lr, dvmAsmInstructionStart + (35 * 64) 11029 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11030 cmp r3, #0 11031 bxeq lr @ nothing to do - jump to real handler 11032 EXPORT_PC() 11033 mov r0, rPC @ arg0 11034 mov r1, rFP @ arg1 11035 mov r2, rSELF @ arg2 11036 b dvmCheckBefore @ (dPC,dFP,self) tail call 11037 11038 /* ------------------------------ */ 11039 .balign 64 11040 .L_ALT_OP_FILLED_NEW_ARRAY: /* 0x24 */ 11041 /* File: armv5te/alt_stub.S */ 11042 /* 11043 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11044 * any interesting requests and then jump to the real instruction 11045 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11046 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11047 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11048 * bail to the real handler if breakFlags==0. 11049 */ 11050 ldrb r3, [rSELF, #offThread_breakFlags] 11051 adrl lr, dvmAsmInstructionStart + (36 * 64) 11052 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11053 cmp r3, #0 11054 bxeq lr @ nothing to do - jump to real handler 11055 EXPORT_PC() 11056 mov r0, rPC @ arg0 11057 mov r1, rFP @ arg1 11058 mov r2, rSELF @ arg2 11059 b dvmCheckBefore @ (dPC,dFP,self) tail call 11060 11061 /* ------------------------------ */ 11062 .balign 64 11063 .L_ALT_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 11064 /* File: armv5te/alt_stub.S */ 11065 /* 11066 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11067 * any interesting requests and then jump to the real instruction 11068 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11069 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11070 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11071 * bail to the real handler if breakFlags==0. 11072 */ 11073 ldrb r3, [rSELF, #offThread_breakFlags] 11074 adrl lr, dvmAsmInstructionStart + (37 * 64) 11075 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11076 cmp r3, #0 11077 bxeq lr @ nothing to do - jump to real handler 11078 EXPORT_PC() 11079 mov r0, rPC @ arg0 11080 mov r1, rFP @ arg1 11081 mov r2, rSELF @ arg2 11082 b dvmCheckBefore @ (dPC,dFP,self) tail call 11083 11084 /* ------------------------------ */ 11085 .balign 64 11086 .L_ALT_OP_FILL_ARRAY_DATA: /* 0x26 */ 11087 /* File: armv5te/alt_stub.S */ 11088 /* 11089 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11090 * any interesting requests and then jump to the real instruction 11091 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11092 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11093 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11094 * bail to the real handler if breakFlags==0. 11095 */ 11096 ldrb r3, [rSELF, #offThread_breakFlags] 11097 adrl lr, dvmAsmInstructionStart + (38 * 64) 11098 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11099 cmp r3, #0 11100 bxeq lr @ nothing to do - jump to real handler 11101 EXPORT_PC() 11102 mov r0, rPC @ arg0 11103 mov r1, rFP @ arg1 11104 mov r2, rSELF @ arg2 11105 b dvmCheckBefore @ (dPC,dFP,self) tail call 11106 11107 /* ------------------------------ */ 11108 .balign 64 11109 .L_ALT_OP_THROW: /* 0x27 */ 11110 /* File: armv5te/alt_stub.S */ 11111 /* 11112 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11113 * any interesting requests and then jump to the real instruction 11114 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11115 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11116 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11117 * bail to the real handler if breakFlags==0. 11118 */ 11119 ldrb r3, [rSELF, #offThread_breakFlags] 11120 adrl lr, dvmAsmInstructionStart + (39 * 64) 11121 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11122 cmp r3, #0 11123 bxeq lr @ nothing to do - jump to real handler 11124 EXPORT_PC() 11125 mov r0, rPC @ arg0 11126 mov r1, rFP @ arg1 11127 mov r2, rSELF @ arg2 11128 b dvmCheckBefore @ (dPC,dFP,self) tail call 11129 11130 /* ------------------------------ */ 11131 .balign 64 11132 .L_ALT_OP_GOTO: /* 0x28 */ 11133 /* File: armv5te/alt_stub.S */ 11134 /* 11135 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11136 * any interesting requests and then jump to the real instruction 11137 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11138 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11139 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11140 * bail to the real handler if breakFlags==0. 11141 */ 11142 ldrb r3, [rSELF, #offThread_breakFlags] 11143 adrl lr, dvmAsmInstructionStart + (40 * 64) 11144 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11145 cmp r3, #0 11146 bxeq lr @ nothing to do - jump to real handler 11147 EXPORT_PC() 11148 mov r0, rPC @ arg0 11149 mov r1, rFP @ arg1 11150 mov r2, rSELF @ arg2 11151 b dvmCheckBefore @ (dPC,dFP,self) tail call 11152 11153 /* ------------------------------ */ 11154 .balign 64 11155 .L_ALT_OP_GOTO_16: /* 0x29 */ 11156 /* File: armv5te/alt_stub.S */ 11157 /* 11158 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11159 * any interesting requests and then jump to the real instruction 11160 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11161 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11162 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11163 * bail to the real handler if breakFlags==0. 11164 */ 11165 ldrb r3, [rSELF, #offThread_breakFlags] 11166 adrl lr, dvmAsmInstructionStart + (41 * 64) 11167 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11168 cmp r3, #0 11169 bxeq lr @ nothing to do - jump to real handler 11170 EXPORT_PC() 11171 mov r0, rPC @ arg0 11172 mov r1, rFP @ arg1 11173 mov r2, rSELF @ arg2 11174 b dvmCheckBefore @ (dPC,dFP,self) tail call 11175 11176 /* ------------------------------ */ 11177 .balign 64 11178 .L_ALT_OP_GOTO_32: /* 0x2a */ 11179 /* File: armv5te/alt_stub.S */ 11180 /* 11181 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11182 * any interesting requests and then jump to the real instruction 11183 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11184 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11185 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11186 * bail to the real handler if breakFlags==0. 11187 */ 11188 ldrb r3, [rSELF, #offThread_breakFlags] 11189 adrl lr, dvmAsmInstructionStart + (42 * 64) 11190 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11191 cmp r3, #0 11192 bxeq lr @ nothing to do - jump to real handler 11193 EXPORT_PC() 11194 mov r0, rPC @ arg0 11195 mov r1, rFP @ arg1 11196 mov r2, rSELF @ arg2 11197 b dvmCheckBefore @ (dPC,dFP,self) tail call 11198 11199 /* ------------------------------ */ 11200 .balign 64 11201 .L_ALT_OP_PACKED_SWITCH: /* 0x2b */ 11202 /* File: armv5te/alt_stub.S */ 11203 /* 11204 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11205 * any interesting requests and then jump to the real instruction 11206 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11207 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11208 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11209 * bail to the real handler if breakFlags==0. 11210 */ 11211 ldrb r3, [rSELF, #offThread_breakFlags] 11212 adrl lr, dvmAsmInstructionStart + (43 * 64) 11213 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11214 cmp r3, #0 11215 bxeq lr @ nothing to do - jump to real handler 11216 EXPORT_PC() 11217 mov r0, rPC @ arg0 11218 mov r1, rFP @ arg1 11219 mov r2, rSELF @ arg2 11220 b dvmCheckBefore @ (dPC,dFP,self) tail call 11221 11222 /* ------------------------------ */ 11223 .balign 64 11224 .L_ALT_OP_SPARSE_SWITCH: /* 0x2c */ 11225 /* File: armv5te/alt_stub.S */ 11226 /* 11227 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11228 * any interesting requests and then jump to the real instruction 11229 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11230 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11231 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11232 * bail to the real handler if breakFlags==0. 11233 */ 11234 ldrb r3, [rSELF, #offThread_breakFlags] 11235 adrl lr, dvmAsmInstructionStart + (44 * 64) 11236 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11237 cmp r3, #0 11238 bxeq lr @ nothing to do - jump to real handler 11239 EXPORT_PC() 11240 mov r0, rPC @ arg0 11241 mov r1, rFP @ arg1 11242 mov r2, rSELF @ arg2 11243 b dvmCheckBefore @ (dPC,dFP,self) tail call 11244 11245 /* ------------------------------ */ 11246 .balign 64 11247 .L_ALT_OP_CMPL_FLOAT: /* 0x2d */ 11248 /* File: armv5te/alt_stub.S */ 11249 /* 11250 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11251 * any interesting requests and then jump to the real instruction 11252 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11253 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11254 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11255 * bail to the real handler if breakFlags==0. 11256 */ 11257 ldrb r3, [rSELF, #offThread_breakFlags] 11258 adrl lr, dvmAsmInstructionStart + (45 * 64) 11259 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11260 cmp r3, #0 11261 bxeq lr @ nothing to do - jump to real handler 11262 EXPORT_PC() 11263 mov r0, rPC @ arg0 11264 mov r1, rFP @ arg1 11265 mov r2, rSELF @ arg2 11266 b dvmCheckBefore @ (dPC,dFP,self) tail call 11267 11268 /* ------------------------------ */ 11269 .balign 64 11270 .L_ALT_OP_CMPG_FLOAT: /* 0x2e */ 11271 /* File: armv5te/alt_stub.S */ 11272 /* 11273 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11274 * any interesting requests and then jump to the real instruction 11275 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11276 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11277 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11278 * bail to the real handler if breakFlags==0. 11279 */ 11280 ldrb r3, [rSELF, #offThread_breakFlags] 11281 adrl lr, dvmAsmInstructionStart + (46 * 64) 11282 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11283 cmp r3, #0 11284 bxeq lr @ nothing to do - jump to real handler 11285 EXPORT_PC() 11286 mov r0, rPC @ arg0 11287 mov r1, rFP @ arg1 11288 mov r2, rSELF @ arg2 11289 b dvmCheckBefore @ (dPC,dFP,self) tail call 11290 11291 /* ------------------------------ */ 11292 .balign 64 11293 .L_ALT_OP_CMPL_DOUBLE: /* 0x2f */ 11294 /* File: armv5te/alt_stub.S */ 11295 /* 11296 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11297 * any interesting requests and then jump to the real instruction 11298 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11299 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11300 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11301 * bail to the real handler if breakFlags==0. 11302 */ 11303 ldrb r3, [rSELF, #offThread_breakFlags] 11304 adrl lr, dvmAsmInstructionStart + (47 * 64) 11305 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11306 cmp r3, #0 11307 bxeq lr @ nothing to do - jump to real handler 11308 EXPORT_PC() 11309 mov r0, rPC @ arg0 11310 mov r1, rFP @ arg1 11311 mov r2, rSELF @ arg2 11312 b dvmCheckBefore @ (dPC,dFP,self) tail call 11313 11314 /* ------------------------------ */ 11315 .balign 64 11316 .L_ALT_OP_CMPG_DOUBLE: /* 0x30 */ 11317 /* File: armv5te/alt_stub.S */ 11318 /* 11319 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11320 * any interesting requests and then jump to the real instruction 11321 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11322 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11323 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11324 * bail to the real handler if breakFlags==0. 11325 */ 11326 ldrb r3, [rSELF, #offThread_breakFlags] 11327 adrl lr, dvmAsmInstructionStart + (48 * 64) 11328 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11329 cmp r3, #0 11330 bxeq lr @ nothing to do - jump to real handler 11331 EXPORT_PC() 11332 mov r0, rPC @ arg0 11333 mov r1, rFP @ arg1 11334 mov r2, rSELF @ arg2 11335 b dvmCheckBefore @ (dPC,dFP,self) tail call 11336 11337 /* ------------------------------ */ 11338 .balign 64 11339 .L_ALT_OP_CMP_LONG: /* 0x31 */ 11340 /* File: armv5te/alt_stub.S */ 11341 /* 11342 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11343 * any interesting requests and then jump to the real instruction 11344 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11345 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11346 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11347 * bail to the real handler if breakFlags==0. 11348 */ 11349 ldrb r3, [rSELF, #offThread_breakFlags] 11350 adrl lr, dvmAsmInstructionStart + (49 * 64) 11351 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11352 cmp r3, #0 11353 bxeq lr @ nothing to do - jump to real handler 11354 EXPORT_PC() 11355 mov r0, rPC @ arg0 11356 mov r1, rFP @ arg1 11357 mov r2, rSELF @ arg2 11358 b dvmCheckBefore @ (dPC,dFP,self) tail call 11359 11360 /* ------------------------------ */ 11361 .balign 64 11362 .L_ALT_OP_IF_EQ: /* 0x32 */ 11363 /* File: armv5te/alt_stub.S */ 11364 /* 11365 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11366 * any interesting requests and then jump to the real instruction 11367 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11368 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11369 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11370 * bail to the real handler if breakFlags==0. 11371 */ 11372 ldrb r3, [rSELF, #offThread_breakFlags] 11373 adrl lr, dvmAsmInstructionStart + (50 * 64) 11374 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11375 cmp r3, #0 11376 bxeq lr @ nothing to do - jump to real handler 11377 EXPORT_PC() 11378 mov r0, rPC @ arg0 11379 mov r1, rFP @ arg1 11380 mov r2, rSELF @ arg2 11381 b dvmCheckBefore @ (dPC,dFP,self) tail call 11382 11383 /* ------------------------------ */ 11384 .balign 64 11385 .L_ALT_OP_IF_NE: /* 0x33 */ 11386 /* File: armv5te/alt_stub.S */ 11387 /* 11388 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11389 * any interesting requests and then jump to the real instruction 11390 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11391 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11392 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11393 * bail to the real handler if breakFlags==0. 11394 */ 11395 ldrb r3, [rSELF, #offThread_breakFlags] 11396 adrl lr, dvmAsmInstructionStart + (51 * 64) 11397 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11398 cmp r3, #0 11399 bxeq lr @ nothing to do - jump to real handler 11400 EXPORT_PC() 11401 mov r0, rPC @ arg0 11402 mov r1, rFP @ arg1 11403 mov r2, rSELF @ arg2 11404 b dvmCheckBefore @ (dPC,dFP,self) tail call 11405 11406 /* ------------------------------ */ 11407 .balign 64 11408 .L_ALT_OP_IF_LT: /* 0x34 */ 11409 /* File: armv5te/alt_stub.S */ 11410 /* 11411 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11412 * any interesting requests and then jump to the real instruction 11413 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11414 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11415 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11416 * bail to the real handler if breakFlags==0. 11417 */ 11418 ldrb r3, [rSELF, #offThread_breakFlags] 11419 adrl lr, dvmAsmInstructionStart + (52 * 64) 11420 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11421 cmp r3, #0 11422 bxeq lr @ nothing to do - jump to real handler 11423 EXPORT_PC() 11424 mov r0, rPC @ arg0 11425 mov r1, rFP @ arg1 11426 mov r2, rSELF @ arg2 11427 b dvmCheckBefore @ (dPC,dFP,self) tail call 11428 11429 /* ------------------------------ */ 11430 .balign 64 11431 .L_ALT_OP_IF_GE: /* 0x35 */ 11432 /* File: armv5te/alt_stub.S */ 11433 /* 11434 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11435 * any interesting requests and then jump to the real instruction 11436 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11437 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11438 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11439 * bail to the real handler if breakFlags==0. 11440 */ 11441 ldrb r3, [rSELF, #offThread_breakFlags] 11442 adrl lr, dvmAsmInstructionStart + (53 * 64) 11443 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11444 cmp r3, #0 11445 bxeq lr @ nothing to do - jump to real handler 11446 EXPORT_PC() 11447 mov r0, rPC @ arg0 11448 mov r1, rFP @ arg1 11449 mov r2, rSELF @ arg2 11450 b dvmCheckBefore @ (dPC,dFP,self) tail call 11451 11452 /* ------------------------------ */ 11453 .balign 64 11454 .L_ALT_OP_IF_GT: /* 0x36 */ 11455 /* File: armv5te/alt_stub.S */ 11456 /* 11457 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11458 * any interesting requests and then jump to the real instruction 11459 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11460 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11461 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11462 * bail to the real handler if breakFlags==0. 11463 */ 11464 ldrb r3, [rSELF, #offThread_breakFlags] 11465 adrl lr, dvmAsmInstructionStart + (54 * 64) 11466 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11467 cmp r3, #0 11468 bxeq lr @ nothing to do - jump to real handler 11469 EXPORT_PC() 11470 mov r0, rPC @ arg0 11471 mov r1, rFP @ arg1 11472 mov r2, rSELF @ arg2 11473 b dvmCheckBefore @ (dPC,dFP,self) tail call 11474 11475 /* ------------------------------ */ 11476 .balign 64 11477 .L_ALT_OP_IF_LE: /* 0x37 */ 11478 /* File: armv5te/alt_stub.S */ 11479 /* 11480 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11481 * any interesting requests and then jump to the real instruction 11482 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11483 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11484 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11485 * bail to the real handler if breakFlags==0. 11486 */ 11487 ldrb r3, [rSELF, #offThread_breakFlags] 11488 adrl lr, dvmAsmInstructionStart + (55 * 64) 11489 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11490 cmp r3, #0 11491 bxeq lr @ nothing to do - jump to real handler 11492 EXPORT_PC() 11493 mov r0, rPC @ arg0 11494 mov r1, rFP @ arg1 11495 mov r2, rSELF @ arg2 11496 b dvmCheckBefore @ (dPC,dFP,self) tail call 11497 11498 /* ------------------------------ */ 11499 .balign 64 11500 .L_ALT_OP_IF_EQZ: /* 0x38 */ 11501 /* File: armv5te/alt_stub.S */ 11502 /* 11503 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11504 * any interesting requests and then jump to the real instruction 11505 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11506 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11507 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11508 * bail to the real handler if breakFlags==0. 11509 */ 11510 ldrb r3, [rSELF, #offThread_breakFlags] 11511 adrl lr, dvmAsmInstructionStart + (56 * 64) 11512 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11513 cmp r3, #0 11514 bxeq lr @ nothing to do - jump to real handler 11515 EXPORT_PC() 11516 mov r0, rPC @ arg0 11517 mov r1, rFP @ arg1 11518 mov r2, rSELF @ arg2 11519 b dvmCheckBefore @ (dPC,dFP,self) tail call 11520 11521 /* ------------------------------ */ 11522 .balign 64 11523 .L_ALT_OP_IF_NEZ: /* 0x39 */ 11524 /* File: armv5te/alt_stub.S */ 11525 /* 11526 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11527 * any interesting requests and then jump to the real instruction 11528 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11529 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11530 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11531 * bail to the real handler if breakFlags==0. 11532 */ 11533 ldrb r3, [rSELF, #offThread_breakFlags] 11534 adrl lr, dvmAsmInstructionStart + (57 * 64) 11535 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11536 cmp r3, #0 11537 bxeq lr @ nothing to do - jump to real handler 11538 EXPORT_PC() 11539 mov r0, rPC @ arg0 11540 mov r1, rFP @ arg1 11541 mov r2, rSELF @ arg2 11542 b dvmCheckBefore @ (dPC,dFP,self) tail call 11543 11544 /* ------------------------------ */ 11545 .balign 64 11546 .L_ALT_OP_IF_LTZ: /* 0x3a */ 11547 /* File: armv5te/alt_stub.S */ 11548 /* 11549 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11550 * any interesting requests and then jump to the real instruction 11551 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11552 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11553 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11554 * bail to the real handler if breakFlags==0. 11555 */ 11556 ldrb r3, [rSELF, #offThread_breakFlags] 11557 adrl lr, dvmAsmInstructionStart + (58 * 64) 11558 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11559 cmp r3, #0 11560 bxeq lr @ nothing to do - jump to real handler 11561 EXPORT_PC() 11562 mov r0, rPC @ arg0 11563 mov r1, rFP @ arg1 11564 mov r2, rSELF @ arg2 11565 b dvmCheckBefore @ (dPC,dFP,self) tail call 11566 11567 /* ------------------------------ */ 11568 .balign 64 11569 .L_ALT_OP_IF_GEZ: /* 0x3b */ 11570 /* File: armv5te/alt_stub.S */ 11571 /* 11572 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11573 * any interesting requests and then jump to the real instruction 11574 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11575 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11576 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11577 * bail to the real handler if breakFlags==0. 11578 */ 11579 ldrb r3, [rSELF, #offThread_breakFlags] 11580 adrl lr, dvmAsmInstructionStart + (59 * 64) 11581 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11582 cmp r3, #0 11583 bxeq lr @ nothing to do - jump to real handler 11584 EXPORT_PC() 11585 mov r0, rPC @ arg0 11586 mov r1, rFP @ arg1 11587 mov r2, rSELF @ arg2 11588 b dvmCheckBefore @ (dPC,dFP,self) tail call 11589 11590 /* ------------------------------ */ 11591 .balign 64 11592 .L_ALT_OP_IF_GTZ: /* 0x3c */ 11593 /* File: armv5te/alt_stub.S */ 11594 /* 11595 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11596 * any interesting requests and then jump to the real instruction 11597 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11598 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11599 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11600 * bail to the real handler if breakFlags==0. 11601 */ 11602 ldrb r3, [rSELF, #offThread_breakFlags] 11603 adrl lr, dvmAsmInstructionStart + (60 * 64) 11604 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11605 cmp r3, #0 11606 bxeq lr @ nothing to do - jump to real handler 11607 EXPORT_PC() 11608 mov r0, rPC @ arg0 11609 mov r1, rFP @ arg1 11610 mov r2, rSELF @ arg2 11611 b dvmCheckBefore @ (dPC,dFP,self) tail call 11612 11613 /* ------------------------------ */ 11614 .balign 64 11615 .L_ALT_OP_IF_LEZ: /* 0x3d */ 11616 /* File: armv5te/alt_stub.S */ 11617 /* 11618 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11619 * any interesting requests and then jump to the real instruction 11620 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11621 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11622 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11623 * bail to the real handler if breakFlags==0. 11624 */ 11625 ldrb r3, [rSELF, #offThread_breakFlags] 11626 adrl lr, dvmAsmInstructionStart + (61 * 64) 11627 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11628 cmp r3, #0 11629 bxeq lr @ nothing to do - jump to real handler 11630 EXPORT_PC() 11631 mov r0, rPC @ arg0 11632 mov r1, rFP @ arg1 11633 mov r2, rSELF @ arg2 11634 b dvmCheckBefore @ (dPC,dFP,self) tail call 11635 11636 /* ------------------------------ */ 11637 .balign 64 11638 .L_ALT_OP_UNUSED_3E: /* 0x3e */ 11639 /* File: armv5te/alt_stub.S */ 11640 /* 11641 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11642 * any interesting requests and then jump to the real instruction 11643 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11644 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11645 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11646 * bail to the real handler if breakFlags==0. 11647 */ 11648 ldrb r3, [rSELF, #offThread_breakFlags] 11649 adrl lr, dvmAsmInstructionStart + (62 * 64) 11650 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11651 cmp r3, #0 11652 bxeq lr @ nothing to do - jump to real handler 11653 EXPORT_PC() 11654 mov r0, rPC @ arg0 11655 mov r1, rFP @ arg1 11656 mov r2, rSELF @ arg2 11657 b dvmCheckBefore @ (dPC,dFP,self) tail call 11658 11659 /* ------------------------------ */ 11660 .balign 64 11661 .L_ALT_OP_UNUSED_3F: /* 0x3f */ 11662 /* File: armv5te/alt_stub.S */ 11663 /* 11664 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11665 * any interesting requests and then jump to the real instruction 11666 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11667 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11668 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11669 * bail to the real handler if breakFlags==0. 11670 */ 11671 ldrb r3, [rSELF, #offThread_breakFlags] 11672 adrl lr, dvmAsmInstructionStart + (63 * 64) 11673 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11674 cmp r3, #0 11675 bxeq lr @ nothing to do - jump to real handler 11676 EXPORT_PC() 11677 mov r0, rPC @ arg0 11678 mov r1, rFP @ arg1 11679 mov r2, rSELF @ arg2 11680 b dvmCheckBefore @ (dPC,dFP,self) tail call 11681 11682 /* ------------------------------ */ 11683 .balign 64 11684 .L_ALT_OP_UNUSED_40: /* 0x40 */ 11685 /* File: armv5te/alt_stub.S */ 11686 /* 11687 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11688 * any interesting requests and then jump to the real instruction 11689 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11690 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11691 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11692 * bail to the real handler if breakFlags==0. 11693 */ 11694 ldrb r3, [rSELF, #offThread_breakFlags] 11695 adrl lr, dvmAsmInstructionStart + (64 * 64) 11696 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11697 cmp r3, #0 11698 bxeq lr @ nothing to do - jump to real handler 11699 EXPORT_PC() 11700 mov r0, rPC @ arg0 11701 mov r1, rFP @ arg1 11702 mov r2, rSELF @ arg2 11703 b dvmCheckBefore @ (dPC,dFP,self) tail call 11704 11705 /* ------------------------------ */ 11706 .balign 64 11707 .L_ALT_OP_UNUSED_41: /* 0x41 */ 11708 /* File: armv5te/alt_stub.S */ 11709 /* 11710 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11711 * any interesting requests and then jump to the real instruction 11712 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11713 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11714 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11715 * bail to the real handler if breakFlags==0. 11716 */ 11717 ldrb r3, [rSELF, #offThread_breakFlags] 11718 adrl lr, dvmAsmInstructionStart + (65 * 64) 11719 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11720 cmp r3, #0 11721 bxeq lr @ nothing to do - jump to real handler 11722 EXPORT_PC() 11723 mov r0, rPC @ arg0 11724 mov r1, rFP @ arg1 11725 mov r2, rSELF @ arg2 11726 b dvmCheckBefore @ (dPC,dFP,self) tail call 11727 11728 /* ------------------------------ */ 11729 .balign 64 11730 .L_ALT_OP_UNUSED_42: /* 0x42 */ 11731 /* File: armv5te/alt_stub.S */ 11732 /* 11733 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11734 * any interesting requests and then jump to the real instruction 11735 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11736 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11737 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11738 * bail to the real handler if breakFlags==0. 11739 */ 11740 ldrb r3, [rSELF, #offThread_breakFlags] 11741 adrl lr, dvmAsmInstructionStart + (66 * 64) 11742 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11743 cmp r3, #0 11744 bxeq lr @ nothing to do - jump to real handler 11745 EXPORT_PC() 11746 mov r0, rPC @ arg0 11747 mov r1, rFP @ arg1 11748 mov r2, rSELF @ arg2 11749 b dvmCheckBefore @ (dPC,dFP,self) tail call 11750 11751 /* ------------------------------ */ 11752 .balign 64 11753 .L_ALT_OP_UNUSED_43: /* 0x43 */ 11754 /* File: armv5te/alt_stub.S */ 11755 /* 11756 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11757 * any interesting requests and then jump to the real instruction 11758 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11759 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11760 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11761 * bail to the real handler if breakFlags==0. 11762 */ 11763 ldrb r3, [rSELF, #offThread_breakFlags] 11764 adrl lr, dvmAsmInstructionStart + (67 * 64) 11765 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11766 cmp r3, #0 11767 bxeq lr @ nothing to do - jump to real handler 11768 EXPORT_PC() 11769 mov r0, rPC @ arg0 11770 mov r1, rFP @ arg1 11771 mov r2, rSELF @ arg2 11772 b dvmCheckBefore @ (dPC,dFP,self) tail call 11773 11774 /* ------------------------------ */ 11775 .balign 64 11776 .L_ALT_OP_AGET: /* 0x44 */ 11777 /* File: armv5te/alt_stub.S */ 11778 /* 11779 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11780 * any interesting requests and then jump to the real instruction 11781 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11782 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11783 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11784 * bail to the real handler if breakFlags==0. 11785 */ 11786 ldrb r3, [rSELF, #offThread_breakFlags] 11787 adrl lr, dvmAsmInstructionStart + (68 * 64) 11788 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11789 cmp r3, #0 11790 bxeq lr @ nothing to do - jump to real handler 11791 EXPORT_PC() 11792 mov r0, rPC @ arg0 11793 mov r1, rFP @ arg1 11794 mov r2, rSELF @ arg2 11795 b dvmCheckBefore @ (dPC,dFP,self) tail call 11796 11797 /* ------------------------------ */ 11798 .balign 64 11799 .L_ALT_OP_AGET_WIDE: /* 0x45 */ 11800 /* File: armv5te/alt_stub.S */ 11801 /* 11802 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11803 * any interesting requests and then jump to the real instruction 11804 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11805 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11806 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11807 * bail to the real handler if breakFlags==0. 11808 */ 11809 ldrb r3, [rSELF, #offThread_breakFlags] 11810 adrl lr, dvmAsmInstructionStart + (69 * 64) 11811 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11812 cmp r3, #0 11813 bxeq lr @ nothing to do - jump to real handler 11814 EXPORT_PC() 11815 mov r0, rPC @ arg0 11816 mov r1, rFP @ arg1 11817 mov r2, rSELF @ arg2 11818 b dvmCheckBefore @ (dPC,dFP,self) tail call 11819 11820 /* ------------------------------ */ 11821 .balign 64 11822 .L_ALT_OP_AGET_OBJECT: /* 0x46 */ 11823 /* File: armv5te/alt_stub.S */ 11824 /* 11825 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11826 * any interesting requests and then jump to the real instruction 11827 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11828 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11829 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11830 * bail to the real handler if breakFlags==0. 11831 */ 11832 ldrb r3, [rSELF, #offThread_breakFlags] 11833 adrl lr, dvmAsmInstructionStart + (70 * 64) 11834 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11835 cmp r3, #0 11836 bxeq lr @ nothing to do - jump to real handler 11837 EXPORT_PC() 11838 mov r0, rPC @ arg0 11839 mov r1, rFP @ arg1 11840 mov r2, rSELF @ arg2 11841 b dvmCheckBefore @ (dPC,dFP,self) tail call 11842 11843 /* ------------------------------ */ 11844 .balign 64 11845 .L_ALT_OP_AGET_BOOLEAN: /* 0x47 */ 11846 /* File: armv5te/alt_stub.S */ 11847 /* 11848 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11849 * any interesting requests and then jump to the real instruction 11850 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11851 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11852 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11853 * bail to the real handler if breakFlags==0. 11854 */ 11855 ldrb r3, [rSELF, #offThread_breakFlags] 11856 adrl lr, dvmAsmInstructionStart + (71 * 64) 11857 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11858 cmp r3, #0 11859 bxeq lr @ nothing to do - jump to real handler 11860 EXPORT_PC() 11861 mov r0, rPC @ arg0 11862 mov r1, rFP @ arg1 11863 mov r2, rSELF @ arg2 11864 b dvmCheckBefore @ (dPC,dFP,self) tail call 11865 11866 /* ------------------------------ */ 11867 .balign 64 11868 .L_ALT_OP_AGET_BYTE: /* 0x48 */ 11869 /* File: armv5te/alt_stub.S */ 11870 /* 11871 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11872 * any interesting requests and then jump to the real instruction 11873 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11874 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11875 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11876 * bail to the real handler if breakFlags==0. 11877 */ 11878 ldrb r3, [rSELF, #offThread_breakFlags] 11879 adrl lr, dvmAsmInstructionStart + (72 * 64) 11880 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11881 cmp r3, #0 11882 bxeq lr @ nothing to do - jump to real handler 11883 EXPORT_PC() 11884 mov r0, rPC @ arg0 11885 mov r1, rFP @ arg1 11886 mov r2, rSELF @ arg2 11887 b dvmCheckBefore @ (dPC,dFP,self) tail call 11888 11889 /* ------------------------------ */ 11890 .balign 64 11891 .L_ALT_OP_AGET_CHAR: /* 0x49 */ 11892 /* File: armv5te/alt_stub.S */ 11893 /* 11894 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11895 * any interesting requests and then jump to the real instruction 11896 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11897 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11898 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11899 * bail to the real handler if breakFlags==0. 11900 */ 11901 ldrb r3, [rSELF, #offThread_breakFlags] 11902 adrl lr, dvmAsmInstructionStart + (73 * 64) 11903 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11904 cmp r3, #0 11905 bxeq lr @ nothing to do - jump to real handler 11906 EXPORT_PC() 11907 mov r0, rPC @ arg0 11908 mov r1, rFP @ arg1 11909 mov r2, rSELF @ arg2 11910 b dvmCheckBefore @ (dPC,dFP,self) tail call 11911 11912 /* ------------------------------ */ 11913 .balign 64 11914 .L_ALT_OP_AGET_SHORT: /* 0x4a */ 11915 /* File: armv5te/alt_stub.S */ 11916 /* 11917 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11918 * any interesting requests and then jump to the real instruction 11919 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11920 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11921 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11922 * bail to the real handler if breakFlags==0. 11923 */ 11924 ldrb r3, [rSELF, #offThread_breakFlags] 11925 adrl lr, dvmAsmInstructionStart + (74 * 64) 11926 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11927 cmp r3, #0 11928 bxeq lr @ nothing to do - jump to real handler 11929 EXPORT_PC() 11930 mov r0, rPC @ arg0 11931 mov r1, rFP @ arg1 11932 mov r2, rSELF @ arg2 11933 b dvmCheckBefore @ (dPC,dFP,self) tail call 11934 11935 /* ------------------------------ */ 11936 .balign 64 11937 .L_ALT_OP_APUT: /* 0x4b */ 11938 /* File: armv5te/alt_stub.S */ 11939 /* 11940 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11941 * any interesting requests and then jump to the real instruction 11942 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11943 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11944 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11945 * bail to the real handler if breakFlags==0. 11946 */ 11947 ldrb r3, [rSELF, #offThread_breakFlags] 11948 adrl lr, dvmAsmInstructionStart + (75 * 64) 11949 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11950 cmp r3, #0 11951 bxeq lr @ nothing to do - jump to real handler 11952 EXPORT_PC() 11953 mov r0, rPC @ arg0 11954 mov r1, rFP @ arg1 11955 mov r2, rSELF @ arg2 11956 b dvmCheckBefore @ (dPC,dFP,self) tail call 11957 11958 /* ------------------------------ */ 11959 .balign 64 11960 .L_ALT_OP_APUT_WIDE: /* 0x4c */ 11961 /* File: armv5te/alt_stub.S */ 11962 /* 11963 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11964 * any interesting requests and then jump to the real instruction 11965 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11966 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11967 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11968 * bail to the real handler if breakFlags==0. 11969 */ 11970 ldrb r3, [rSELF, #offThread_breakFlags] 11971 adrl lr, dvmAsmInstructionStart + (76 * 64) 11972 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11973 cmp r3, #0 11974 bxeq lr @ nothing to do - jump to real handler 11975 EXPORT_PC() 11976 mov r0, rPC @ arg0 11977 mov r1, rFP @ arg1 11978 mov r2, rSELF @ arg2 11979 b dvmCheckBefore @ (dPC,dFP,self) tail call 11980 11981 /* ------------------------------ */ 11982 .balign 64 11983 .L_ALT_OP_APUT_OBJECT: /* 0x4d */ 11984 /* File: armv5te/alt_stub.S */ 11985 /* 11986 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11987 * any interesting requests and then jump to the real instruction 11988 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11989 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11990 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11991 * bail to the real handler if breakFlags==0. 11992 */ 11993 ldrb r3, [rSELF, #offThread_breakFlags] 11994 adrl lr, dvmAsmInstructionStart + (77 * 64) 11995 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11996 cmp r3, #0 11997 bxeq lr @ nothing to do - jump to real handler 11998 EXPORT_PC() 11999 mov r0, rPC @ arg0 12000 mov r1, rFP @ arg1 12001 mov r2, rSELF @ arg2 12002 b dvmCheckBefore @ (dPC,dFP,self) tail call 12003 12004 /* ------------------------------ */ 12005 .balign 64 12006 .L_ALT_OP_APUT_BOOLEAN: /* 0x4e */ 12007 /* File: armv5te/alt_stub.S */ 12008 /* 12009 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12010 * any interesting requests and then jump to the real instruction 12011 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12012 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12013 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12014 * bail to the real handler if breakFlags==0. 12015 */ 12016 ldrb r3, [rSELF, #offThread_breakFlags] 12017 adrl lr, dvmAsmInstructionStart + (78 * 64) 12018 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12019 cmp r3, #0 12020 bxeq lr @ nothing to do - jump to real handler 12021 EXPORT_PC() 12022 mov r0, rPC @ arg0 12023 mov r1, rFP @ arg1 12024 mov r2, rSELF @ arg2 12025 b dvmCheckBefore @ (dPC,dFP,self) tail call 12026 12027 /* ------------------------------ */ 12028 .balign 64 12029 .L_ALT_OP_APUT_BYTE: /* 0x4f */ 12030 /* File: armv5te/alt_stub.S */ 12031 /* 12032 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12033 * any interesting requests and then jump to the real instruction 12034 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12035 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12036 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12037 * bail to the real handler if breakFlags==0. 12038 */ 12039 ldrb r3, [rSELF, #offThread_breakFlags] 12040 adrl lr, dvmAsmInstructionStart + (79 * 64) 12041 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12042 cmp r3, #0 12043 bxeq lr @ nothing to do - jump to real handler 12044 EXPORT_PC() 12045 mov r0, rPC @ arg0 12046 mov r1, rFP @ arg1 12047 mov r2, rSELF @ arg2 12048 b dvmCheckBefore @ (dPC,dFP,self) tail call 12049 12050 /* ------------------------------ */ 12051 .balign 64 12052 .L_ALT_OP_APUT_CHAR: /* 0x50 */ 12053 /* File: armv5te/alt_stub.S */ 12054 /* 12055 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12056 * any interesting requests and then jump to the real instruction 12057 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12058 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12059 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12060 * bail to the real handler if breakFlags==0. 12061 */ 12062 ldrb r3, [rSELF, #offThread_breakFlags] 12063 adrl lr, dvmAsmInstructionStart + (80 * 64) 12064 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12065 cmp r3, #0 12066 bxeq lr @ nothing to do - jump to real handler 12067 EXPORT_PC() 12068 mov r0, rPC @ arg0 12069 mov r1, rFP @ arg1 12070 mov r2, rSELF @ arg2 12071 b dvmCheckBefore @ (dPC,dFP,self) tail call 12072 12073 /* ------------------------------ */ 12074 .balign 64 12075 .L_ALT_OP_APUT_SHORT: /* 0x51 */ 12076 /* File: armv5te/alt_stub.S */ 12077 /* 12078 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12079 * any interesting requests and then jump to the real instruction 12080 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12081 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12082 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12083 * bail to the real handler if breakFlags==0. 12084 */ 12085 ldrb r3, [rSELF, #offThread_breakFlags] 12086 adrl lr, dvmAsmInstructionStart + (81 * 64) 12087 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12088 cmp r3, #0 12089 bxeq lr @ nothing to do - jump to real handler 12090 EXPORT_PC() 12091 mov r0, rPC @ arg0 12092 mov r1, rFP @ arg1 12093 mov r2, rSELF @ arg2 12094 b dvmCheckBefore @ (dPC,dFP,self) tail call 12095 12096 /* ------------------------------ */ 12097 .balign 64 12098 .L_ALT_OP_IGET: /* 0x52 */ 12099 /* File: armv5te/alt_stub.S */ 12100 /* 12101 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12102 * any interesting requests and then jump to the real instruction 12103 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12104 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12105 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12106 * bail to the real handler if breakFlags==0. 12107 */ 12108 ldrb r3, [rSELF, #offThread_breakFlags] 12109 adrl lr, dvmAsmInstructionStart + (82 * 64) 12110 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12111 cmp r3, #0 12112 bxeq lr @ nothing to do - jump to real handler 12113 EXPORT_PC() 12114 mov r0, rPC @ arg0 12115 mov r1, rFP @ arg1 12116 mov r2, rSELF @ arg2 12117 b dvmCheckBefore @ (dPC,dFP,self) tail call 12118 12119 /* ------------------------------ */ 12120 .balign 64 12121 .L_ALT_OP_IGET_WIDE: /* 0x53 */ 12122 /* File: armv5te/alt_stub.S */ 12123 /* 12124 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12125 * any interesting requests and then jump to the real instruction 12126 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12127 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12128 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12129 * bail to the real handler if breakFlags==0. 12130 */ 12131 ldrb r3, [rSELF, #offThread_breakFlags] 12132 adrl lr, dvmAsmInstructionStart + (83 * 64) 12133 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12134 cmp r3, #0 12135 bxeq lr @ nothing to do - jump to real handler 12136 EXPORT_PC() 12137 mov r0, rPC @ arg0 12138 mov r1, rFP @ arg1 12139 mov r2, rSELF @ arg2 12140 b dvmCheckBefore @ (dPC,dFP,self) tail call 12141 12142 /* ------------------------------ */ 12143 .balign 64 12144 .L_ALT_OP_IGET_OBJECT: /* 0x54 */ 12145 /* File: armv5te/alt_stub.S */ 12146 /* 12147 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12148 * any interesting requests and then jump to the real instruction 12149 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12150 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12151 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12152 * bail to the real handler if breakFlags==0. 12153 */ 12154 ldrb r3, [rSELF, #offThread_breakFlags] 12155 adrl lr, dvmAsmInstructionStart + (84 * 64) 12156 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12157 cmp r3, #0 12158 bxeq lr @ nothing to do - jump to real handler 12159 EXPORT_PC() 12160 mov r0, rPC @ arg0 12161 mov r1, rFP @ arg1 12162 mov r2, rSELF @ arg2 12163 b dvmCheckBefore @ (dPC,dFP,self) tail call 12164 12165 /* ------------------------------ */ 12166 .balign 64 12167 .L_ALT_OP_IGET_BOOLEAN: /* 0x55 */ 12168 /* File: armv5te/alt_stub.S */ 12169 /* 12170 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12171 * any interesting requests and then jump to the real instruction 12172 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12173 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12174 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12175 * bail to the real handler if breakFlags==0. 12176 */ 12177 ldrb r3, [rSELF, #offThread_breakFlags] 12178 adrl lr, dvmAsmInstructionStart + (85 * 64) 12179 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12180 cmp r3, #0 12181 bxeq lr @ nothing to do - jump to real handler 12182 EXPORT_PC() 12183 mov r0, rPC @ arg0 12184 mov r1, rFP @ arg1 12185 mov r2, rSELF @ arg2 12186 b dvmCheckBefore @ (dPC,dFP,self) tail call 12187 12188 /* ------------------------------ */ 12189 .balign 64 12190 .L_ALT_OP_IGET_BYTE: /* 0x56 */ 12191 /* File: armv5te/alt_stub.S */ 12192 /* 12193 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12194 * any interesting requests and then jump to the real instruction 12195 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12196 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12197 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12198 * bail to the real handler if breakFlags==0. 12199 */ 12200 ldrb r3, [rSELF, #offThread_breakFlags] 12201 adrl lr, dvmAsmInstructionStart + (86 * 64) 12202 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12203 cmp r3, #0 12204 bxeq lr @ nothing to do - jump to real handler 12205 EXPORT_PC() 12206 mov r0, rPC @ arg0 12207 mov r1, rFP @ arg1 12208 mov r2, rSELF @ arg2 12209 b dvmCheckBefore @ (dPC,dFP,self) tail call 12210 12211 /* ------------------------------ */ 12212 .balign 64 12213 .L_ALT_OP_IGET_CHAR: /* 0x57 */ 12214 /* File: armv5te/alt_stub.S */ 12215 /* 12216 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12217 * any interesting requests and then jump to the real instruction 12218 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12219 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12220 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12221 * bail to the real handler if breakFlags==0. 12222 */ 12223 ldrb r3, [rSELF, #offThread_breakFlags] 12224 adrl lr, dvmAsmInstructionStart + (87 * 64) 12225 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12226 cmp r3, #0 12227 bxeq lr @ nothing to do - jump to real handler 12228 EXPORT_PC() 12229 mov r0, rPC @ arg0 12230 mov r1, rFP @ arg1 12231 mov r2, rSELF @ arg2 12232 b dvmCheckBefore @ (dPC,dFP,self) tail call 12233 12234 /* ------------------------------ */ 12235 .balign 64 12236 .L_ALT_OP_IGET_SHORT: /* 0x58 */ 12237 /* File: armv5te/alt_stub.S */ 12238 /* 12239 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12240 * any interesting requests and then jump to the real instruction 12241 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12242 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12243 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12244 * bail to the real handler if breakFlags==0. 12245 */ 12246 ldrb r3, [rSELF, #offThread_breakFlags] 12247 adrl lr, dvmAsmInstructionStart + (88 * 64) 12248 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12249 cmp r3, #0 12250 bxeq lr @ nothing to do - jump to real handler 12251 EXPORT_PC() 12252 mov r0, rPC @ arg0 12253 mov r1, rFP @ arg1 12254 mov r2, rSELF @ arg2 12255 b dvmCheckBefore @ (dPC,dFP,self) tail call 12256 12257 /* ------------------------------ */ 12258 .balign 64 12259 .L_ALT_OP_IPUT: /* 0x59 */ 12260 /* File: armv5te/alt_stub.S */ 12261 /* 12262 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12263 * any interesting requests and then jump to the real instruction 12264 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12265 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12266 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12267 * bail to the real handler if breakFlags==0. 12268 */ 12269 ldrb r3, [rSELF, #offThread_breakFlags] 12270 adrl lr, dvmAsmInstructionStart + (89 * 64) 12271 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12272 cmp r3, #0 12273 bxeq lr @ nothing to do - jump to real handler 12274 EXPORT_PC() 12275 mov r0, rPC @ arg0 12276 mov r1, rFP @ arg1 12277 mov r2, rSELF @ arg2 12278 b dvmCheckBefore @ (dPC,dFP,self) tail call 12279 12280 /* ------------------------------ */ 12281 .balign 64 12282 .L_ALT_OP_IPUT_WIDE: /* 0x5a */ 12283 /* File: armv5te/alt_stub.S */ 12284 /* 12285 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12286 * any interesting requests and then jump to the real instruction 12287 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12288 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12289 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12290 * bail to the real handler if breakFlags==0. 12291 */ 12292 ldrb r3, [rSELF, #offThread_breakFlags] 12293 adrl lr, dvmAsmInstructionStart + (90 * 64) 12294 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12295 cmp r3, #0 12296 bxeq lr @ nothing to do - jump to real handler 12297 EXPORT_PC() 12298 mov r0, rPC @ arg0 12299 mov r1, rFP @ arg1 12300 mov r2, rSELF @ arg2 12301 b dvmCheckBefore @ (dPC,dFP,self) tail call 12302 12303 /* ------------------------------ */ 12304 .balign 64 12305 .L_ALT_OP_IPUT_OBJECT: /* 0x5b */ 12306 /* File: armv5te/alt_stub.S */ 12307 /* 12308 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12309 * any interesting requests and then jump to the real instruction 12310 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12311 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12312 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12313 * bail to the real handler if breakFlags==0. 12314 */ 12315 ldrb r3, [rSELF, #offThread_breakFlags] 12316 adrl lr, dvmAsmInstructionStart + (91 * 64) 12317 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12318 cmp r3, #0 12319 bxeq lr @ nothing to do - jump to real handler 12320 EXPORT_PC() 12321 mov r0, rPC @ arg0 12322 mov r1, rFP @ arg1 12323 mov r2, rSELF @ arg2 12324 b dvmCheckBefore @ (dPC,dFP,self) tail call 12325 12326 /* ------------------------------ */ 12327 .balign 64 12328 .L_ALT_OP_IPUT_BOOLEAN: /* 0x5c */ 12329 /* File: armv5te/alt_stub.S */ 12330 /* 12331 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12332 * any interesting requests and then jump to the real instruction 12333 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12334 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12335 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12336 * bail to the real handler if breakFlags==0. 12337 */ 12338 ldrb r3, [rSELF, #offThread_breakFlags] 12339 adrl lr, dvmAsmInstructionStart + (92 * 64) 12340 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12341 cmp r3, #0 12342 bxeq lr @ nothing to do - jump to real handler 12343 EXPORT_PC() 12344 mov r0, rPC @ arg0 12345 mov r1, rFP @ arg1 12346 mov r2, rSELF @ arg2 12347 b dvmCheckBefore @ (dPC,dFP,self) tail call 12348 12349 /* ------------------------------ */ 12350 .balign 64 12351 .L_ALT_OP_IPUT_BYTE: /* 0x5d */ 12352 /* File: armv5te/alt_stub.S */ 12353 /* 12354 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12355 * any interesting requests and then jump to the real instruction 12356 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12357 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12358 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12359 * bail to the real handler if breakFlags==0. 12360 */ 12361 ldrb r3, [rSELF, #offThread_breakFlags] 12362 adrl lr, dvmAsmInstructionStart + (93 * 64) 12363 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12364 cmp r3, #0 12365 bxeq lr @ nothing to do - jump to real handler 12366 EXPORT_PC() 12367 mov r0, rPC @ arg0 12368 mov r1, rFP @ arg1 12369 mov r2, rSELF @ arg2 12370 b dvmCheckBefore @ (dPC,dFP,self) tail call 12371 12372 /* ------------------------------ */ 12373 .balign 64 12374 .L_ALT_OP_IPUT_CHAR: /* 0x5e */ 12375 /* File: armv5te/alt_stub.S */ 12376 /* 12377 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12378 * any interesting requests and then jump to the real instruction 12379 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12380 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12381 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12382 * bail to the real handler if breakFlags==0. 12383 */ 12384 ldrb r3, [rSELF, #offThread_breakFlags] 12385 adrl lr, dvmAsmInstructionStart + (94 * 64) 12386 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12387 cmp r3, #0 12388 bxeq lr @ nothing to do - jump to real handler 12389 EXPORT_PC() 12390 mov r0, rPC @ arg0 12391 mov r1, rFP @ arg1 12392 mov r2, rSELF @ arg2 12393 b dvmCheckBefore @ (dPC,dFP,self) tail call 12394 12395 /* ------------------------------ */ 12396 .balign 64 12397 .L_ALT_OP_IPUT_SHORT: /* 0x5f */ 12398 /* File: armv5te/alt_stub.S */ 12399 /* 12400 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12401 * any interesting requests and then jump to the real instruction 12402 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12403 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12404 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12405 * bail to the real handler if breakFlags==0. 12406 */ 12407 ldrb r3, [rSELF, #offThread_breakFlags] 12408 adrl lr, dvmAsmInstructionStart + (95 * 64) 12409 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12410 cmp r3, #0 12411 bxeq lr @ nothing to do - jump to real handler 12412 EXPORT_PC() 12413 mov r0, rPC @ arg0 12414 mov r1, rFP @ arg1 12415 mov r2, rSELF @ arg2 12416 b dvmCheckBefore @ (dPC,dFP,self) tail call 12417 12418 /* ------------------------------ */ 12419 .balign 64 12420 .L_ALT_OP_SGET: /* 0x60 */ 12421 /* File: armv5te/alt_stub.S */ 12422 /* 12423 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12424 * any interesting requests and then jump to the real instruction 12425 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12426 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12427 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12428 * bail to the real handler if breakFlags==0. 12429 */ 12430 ldrb r3, [rSELF, #offThread_breakFlags] 12431 adrl lr, dvmAsmInstructionStart + (96 * 64) 12432 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12433 cmp r3, #0 12434 bxeq lr @ nothing to do - jump to real handler 12435 EXPORT_PC() 12436 mov r0, rPC @ arg0 12437 mov r1, rFP @ arg1 12438 mov r2, rSELF @ arg2 12439 b dvmCheckBefore @ (dPC,dFP,self) tail call 12440 12441 /* ------------------------------ */ 12442 .balign 64 12443 .L_ALT_OP_SGET_WIDE: /* 0x61 */ 12444 /* File: armv5te/alt_stub.S */ 12445 /* 12446 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12447 * any interesting requests and then jump to the real instruction 12448 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12449 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12450 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12451 * bail to the real handler if breakFlags==0. 12452 */ 12453 ldrb r3, [rSELF, #offThread_breakFlags] 12454 adrl lr, dvmAsmInstructionStart + (97 * 64) 12455 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12456 cmp r3, #0 12457 bxeq lr @ nothing to do - jump to real handler 12458 EXPORT_PC() 12459 mov r0, rPC @ arg0 12460 mov r1, rFP @ arg1 12461 mov r2, rSELF @ arg2 12462 b dvmCheckBefore @ (dPC,dFP,self) tail call 12463 12464 /* ------------------------------ */ 12465 .balign 64 12466 .L_ALT_OP_SGET_OBJECT: /* 0x62 */ 12467 /* File: armv5te/alt_stub.S */ 12468 /* 12469 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12470 * any interesting requests and then jump to the real instruction 12471 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12472 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12473 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12474 * bail to the real handler if breakFlags==0. 12475 */ 12476 ldrb r3, [rSELF, #offThread_breakFlags] 12477 adrl lr, dvmAsmInstructionStart + (98 * 64) 12478 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12479 cmp r3, #0 12480 bxeq lr @ nothing to do - jump to real handler 12481 EXPORT_PC() 12482 mov r0, rPC @ arg0 12483 mov r1, rFP @ arg1 12484 mov r2, rSELF @ arg2 12485 b dvmCheckBefore @ (dPC,dFP,self) tail call 12486 12487 /* ------------------------------ */ 12488 .balign 64 12489 .L_ALT_OP_SGET_BOOLEAN: /* 0x63 */ 12490 /* File: armv5te/alt_stub.S */ 12491 /* 12492 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12493 * any interesting requests and then jump to the real instruction 12494 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12495 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12496 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12497 * bail to the real handler if breakFlags==0. 12498 */ 12499 ldrb r3, [rSELF, #offThread_breakFlags] 12500 adrl lr, dvmAsmInstructionStart + (99 * 64) 12501 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12502 cmp r3, #0 12503 bxeq lr @ nothing to do - jump to real handler 12504 EXPORT_PC() 12505 mov r0, rPC @ arg0 12506 mov r1, rFP @ arg1 12507 mov r2, rSELF @ arg2 12508 b dvmCheckBefore @ (dPC,dFP,self) tail call 12509 12510 /* ------------------------------ */ 12511 .balign 64 12512 .L_ALT_OP_SGET_BYTE: /* 0x64 */ 12513 /* File: armv5te/alt_stub.S */ 12514 /* 12515 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12516 * any interesting requests and then jump to the real instruction 12517 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12518 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12519 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12520 * bail to the real handler if breakFlags==0. 12521 */ 12522 ldrb r3, [rSELF, #offThread_breakFlags] 12523 adrl lr, dvmAsmInstructionStart + (100 * 64) 12524 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12525 cmp r3, #0 12526 bxeq lr @ nothing to do - jump to real handler 12527 EXPORT_PC() 12528 mov r0, rPC @ arg0 12529 mov r1, rFP @ arg1 12530 mov r2, rSELF @ arg2 12531 b dvmCheckBefore @ (dPC,dFP,self) tail call 12532 12533 /* ------------------------------ */ 12534 .balign 64 12535 .L_ALT_OP_SGET_CHAR: /* 0x65 */ 12536 /* File: armv5te/alt_stub.S */ 12537 /* 12538 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12539 * any interesting requests and then jump to the real instruction 12540 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12541 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12542 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12543 * bail to the real handler if breakFlags==0. 12544 */ 12545 ldrb r3, [rSELF, #offThread_breakFlags] 12546 adrl lr, dvmAsmInstructionStart + (101 * 64) 12547 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12548 cmp r3, #0 12549 bxeq lr @ nothing to do - jump to real handler 12550 EXPORT_PC() 12551 mov r0, rPC @ arg0 12552 mov r1, rFP @ arg1 12553 mov r2, rSELF @ arg2 12554 b dvmCheckBefore @ (dPC,dFP,self) tail call 12555 12556 /* ------------------------------ */ 12557 .balign 64 12558 .L_ALT_OP_SGET_SHORT: /* 0x66 */ 12559 /* File: armv5te/alt_stub.S */ 12560 /* 12561 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12562 * any interesting requests and then jump to the real instruction 12563 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12564 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12565 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12566 * bail to the real handler if breakFlags==0. 12567 */ 12568 ldrb r3, [rSELF, #offThread_breakFlags] 12569 adrl lr, dvmAsmInstructionStart + (102 * 64) 12570 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12571 cmp r3, #0 12572 bxeq lr @ nothing to do - jump to real handler 12573 EXPORT_PC() 12574 mov r0, rPC @ arg0 12575 mov r1, rFP @ arg1 12576 mov r2, rSELF @ arg2 12577 b dvmCheckBefore @ (dPC,dFP,self) tail call 12578 12579 /* ------------------------------ */ 12580 .balign 64 12581 .L_ALT_OP_SPUT: /* 0x67 */ 12582 /* File: armv5te/alt_stub.S */ 12583 /* 12584 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12585 * any interesting requests and then jump to the real instruction 12586 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12587 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12588 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12589 * bail to the real handler if breakFlags==0. 12590 */ 12591 ldrb r3, [rSELF, #offThread_breakFlags] 12592 adrl lr, dvmAsmInstructionStart + (103 * 64) 12593 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12594 cmp r3, #0 12595 bxeq lr @ nothing to do - jump to real handler 12596 EXPORT_PC() 12597 mov r0, rPC @ arg0 12598 mov r1, rFP @ arg1 12599 mov r2, rSELF @ arg2 12600 b dvmCheckBefore @ (dPC,dFP,self) tail call 12601 12602 /* ------------------------------ */ 12603 .balign 64 12604 .L_ALT_OP_SPUT_WIDE: /* 0x68 */ 12605 /* File: armv5te/alt_stub.S */ 12606 /* 12607 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12608 * any interesting requests and then jump to the real instruction 12609 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12610 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12611 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12612 * bail to the real handler if breakFlags==0. 12613 */ 12614 ldrb r3, [rSELF, #offThread_breakFlags] 12615 adrl lr, dvmAsmInstructionStart + (104 * 64) 12616 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12617 cmp r3, #0 12618 bxeq lr @ nothing to do - jump to real handler 12619 EXPORT_PC() 12620 mov r0, rPC @ arg0 12621 mov r1, rFP @ arg1 12622 mov r2, rSELF @ arg2 12623 b dvmCheckBefore @ (dPC,dFP,self) tail call 12624 12625 /* ------------------------------ */ 12626 .balign 64 12627 .L_ALT_OP_SPUT_OBJECT: /* 0x69 */ 12628 /* File: armv5te/alt_stub.S */ 12629 /* 12630 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12631 * any interesting requests and then jump to the real instruction 12632 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12633 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12634 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12635 * bail to the real handler if breakFlags==0. 12636 */ 12637 ldrb r3, [rSELF, #offThread_breakFlags] 12638 adrl lr, dvmAsmInstructionStart + (105 * 64) 12639 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12640 cmp r3, #0 12641 bxeq lr @ nothing to do - jump to real handler 12642 EXPORT_PC() 12643 mov r0, rPC @ arg0 12644 mov r1, rFP @ arg1 12645 mov r2, rSELF @ arg2 12646 b dvmCheckBefore @ (dPC,dFP,self) tail call 12647 12648 /* ------------------------------ */ 12649 .balign 64 12650 .L_ALT_OP_SPUT_BOOLEAN: /* 0x6a */ 12651 /* File: armv5te/alt_stub.S */ 12652 /* 12653 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12654 * any interesting requests and then jump to the real instruction 12655 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12656 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12657 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12658 * bail to the real handler if breakFlags==0. 12659 */ 12660 ldrb r3, [rSELF, #offThread_breakFlags] 12661 adrl lr, dvmAsmInstructionStart + (106 * 64) 12662 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12663 cmp r3, #0 12664 bxeq lr @ nothing to do - jump to real handler 12665 EXPORT_PC() 12666 mov r0, rPC @ arg0 12667 mov r1, rFP @ arg1 12668 mov r2, rSELF @ arg2 12669 b dvmCheckBefore @ (dPC,dFP,self) tail call 12670 12671 /* ------------------------------ */ 12672 .balign 64 12673 .L_ALT_OP_SPUT_BYTE: /* 0x6b */ 12674 /* File: armv5te/alt_stub.S */ 12675 /* 12676 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12677 * any interesting requests and then jump to the real instruction 12678 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12679 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12680 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12681 * bail to the real handler if breakFlags==0. 12682 */ 12683 ldrb r3, [rSELF, #offThread_breakFlags] 12684 adrl lr, dvmAsmInstructionStart + (107 * 64) 12685 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12686 cmp r3, #0 12687 bxeq lr @ nothing to do - jump to real handler 12688 EXPORT_PC() 12689 mov r0, rPC @ arg0 12690 mov r1, rFP @ arg1 12691 mov r2, rSELF @ arg2 12692 b dvmCheckBefore @ (dPC,dFP,self) tail call 12693 12694 /* ------------------------------ */ 12695 .balign 64 12696 .L_ALT_OP_SPUT_CHAR: /* 0x6c */ 12697 /* File: armv5te/alt_stub.S */ 12698 /* 12699 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12700 * any interesting requests and then jump to the real instruction 12701 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12702 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12703 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12704 * bail to the real handler if breakFlags==0. 12705 */ 12706 ldrb r3, [rSELF, #offThread_breakFlags] 12707 adrl lr, dvmAsmInstructionStart + (108 * 64) 12708 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12709 cmp r3, #0 12710 bxeq lr @ nothing to do - jump to real handler 12711 EXPORT_PC() 12712 mov r0, rPC @ arg0 12713 mov r1, rFP @ arg1 12714 mov r2, rSELF @ arg2 12715 b dvmCheckBefore @ (dPC,dFP,self) tail call 12716 12717 /* ------------------------------ */ 12718 .balign 64 12719 .L_ALT_OP_SPUT_SHORT: /* 0x6d */ 12720 /* File: armv5te/alt_stub.S */ 12721 /* 12722 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12723 * any interesting requests and then jump to the real instruction 12724 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12725 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12726 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12727 * bail to the real handler if breakFlags==0. 12728 */ 12729 ldrb r3, [rSELF, #offThread_breakFlags] 12730 adrl lr, dvmAsmInstructionStart + (109 * 64) 12731 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12732 cmp r3, #0 12733 bxeq lr @ nothing to do - jump to real handler 12734 EXPORT_PC() 12735 mov r0, rPC @ arg0 12736 mov r1, rFP @ arg1 12737 mov r2, rSELF @ arg2 12738 b dvmCheckBefore @ (dPC,dFP,self) tail call 12739 12740 /* ------------------------------ */ 12741 .balign 64 12742 .L_ALT_OP_INVOKE_VIRTUAL: /* 0x6e */ 12743 /* File: armv5te/alt_stub.S */ 12744 /* 12745 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12746 * any interesting requests and then jump to the real instruction 12747 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12748 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12749 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12750 * bail to the real handler if breakFlags==0. 12751 */ 12752 ldrb r3, [rSELF, #offThread_breakFlags] 12753 adrl lr, dvmAsmInstructionStart + (110 * 64) 12754 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12755 cmp r3, #0 12756 bxeq lr @ nothing to do - jump to real handler 12757 EXPORT_PC() 12758 mov r0, rPC @ arg0 12759 mov r1, rFP @ arg1 12760 mov r2, rSELF @ arg2 12761 b dvmCheckBefore @ (dPC,dFP,self) tail call 12762 12763 /* ------------------------------ */ 12764 .balign 64 12765 .L_ALT_OP_INVOKE_SUPER: /* 0x6f */ 12766 /* File: armv5te/alt_stub.S */ 12767 /* 12768 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12769 * any interesting requests and then jump to the real instruction 12770 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12771 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12772 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12773 * bail to the real handler if breakFlags==0. 12774 */ 12775 ldrb r3, [rSELF, #offThread_breakFlags] 12776 adrl lr, dvmAsmInstructionStart + (111 * 64) 12777 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12778 cmp r3, #0 12779 bxeq lr @ nothing to do - jump to real handler 12780 EXPORT_PC() 12781 mov r0, rPC @ arg0 12782 mov r1, rFP @ arg1 12783 mov r2, rSELF @ arg2 12784 b dvmCheckBefore @ (dPC,dFP,self) tail call 12785 12786 /* ------------------------------ */ 12787 .balign 64 12788 .L_ALT_OP_INVOKE_DIRECT: /* 0x70 */ 12789 /* File: armv5te/alt_stub.S */ 12790 /* 12791 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12792 * any interesting requests and then jump to the real instruction 12793 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12794 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12795 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12796 * bail to the real handler if breakFlags==0. 12797 */ 12798 ldrb r3, [rSELF, #offThread_breakFlags] 12799 adrl lr, dvmAsmInstructionStart + (112 * 64) 12800 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12801 cmp r3, #0 12802 bxeq lr @ nothing to do - jump to real handler 12803 EXPORT_PC() 12804 mov r0, rPC @ arg0 12805 mov r1, rFP @ arg1 12806 mov r2, rSELF @ arg2 12807 b dvmCheckBefore @ (dPC,dFP,self) tail call 12808 12809 /* ------------------------------ */ 12810 .balign 64 12811 .L_ALT_OP_INVOKE_STATIC: /* 0x71 */ 12812 /* File: armv5te/alt_stub.S */ 12813 /* 12814 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12815 * any interesting requests and then jump to the real instruction 12816 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12817 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12818 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12819 * bail to the real handler if breakFlags==0. 12820 */ 12821 ldrb r3, [rSELF, #offThread_breakFlags] 12822 adrl lr, dvmAsmInstructionStart + (113 * 64) 12823 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12824 cmp r3, #0 12825 bxeq lr @ nothing to do - jump to real handler 12826 EXPORT_PC() 12827 mov r0, rPC @ arg0 12828 mov r1, rFP @ arg1 12829 mov r2, rSELF @ arg2 12830 b dvmCheckBefore @ (dPC,dFP,self) tail call 12831 12832 /* ------------------------------ */ 12833 .balign 64 12834 .L_ALT_OP_INVOKE_INTERFACE: /* 0x72 */ 12835 /* File: armv5te/alt_stub.S */ 12836 /* 12837 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12838 * any interesting requests and then jump to the real instruction 12839 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12840 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12841 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12842 * bail to the real handler if breakFlags==0. 12843 */ 12844 ldrb r3, [rSELF, #offThread_breakFlags] 12845 adrl lr, dvmAsmInstructionStart + (114 * 64) 12846 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12847 cmp r3, #0 12848 bxeq lr @ nothing to do - jump to real handler 12849 EXPORT_PC() 12850 mov r0, rPC @ arg0 12851 mov r1, rFP @ arg1 12852 mov r2, rSELF @ arg2 12853 b dvmCheckBefore @ (dPC,dFP,self) tail call 12854 12855 /* ------------------------------ */ 12856 .balign 64 12857 .L_ALT_OP_UNUSED_73: /* 0x73 */ 12858 /* File: armv5te/alt_stub.S */ 12859 /* 12860 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12861 * any interesting requests and then jump to the real instruction 12862 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12863 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12864 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12865 * bail to the real handler if breakFlags==0. 12866 */ 12867 ldrb r3, [rSELF, #offThread_breakFlags] 12868 adrl lr, dvmAsmInstructionStart + (115 * 64) 12869 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12870 cmp r3, #0 12871 bxeq lr @ nothing to do - jump to real handler 12872 EXPORT_PC() 12873 mov r0, rPC @ arg0 12874 mov r1, rFP @ arg1 12875 mov r2, rSELF @ arg2 12876 b dvmCheckBefore @ (dPC,dFP,self) tail call 12877 12878 /* ------------------------------ */ 12879 .balign 64 12880 .L_ALT_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 12881 /* File: armv5te/alt_stub.S */ 12882 /* 12883 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12884 * any interesting requests and then jump to the real instruction 12885 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12886 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12887 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12888 * bail to the real handler if breakFlags==0. 12889 */ 12890 ldrb r3, [rSELF, #offThread_breakFlags] 12891 adrl lr, dvmAsmInstructionStart + (116 * 64) 12892 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12893 cmp r3, #0 12894 bxeq lr @ nothing to do - jump to real handler 12895 EXPORT_PC() 12896 mov r0, rPC @ arg0 12897 mov r1, rFP @ arg1 12898 mov r2, rSELF @ arg2 12899 b dvmCheckBefore @ (dPC,dFP,self) tail call 12900 12901 /* ------------------------------ */ 12902 .balign 64 12903 .L_ALT_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 12904 /* File: armv5te/alt_stub.S */ 12905 /* 12906 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12907 * any interesting requests and then jump to the real instruction 12908 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12909 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12910 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12911 * bail to the real handler if breakFlags==0. 12912 */ 12913 ldrb r3, [rSELF, #offThread_breakFlags] 12914 adrl lr, dvmAsmInstructionStart + (117 * 64) 12915 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12916 cmp r3, #0 12917 bxeq lr @ nothing to do - jump to real handler 12918 EXPORT_PC() 12919 mov r0, rPC @ arg0 12920 mov r1, rFP @ arg1 12921 mov r2, rSELF @ arg2 12922 b dvmCheckBefore @ (dPC,dFP,self) tail call 12923 12924 /* ------------------------------ */ 12925 .balign 64 12926 .L_ALT_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 12927 /* File: armv5te/alt_stub.S */ 12928 /* 12929 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12930 * any interesting requests and then jump to the real instruction 12931 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12932 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12933 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12934 * bail to the real handler if breakFlags==0. 12935 */ 12936 ldrb r3, [rSELF, #offThread_breakFlags] 12937 adrl lr, dvmAsmInstructionStart + (118 * 64) 12938 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12939 cmp r3, #0 12940 bxeq lr @ nothing to do - jump to real handler 12941 EXPORT_PC() 12942 mov r0, rPC @ arg0 12943 mov r1, rFP @ arg1 12944 mov r2, rSELF @ arg2 12945 b dvmCheckBefore @ (dPC,dFP,self) tail call 12946 12947 /* ------------------------------ */ 12948 .balign 64 12949 .L_ALT_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 12950 /* File: armv5te/alt_stub.S */ 12951 /* 12952 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12953 * any interesting requests and then jump to the real instruction 12954 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12955 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12956 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12957 * bail to the real handler if breakFlags==0. 12958 */ 12959 ldrb r3, [rSELF, #offThread_breakFlags] 12960 adrl lr, dvmAsmInstructionStart + (119 * 64) 12961 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12962 cmp r3, #0 12963 bxeq lr @ nothing to do - jump to real handler 12964 EXPORT_PC() 12965 mov r0, rPC @ arg0 12966 mov r1, rFP @ arg1 12967 mov r2, rSELF @ arg2 12968 b dvmCheckBefore @ (dPC,dFP,self) tail call 12969 12970 /* ------------------------------ */ 12971 .balign 64 12972 .L_ALT_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 12973 /* File: armv5te/alt_stub.S */ 12974 /* 12975 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12976 * any interesting requests and then jump to the real instruction 12977 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12978 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12979 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12980 * bail to the real handler if breakFlags==0. 12981 */ 12982 ldrb r3, [rSELF, #offThread_breakFlags] 12983 adrl lr, dvmAsmInstructionStart + (120 * 64) 12984 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12985 cmp r3, #0 12986 bxeq lr @ nothing to do - jump to real handler 12987 EXPORT_PC() 12988 mov r0, rPC @ arg0 12989 mov r1, rFP @ arg1 12990 mov r2, rSELF @ arg2 12991 b dvmCheckBefore @ (dPC,dFP,self) tail call 12992 12993 /* ------------------------------ */ 12994 .balign 64 12995 .L_ALT_OP_UNUSED_79: /* 0x79 */ 12996 /* File: armv5te/alt_stub.S */ 12997 /* 12998 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12999 * any interesting requests and then jump to the real instruction 13000 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13001 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13002 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13003 * bail to the real handler if breakFlags==0. 13004 */ 13005 ldrb r3, [rSELF, #offThread_breakFlags] 13006 adrl lr, dvmAsmInstructionStart + (121 * 64) 13007 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13008 cmp r3, #0 13009 bxeq lr @ nothing to do - jump to real handler 13010 EXPORT_PC() 13011 mov r0, rPC @ arg0 13012 mov r1, rFP @ arg1 13013 mov r2, rSELF @ arg2 13014 b dvmCheckBefore @ (dPC,dFP,self) tail call 13015 13016 /* ------------------------------ */ 13017 .balign 64 13018 .L_ALT_OP_UNUSED_7A: /* 0x7a */ 13019 /* File: armv5te/alt_stub.S */ 13020 /* 13021 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13022 * any interesting requests and then jump to the real instruction 13023 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13024 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13025 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13026 * bail to the real handler if breakFlags==0. 13027 */ 13028 ldrb r3, [rSELF, #offThread_breakFlags] 13029 adrl lr, dvmAsmInstructionStart + (122 * 64) 13030 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13031 cmp r3, #0 13032 bxeq lr @ nothing to do - jump to real handler 13033 EXPORT_PC() 13034 mov r0, rPC @ arg0 13035 mov r1, rFP @ arg1 13036 mov r2, rSELF @ arg2 13037 b dvmCheckBefore @ (dPC,dFP,self) tail call 13038 13039 /* ------------------------------ */ 13040 .balign 64 13041 .L_ALT_OP_NEG_INT: /* 0x7b */ 13042 /* File: armv5te/alt_stub.S */ 13043 /* 13044 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13045 * any interesting requests and then jump to the real instruction 13046 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13047 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13048 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13049 * bail to the real handler if breakFlags==0. 13050 */ 13051 ldrb r3, [rSELF, #offThread_breakFlags] 13052 adrl lr, dvmAsmInstructionStart + (123 * 64) 13053 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13054 cmp r3, #0 13055 bxeq lr @ nothing to do - jump to real handler 13056 EXPORT_PC() 13057 mov r0, rPC @ arg0 13058 mov r1, rFP @ arg1 13059 mov r2, rSELF @ arg2 13060 b dvmCheckBefore @ (dPC,dFP,self) tail call 13061 13062 /* ------------------------------ */ 13063 .balign 64 13064 .L_ALT_OP_NOT_INT: /* 0x7c */ 13065 /* File: armv5te/alt_stub.S */ 13066 /* 13067 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13068 * any interesting requests and then jump to the real instruction 13069 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13070 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13071 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13072 * bail to the real handler if breakFlags==0. 13073 */ 13074 ldrb r3, [rSELF, #offThread_breakFlags] 13075 adrl lr, dvmAsmInstructionStart + (124 * 64) 13076 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13077 cmp r3, #0 13078 bxeq lr @ nothing to do - jump to real handler 13079 EXPORT_PC() 13080 mov r0, rPC @ arg0 13081 mov r1, rFP @ arg1 13082 mov r2, rSELF @ arg2 13083 b dvmCheckBefore @ (dPC,dFP,self) tail call 13084 13085 /* ------------------------------ */ 13086 .balign 64 13087 .L_ALT_OP_NEG_LONG: /* 0x7d */ 13088 /* File: armv5te/alt_stub.S */ 13089 /* 13090 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13091 * any interesting requests and then jump to the real instruction 13092 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13093 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13094 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13095 * bail to the real handler if breakFlags==0. 13096 */ 13097 ldrb r3, [rSELF, #offThread_breakFlags] 13098 adrl lr, dvmAsmInstructionStart + (125 * 64) 13099 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13100 cmp r3, #0 13101 bxeq lr @ nothing to do - jump to real handler 13102 EXPORT_PC() 13103 mov r0, rPC @ arg0 13104 mov r1, rFP @ arg1 13105 mov r2, rSELF @ arg2 13106 b dvmCheckBefore @ (dPC,dFP,self) tail call 13107 13108 /* ------------------------------ */ 13109 .balign 64 13110 .L_ALT_OP_NOT_LONG: /* 0x7e */ 13111 /* File: armv5te/alt_stub.S */ 13112 /* 13113 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13114 * any interesting requests and then jump to the real instruction 13115 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13116 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13117 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13118 * bail to the real handler if breakFlags==0. 13119 */ 13120 ldrb r3, [rSELF, #offThread_breakFlags] 13121 adrl lr, dvmAsmInstructionStart + (126 * 64) 13122 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13123 cmp r3, #0 13124 bxeq lr @ nothing to do - jump to real handler 13125 EXPORT_PC() 13126 mov r0, rPC @ arg0 13127 mov r1, rFP @ arg1 13128 mov r2, rSELF @ arg2 13129 b dvmCheckBefore @ (dPC,dFP,self) tail call 13130 13131 /* ------------------------------ */ 13132 .balign 64 13133 .L_ALT_OP_NEG_FLOAT: /* 0x7f */ 13134 /* File: armv5te/alt_stub.S */ 13135 /* 13136 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13137 * any interesting requests and then jump to the real instruction 13138 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13139 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13140 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13141 * bail to the real handler if breakFlags==0. 13142 */ 13143 ldrb r3, [rSELF, #offThread_breakFlags] 13144 adrl lr, dvmAsmInstructionStart + (127 * 64) 13145 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13146 cmp r3, #0 13147 bxeq lr @ nothing to do - jump to real handler 13148 EXPORT_PC() 13149 mov r0, rPC @ arg0 13150 mov r1, rFP @ arg1 13151 mov r2, rSELF @ arg2 13152 b dvmCheckBefore @ (dPC,dFP,self) tail call 13153 13154 /* ------------------------------ */ 13155 .balign 64 13156 .L_ALT_OP_NEG_DOUBLE: /* 0x80 */ 13157 /* File: armv5te/alt_stub.S */ 13158 /* 13159 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13160 * any interesting requests and then jump to the real instruction 13161 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13162 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13163 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13164 * bail to the real handler if breakFlags==0. 13165 */ 13166 ldrb r3, [rSELF, #offThread_breakFlags] 13167 adrl lr, dvmAsmInstructionStart + (128 * 64) 13168 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13169 cmp r3, #0 13170 bxeq lr @ nothing to do - jump to real handler 13171 EXPORT_PC() 13172 mov r0, rPC @ arg0 13173 mov r1, rFP @ arg1 13174 mov r2, rSELF @ arg2 13175 b dvmCheckBefore @ (dPC,dFP,self) tail call 13176 13177 /* ------------------------------ */ 13178 .balign 64 13179 .L_ALT_OP_INT_TO_LONG: /* 0x81 */ 13180 /* File: armv5te/alt_stub.S */ 13181 /* 13182 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13183 * any interesting requests and then jump to the real instruction 13184 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13185 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13186 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13187 * bail to the real handler if breakFlags==0. 13188 */ 13189 ldrb r3, [rSELF, #offThread_breakFlags] 13190 adrl lr, dvmAsmInstructionStart + (129 * 64) 13191 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13192 cmp r3, #0 13193 bxeq lr @ nothing to do - jump to real handler 13194 EXPORT_PC() 13195 mov r0, rPC @ arg0 13196 mov r1, rFP @ arg1 13197 mov r2, rSELF @ arg2 13198 b dvmCheckBefore @ (dPC,dFP,self) tail call 13199 13200 /* ------------------------------ */ 13201 .balign 64 13202 .L_ALT_OP_INT_TO_FLOAT: /* 0x82 */ 13203 /* File: armv5te/alt_stub.S */ 13204 /* 13205 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13206 * any interesting requests and then jump to the real instruction 13207 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13208 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13209 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13210 * bail to the real handler if breakFlags==0. 13211 */ 13212 ldrb r3, [rSELF, #offThread_breakFlags] 13213 adrl lr, dvmAsmInstructionStart + (130 * 64) 13214 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13215 cmp r3, #0 13216 bxeq lr @ nothing to do - jump to real handler 13217 EXPORT_PC() 13218 mov r0, rPC @ arg0 13219 mov r1, rFP @ arg1 13220 mov r2, rSELF @ arg2 13221 b dvmCheckBefore @ (dPC,dFP,self) tail call 13222 13223 /* ------------------------------ */ 13224 .balign 64 13225 .L_ALT_OP_INT_TO_DOUBLE: /* 0x83 */ 13226 /* File: armv5te/alt_stub.S */ 13227 /* 13228 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13229 * any interesting requests and then jump to the real instruction 13230 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13231 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13232 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13233 * bail to the real handler if breakFlags==0. 13234 */ 13235 ldrb r3, [rSELF, #offThread_breakFlags] 13236 adrl lr, dvmAsmInstructionStart + (131 * 64) 13237 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13238 cmp r3, #0 13239 bxeq lr @ nothing to do - jump to real handler 13240 EXPORT_PC() 13241 mov r0, rPC @ arg0 13242 mov r1, rFP @ arg1 13243 mov r2, rSELF @ arg2 13244 b dvmCheckBefore @ (dPC,dFP,self) tail call 13245 13246 /* ------------------------------ */ 13247 .balign 64 13248 .L_ALT_OP_LONG_TO_INT: /* 0x84 */ 13249 /* File: armv5te/alt_stub.S */ 13250 /* 13251 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13252 * any interesting requests and then jump to the real instruction 13253 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13254 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13255 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13256 * bail to the real handler if breakFlags==0. 13257 */ 13258 ldrb r3, [rSELF, #offThread_breakFlags] 13259 adrl lr, dvmAsmInstructionStart + (132 * 64) 13260 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13261 cmp r3, #0 13262 bxeq lr @ nothing to do - jump to real handler 13263 EXPORT_PC() 13264 mov r0, rPC @ arg0 13265 mov r1, rFP @ arg1 13266 mov r2, rSELF @ arg2 13267 b dvmCheckBefore @ (dPC,dFP,self) tail call 13268 13269 /* ------------------------------ */ 13270 .balign 64 13271 .L_ALT_OP_LONG_TO_FLOAT: /* 0x85 */ 13272 /* File: armv5te/alt_stub.S */ 13273 /* 13274 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13275 * any interesting requests and then jump to the real instruction 13276 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13277 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13278 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13279 * bail to the real handler if breakFlags==0. 13280 */ 13281 ldrb r3, [rSELF, #offThread_breakFlags] 13282 adrl lr, dvmAsmInstructionStart + (133 * 64) 13283 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13284 cmp r3, #0 13285 bxeq lr @ nothing to do - jump to real handler 13286 EXPORT_PC() 13287 mov r0, rPC @ arg0 13288 mov r1, rFP @ arg1 13289 mov r2, rSELF @ arg2 13290 b dvmCheckBefore @ (dPC,dFP,self) tail call 13291 13292 /* ------------------------------ */ 13293 .balign 64 13294 .L_ALT_OP_LONG_TO_DOUBLE: /* 0x86 */ 13295 /* File: armv5te/alt_stub.S */ 13296 /* 13297 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13298 * any interesting requests and then jump to the real instruction 13299 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13300 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13301 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13302 * bail to the real handler if breakFlags==0. 13303 */ 13304 ldrb r3, [rSELF, #offThread_breakFlags] 13305 adrl lr, dvmAsmInstructionStart + (134 * 64) 13306 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13307 cmp r3, #0 13308 bxeq lr @ nothing to do - jump to real handler 13309 EXPORT_PC() 13310 mov r0, rPC @ arg0 13311 mov r1, rFP @ arg1 13312 mov r2, rSELF @ arg2 13313 b dvmCheckBefore @ (dPC,dFP,self) tail call 13314 13315 /* ------------------------------ */ 13316 .balign 64 13317 .L_ALT_OP_FLOAT_TO_INT: /* 0x87 */ 13318 /* File: armv5te/alt_stub.S */ 13319 /* 13320 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13321 * any interesting requests and then jump to the real instruction 13322 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13323 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13324 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13325 * bail to the real handler if breakFlags==0. 13326 */ 13327 ldrb r3, [rSELF, #offThread_breakFlags] 13328 adrl lr, dvmAsmInstructionStart + (135 * 64) 13329 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13330 cmp r3, #0 13331 bxeq lr @ nothing to do - jump to real handler 13332 EXPORT_PC() 13333 mov r0, rPC @ arg0 13334 mov r1, rFP @ arg1 13335 mov r2, rSELF @ arg2 13336 b dvmCheckBefore @ (dPC,dFP,self) tail call 13337 13338 /* ------------------------------ */ 13339 .balign 64 13340 .L_ALT_OP_FLOAT_TO_LONG: /* 0x88 */ 13341 /* File: armv5te/alt_stub.S */ 13342 /* 13343 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13344 * any interesting requests and then jump to the real instruction 13345 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13346 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13347 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13348 * bail to the real handler if breakFlags==0. 13349 */ 13350 ldrb r3, [rSELF, #offThread_breakFlags] 13351 adrl lr, dvmAsmInstructionStart + (136 * 64) 13352 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13353 cmp r3, #0 13354 bxeq lr @ nothing to do - jump to real handler 13355 EXPORT_PC() 13356 mov r0, rPC @ arg0 13357 mov r1, rFP @ arg1 13358 mov r2, rSELF @ arg2 13359 b dvmCheckBefore @ (dPC,dFP,self) tail call 13360 13361 /* ------------------------------ */ 13362 .balign 64 13363 .L_ALT_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 13364 /* File: armv5te/alt_stub.S */ 13365 /* 13366 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13367 * any interesting requests and then jump to the real instruction 13368 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13369 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13370 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13371 * bail to the real handler if breakFlags==0. 13372 */ 13373 ldrb r3, [rSELF, #offThread_breakFlags] 13374 adrl lr, dvmAsmInstructionStart + (137 * 64) 13375 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13376 cmp r3, #0 13377 bxeq lr @ nothing to do - jump to real handler 13378 EXPORT_PC() 13379 mov r0, rPC @ arg0 13380 mov r1, rFP @ arg1 13381 mov r2, rSELF @ arg2 13382 b dvmCheckBefore @ (dPC,dFP,self) tail call 13383 13384 /* ------------------------------ */ 13385 .balign 64 13386 .L_ALT_OP_DOUBLE_TO_INT: /* 0x8a */ 13387 /* File: armv5te/alt_stub.S */ 13388 /* 13389 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13390 * any interesting requests and then jump to the real instruction 13391 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13392 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13393 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13394 * bail to the real handler if breakFlags==0. 13395 */ 13396 ldrb r3, [rSELF, #offThread_breakFlags] 13397 adrl lr, dvmAsmInstructionStart + (138 * 64) 13398 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13399 cmp r3, #0 13400 bxeq lr @ nothing to do - jump to real handler 13401 EXPORT_PC() 13402 mov r0, rPC @ arg0 13403 mov r1, rFP @ arg1 13404 mov r2, rSELF @ arg2 13405 b dvmCheckBefore @ (dPC,dFP,self) tail call 13406 13407 /* ------------------------------ */ 13408 .balign 64 13409 .L_ALT_OP_DOUBLE_TO_LONG: /* 0x8b */ 13410 /* File: armv5te/alt_stub.S */ 13411 /* 13412 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13413 * any interesting requests and then jump to the real instruction 13414 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13415 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13416 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13417 * bail to the real handler if breakFlags==0. 13418 */ 13419 ldrb r3, [rSELF, #offThread_breakFlags] 13420 adrl lr, dvmAsmInstructionStart + (139 * 64) 13421 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13422 cmp r3, #0 13423 bxeq lr @ nothing to do - jump to real handler 13424 EXPORT_PC() 13425 mov r0, rPC @ arg0 13426 mov r1, rFP @ arg1 13427 mov r2, rSELF @ arg2 13428 b dvmCheckBefore @ (dPC,dFP,self) tail call 13429 13430 /* ------------------------------ */ 13431 .balign 64 13432 .L_ALT_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 13433 /* File: armv5te/alt_stub.S */ 13434 /* 13435 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13436 * any interesting requests and then jump to the real instruction 13437 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13438 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13439 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13440 * bail to the real handler if breakFlags==0. 13441 */ 13442 ldrb r3, [rSELF, #offThread_breakFlags] 13443 adrl lr, dvmAsmInstructionStart + (140 * 64) 13444 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13445 cmp r3, #0 13446 bxeq lr @ nothing to do - jump to real handler 13447 EXPORT_PC() 13448 mov r0, rPC @ arg0 13449 mov r1, rFP @ arg1 13450 mov r2, rSELF @ arg2 13451 b dvmCheckBefore @ (dPC,dFP,self) tail call 13452 13453 /* ------------------------------ */ 13454 .balign 64 13455 .L_ALT_OP_INT_TO_BYTE: /* 0x8d */ 13456 /* File: armv5te/alt_stub.S */ 13457 /* 13458 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13459 * any interesting requests and then jump to the real instruction 13460 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13461 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13462 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13463 * bail to the real handler if breakFlags==0. 13464 */ 13465 ldrb r3, [rSELF, #offThread_breakFlags] 13466 adrl lr, dvmAsmInstructionStart + (141 * 64) 13467 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13468 cmp r3, #0 13469 bxeq lr @ nothing to do - jump to real handler 13470 EXPORT_PC() 13471 mov r0, rPC @ arg0 13472 mov r1, rFP @ arg1 13473 mov r2, rSELF @ arg2 13474 b dvmCheckBefore @ (dPC,dFP,self) tail call 13475 13476 /* ------------------------------ */ 13477 .balign 64 13478 .L_ALT_OP_INT_TO_CHAR: /* 0x8e */ 13479 /* File: armv5te/alt_stub.S */ 13480 /* 13481 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13482 * any interesting requests and then jump to the real instruction 13483 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13484 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13485 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13486 * bail to the real handler if breakFlags==0. 13487 */ 13488 ldrb r3, [rSELF, #offThread_breakFlags] 13489 adrl lr, dvmAsmInstructionStart + (142 * 64) 13490 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13491 cmp r3, #0 13492 bxeq lr @ nothing to do - jump to real handler 13493 EXPORT_PC() 13494 mov r0, rPC @ arg0 13495 mov r1, rFP @ arg1 13496 mov r2, rSELF @ arg2 13497 b dvmCheckBefore @ (dPC,dFP,self) tail call 13498 13499 /* ------------------------------ */ 13500 .balign 64 13501 .L_ALT_OP_INT_TO_SHORT: /* 0x8f */ 13502 /* File: armv5te/alt_stub.S */ 13503 /* 13504 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13505 * any interesting requests and then jump to the real instruction 13506 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13507 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13508 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13509 * bail to the real handler if breakFlags==0. 13510 */ 13511 ldrb r3, [rSELF, #offThread_breakFlags] 13512 adrl lr, dvmAsmInstructionStart + (143 * 64) 13513 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13514 cmp r3, #0 13515 bxeq lr @ nothing to do - jump to real handler 13516 EXPORT_PC() 13517 mov r0, rPC @ arg0 13518 mov r1, rFP @ arg1 13519 mov r2, rSELF @ arg2 13520 b dvmCheckBefore @ (dPC,dFP,self) tail call 13521 13522 /* ------------------------------ */ 13523 .balign 64 13524 .L_ALT_OP_ADD_INT: /* 0x90 */ 13525 /* File: armv5te/alt_stub.S */ 13526 /* 13527 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13528 * any interesting requests and then jump to the real instruction 13529 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13530 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13531 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13532 * bail to the real handler if breakFlags==0. 13533 */ 13534 ldrb r3, [rSELF, #offThread_breakFlags] 13535 adrl lr, dvmAsmInstructionStart + (144 * 64) 13536 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13537 cmp r3, #0 13538 bxeq lr @ nothing to do - jump to real handler 13539 EXPORT_PC() 13540 mov r0, rPC @ arg0 13541 mov r1, rFP @ arg1 13542 mov r2, rSELF @ arg2 13543 b dvmCheckBefore @ (dPC,dFP,self) tail call 13544 13545 /* ------------------------------ */ 13546 .balign 64 13547 .L_ALT_OP_SUB_INT: /* 0x91 */ 13548 /* File: armv5te/alt_stub.S */ 13549 /* 13550 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13551 * any interesting requests and then jump to the real instruction 13552 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13553 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13554 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13555 * bail to the real handler if breakFlags==0. 13556 */ 13557 ldrb r3, [rSELF, #offThread_breakFlags] 13558 adrl lr, dvmAsmInstructionStart + (145 * 64) 13559 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13560 cmp r3, #0 13561 bxeq lr @ nothing to do - jump to real handler 13562 EXPORT_PC() 13563 mov r0, rPC @ arg0 13564 mov r1, rFP @ arg1 13565 mov r2, rSELF @ arg2 13566 b dvmCheckBefore @ (dPC,dFP,self) tail call 13567 13568 /* ------------------------------ */ 13569 .balign 64 13570 .L_ALT_OP_MUL_INT: /* 0x92 */ 13571 /* File: armv5te/alt_stub.S */ 13572 /* 13573 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13574 * any interesting requests and then jump to the real instruction 13575 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13576 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13577 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13578 * bail to the real handler if breakFlags==0. 13579 */ 13580 ldrb r3, [rSELF, #offThread_breakFlags] 13581 adrl lr, dvmAsmInstructionStart + (146 * 64) 13582 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13583 cmp r3, #0 13584 bxeq lr @ nothing to do - jump to real handler 13585 EXPORT_PC() 13586 mov r0, rPC @ arg0 13587 mov r1, rFP @ arg1 13588 mov r2, rSELF @ arg2 13589 b dvmCheckBefore @ (dPC,dFP,self) tail call 13590 13591 /* ------------------------------ */ 13592 .balign 64 13593 .L_ALT_OP_DIV_INT: /* 0x93 */ 13594 /* File: armv5te/alt_stub.S */ 13595 /* 13596 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13597 * any interesting requests and then jump to the real instruction 13598 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13599 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13600 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13601 * bail to the real handler if breakFlags==0. 13602 */ 13603 ldrb r3, [rSELF, #offThread_breakFlags] 13604 adrl lr, dvmAsmInstructionStart + (147 * 64) 13605 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13606 cmp r3, #0 13607 bxeq lr @ nothing to do - jump to real handler 13608 EXPORT_PC() 13609 mov r0, rPC @ arg0 13610 mov r1, rFP @ arg1 13611 mov r2, rSELF @ arg2 13612 b dvmCheckBefore @ (dPC,dFP,self) tail call 13613 13614 /* ------------------------------ */ 13615 .balign 64 13616 .L_ALT_OP_REM_INT: /* 0x94 */ 13617 /* File: armv5te/alt_stub.S */ 13618 /* 13619 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13620 * any interesting requests and then jump to the real instruction 13621 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13622 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13623 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13624 * bail to the real handler if breakFlags==0. 13625 */ 13626 ldrb r3, [rSELF, #offThread_breakFlags] 13627 adrl lr, dvmAsmInstructionStart + (148 * 64) 13628 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13629 cmp r3, #0 13630 bxeq lr @ nothing to do - jump to real handler 13631 EXPORT_PC() 13632 mov r0, rPC @ arg0 13633 mov r1, rFP @ arg1 13634 mov r2, rSELF @ arg2 13635 b dvmCheckBefore @ (dPC,dFP,self) tail call 13636 13637 /* ------------------------------ */ 13638 .balign 64 13639 .L_ALT_OP_AND_INT: /* 0x95 */ 13640 /* File: armv5te/alt_stub.S */ 13641 /* 13642 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13643 * any interesting requests and then jump to the real instruction 13644 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13645 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13646 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13647 * bail to the real handler if breakFlags==0. 13648 */ 13649 ldrb r3, [rSELF, #offThread_breakFlags] 13650 adrl lr, dvmAsmInstructionStart + (149 * 64) 13651 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13652 cmp r3, #0 13653 bxeq lr @ nothing to do - jump to real handler 13654 EXPORT_PC() 13655 mov r0, rPC @ arg0 13656 mov r1, rFP @ arg1 13657 mov r2, rSELF @ arg2 13658 b dvmCheckBefore @ (dPC,dFP,self) tail call 13659 13660 /* ------------------------------ */ 13661 .balign 64 13662 .L_ALT_OP_OR_INT: /* 0x96 */ 13663 /* File: armv5te/alt_stub.S */ 13664 /* 13665 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13666 * any interesting requests and then jump to the real instruction 13667 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13668 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13669 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13670 * bail to the real handler if breakFlags==0. 13671 */ 13672 ldrb r3, [rSELF, #offThread_breakFlags] 13673 adrl lr, dvmAsmInstructionStart + (150 * 64) 13674 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13675 cmp r3, #0 13676 bxeq lr @ nothing to do - jump to real handler 13677 EXPORT_PC() 13678 mov r0, rPC @ arg0 13679 mov r1, rFP @ arg1 13680 mov r2, rSELF @ arg2 13681 b dvmCheckBefore @ (dPC,dFP,self) tail call 13682 13683 /* ------------------------------ */ 13684 .balign 64 13685 .L_ALT_OP_XOR_INT: /* 0x97 */ 13686 /* File: armv5te/alt_stub.S */ 13687 /* 13688 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13689 * any interesting requests and then jump to the real instruction 13690 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13691 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13692 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13693 * bail to the real handler if breakFlags==0. 13694 */ 13695 ldrb r3, [rSELF, #offThread_breakFlags] 13696 adrl lr, dvmAsmInstructionStart + (151 * 64) 13697 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13698 cmp r3, #0 13699 bxeq lr @ nothing to do - jump to real handler 13700 EXPORT_PC() 13701 mov r0, rPC @ arg0 13702 mov r1, rFP @ arg1 13703 mov r2, rSELF @ arg2 13704 b dvmCheckBefore @ (dPC,dFP,self) tail call 13705 13706 /* ------------------------------ */ 13707 .balign 64 13708 .L_ALT_OP_SHL_INT: /* 0x98 */ 13709 /* File: armv5te/alt_stub.S */ 13710 /* 13711 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13712 * any interesting requests and then jump to the real instruction 13713 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13714 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13715 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13716 * bail to the real handler if breakFlags==0. 13717 */ 13718 ldrb r3, [rSELF, #offThread_breakFlags] 13719 adrl lr, dvmAsmInstructionStart + (152 * 64) 13720 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13721 cmp r3, #0 13722 bxeq lr @ nothing to do - jump to real handler 13723 EXPORT_PC() 13724 mov r0, rPC @ arg0 13725 mov r1, rFP @ arg1 13726 mov r2, rSELF @ arg2 13727 b dvmCheckBefore @ (dPC,dFP,self) tail call 13728 13729 /* ------------------------------ */ 13730 .balign 64 13731 .L_ALT_OP_SHR_INT: /* 0x99 */ 13732 /* File: armv5te/alt_stub.S */ 13733 /* 13734 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13735 * any interesting requests and then jump to the real instruction 13736 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13737 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13738 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13739 * bail to the real handler if breakFlags==0. 13740 */ 13741 ldrb r3, [rSELF, #offThread_breakFlags] 13742 adrl lr, dvmAsmInstructionStart + (153 * 64) 13743 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13744 cmp r3, #0 13745 bxeq lr @ nothing to do - jump to real handler 13746 EXPORT_PC() 13747 mov r0, rPC @ arg0 13748 mov r1, rFP @ arg1 13749 mov r2, rSELF @ arg2 13750 b dvmCheckBefore @ (dPC,dFP,self) tail call 13751 13752 /* ------------------------------ */ 13753 .balign 64 13754 .L_ALT_OP_USHR_INT: /* 0x9a */ 13755 /* File: armv5te/alt_stub.S */ 13756 /* 13757 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13758 * any interesting requests and then jump to the real instruction 13759 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13760 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13761 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13762 * bail to the real handler if breakFlags==0. 13763 */ 13764 ldrb r3, [rSELF, #offThread_breakFlags] 13765 adrl lr, dvmAsmInstructionStart + (154 * 64) 13766 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13767 cmp r3, #0 13768 bxeq lr @ nothing to do - jump to real handler 13769 EXPORT_PC() 13770 mov r0, rPC @ arg0 13771 mov r1, rFP @ arg1 13772 mov r2, rSELF @ arg2 13773 b dvmCheckBefore @ (dPC,dFP,self) tail call 13774 13775 /* ------------------------------ */ 13776 .balign 64 13777 .L_ALT_OP_ADD_LONG: /* 0x9b */ 13778 /* File: armv5te/alt_stub.S */ 13779 /* 13780 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13781 * any interesting requests and then jump to the real instruction 13782 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13783 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13784 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13785 * bail to the real handler if breakFlags==0. 13786 */ 13787 ldrb r3, [rSELF, #offThread_breakFlags] 13788 adrl lr, dvmAsmInstructionStart + (155 * 64) 13789 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13790 cmp r3, #0 13791 bxeq lr @ nothing to do - jump to real handler 13792 EXPORT_PC() 13793 mov r0, rPC @ arg0 13794 mov r1, rFP @ arg1 13795 mov r2, rSELF @ arg2 13796 b dvmCheckBefore @ (dPC,dFP,self) tail call 13797 13798 /* ------------------------------ */ 13799 .balign 64 13800 .L_ALT_OP_SUB_LONG: /* 0x9c */ 13801 /* File: armv5te/alt_stub.S */ 13802 /* 13803 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13804 * any interesting requests and then jump to the real instruction 13805 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13806 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13807 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13808 * bail to the real handler if breakFlags==0. 13809 */ 13810 ldrb r3, [rSELF, #offThread_breakFlags] 13811 adrl lr, dvmAsmInstructionStart + (156 * 64) 13812 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13813 cmp r3, #0 13814 bxeq lr @ nothing to do - jump to real handler 13815 EXPORT_PC() 13816 mov r0, rPC @ arg0 13817 mov r1, rFP @ arg1 13818 mov r2, rSELF @ arg2 13819 b dvmCheckBefore @ (dPC,dFP,self) tail call 13820 13821 /* ------------------------------ */ 13822 .balign 64 13823 .L_ALT_OP_MUL_LONG: /* 0x9d */ 13824 /* File: armv5te/alt_stub.S */ 13825 /* 13826 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13827 * any interesting requests and then jump to the real instruction 13828 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13829 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13830 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13831 * bail to the real handler if breakFlags==0. 13832 */ 13833 ldrb r3, [rSELF, #offThread_breakFlags] 13834 adrl lr, dvmAsmInstructionStart + (157 * 64) 13835 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13836 cmp r3, #0 13837 bxeq lr @ nothing to do - jump to real handler 13838 EXPORT_PC() 13839 mov r0, rPC @ arg0 13840 mov r1, rFP @ arg1 13841 mov r2, rSELF @ arg2 13842 b dvmCheckBefore @ (dPC,dFP,self) tail call 13843 13844 /* ------------------------------ */ 13845 .balign 64 13846 .L_ALT_OP_DIV_LONG: /* 0x9e */ 13847 /* File: armv5te/alt_stub.S */ 13848 /* 13849 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13850 * any interesting requests and then jump to the real instruction 13851 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13852 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13853 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13854 * bail to the real handler if breakFlags==0. 13855 */ 13856 ldrb r3, [rSELF, #offThread_breakFlags] 13857 adrl lr, dvmAsmInstructionStart + (158 * 64) 13858 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13859 cmp r3, #0 13860 bxeq lr @ nothing to do - jump to real handler 13861 EXPORT_PC() 13862 mov r0, rPC @ arg0 13863 mov r1, rFP @ arg1 13864 mov r2, rSELF @ arg2 13865 b dvmCheckBefore @ (dPC,dFP,self) tail call 13866 13867 /* ------------------------------ */ 13868 .balign 64 13869 .L_ALT_OP_REM_LONG: /* 0x9f */ 13870 /* File: armv5te/alt_stub.S */ 13871 /* 13872 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13873 * any interesting requests and then jump to the real instruction 13874 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13875 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13876 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13877 * bail to the real handler if breakFlags==0. 13878 */ 13879 ldrb r3, [rSELF, #offThread_breakFlags] 13880 adrl lr, dvmAsmInstructionStart + (159 * 64) 13881 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13882 cmp r3, #0 13883 bxeq lr @ nothing to do - jump to real handler 13884 EXPORT_PC() 13885 mov r0, rPC @ arg0 13886 mov r1, rFP @ arg1 13887 mov r2, rSELF @ arg2 13888 b dvmCheckBefore @ (dPC,dFP,self) tail call 13889 13890 /* ------------------------------ */ 13891 .balign 64 13892 .L_ALT_OP_AND_LONG: /* 0xa0 */ 13893 /* File: armv5te/alt_stub.S */ 13894 /* 13895 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13896 * any interesting requests and then jump to the real instruction 13897 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13898 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13899 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13900 * bail to the real handler if breakFlags==0. 13901 */ 13902 ldrb r3, [rSELF, #offThread_breakFlags] 13903 adrl lr, dvmAsmInstructionStart + (160 * 64) 13904 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13905 cmp r3, #0 13906 bxeq lr @ nothing to do - jump to real handler 13907 EXPORT_PC() 13908 mov r0, rPC @ arg0 13909 mov r1, rFP @ arg1 13910 mov r2, rSELF @ arg2 13911 b dvmCheckBefore @ (dPC,dFP,self) tail call 13912 13913 /* ------------------------------ */ 13914 .balign 64 13915 .L_ALT_OP_OR_LONG: /* 0xa1 */ 13916 /* File: armv5te/alt_stub.S */ 13917 /* 13918 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13919 * any interesting requests and then jump to the real instruction 13920 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13921 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13922 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13923 * bail to the real handler if breakFlags==0. 13924 */ 13925 ldrb r3, [rSELF, #offThread_breakFlags] 13926 adrl lr, dvmAsmInstructionStart + (161 * 64) 13927 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13928 cmp r3, #0 13929 bxeq lr @ nothing to do - jump to real handler 13930 EXPORT_PC() 13931 mov r0, rPC @ arg0 13932 mov r1, rFP @ arg1 13933 mov r2, rSELF @ arg2 13934 b dvmCheckBefore @ (dPC,dFP,self) tail call 13935 13936 /* ------------------------------ */ 13937 .balign 64 13938 .L_ALT_OP_XOR_LONG: /* 0xa2 */ 13939 /* File: armv5te/alt_stub.S */ 13940 /* 13941 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13942 * any interesting requests and then jump to the real instruction 13943 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13944 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13945 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13946 * bail to the real handler if breakFlags==0. 13947 */ 13948 ldrb r3, [rSELF, #offThread_breakFlags] 13949 adrl lr, dvmAsmInstructionStart + (162 * 64) 13950 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13951 cmp r3, #0 13952 bxeq lr @ nothing to do - jump to real handler 13953 EXPORT_PC() 13954 mov r0, rPC @ arg0 13955 mov r1, rFP @ arg1 13956 mov r2, rSELF @ arg2 13957 b dvmCheckBefore @ (dPC,dFP,self) tail call 13958 13959 /* ------------------------------ */ 13960 .balign 64 13961 .L_ALT_OP_SHL_LONG: /* 0xa3 */ 13962 /* File: armv5te/alt_stub.S */ 13963 /* 13964 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13965 * any interesting requests and then jump to the real instruction 13966 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13967 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13968 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13969 * bail to the real handler if breakFlags==0. 13970 */ 13971 ldrb r3, [rSELF, #offThread_breakFlags] 13972 adrl lr, dvmAsmInstructionStart + (163 * 64) 13973 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13974 cmp r3, #0 13975 bxeq lr @ nothing to do - jump to real handler 13976 EXPORT_PC() 13977 mov r0, rPC @ arg0 13978 mov r1, rFP @ arg1 13979 mov r2, rSELF @ arg2 13980 b dvmCheckBefore @ (dPC,dFP,self) tail call 13981 13982 /* ------------------------------ */ 13983 .balign 64 13984 .L_ALT_OP_SHR_LONG: /* 0xa4 */ 13985 /* File: armv5te/alt_stub.S */ 13986 /* 13987 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13988 * any interesting requests and then jump to the real instruction 13989 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13990 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13991 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13992 * bail to the real handler if breakFlags==0. 13993 */ 13994 ldrb r3, [rSELF, #offThread_breakFlags] 13995 adrl lr, dvmAsmInstructionStart + (164 * 64) 13996 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13997 cmp r3, #0 13998 bxeq lr @ nothing to do - jump to real handler 13999 EXPORT_PC() 14000 mov r0, rPC @ arg0 14001 mov r1, rFP @ arg1 14002 mov r2, rSELF @ arg2 14003 b dvmCheckBefore @ (dPC,dFP,self) tail call 14004 14005 /* ------------------------------ */ 14006 .balign 64 14007 .L_ALT_OP_USHR_LONG: /* 0xa5 */ 14008 /* File: armv5te/alt_stub.S */ 14009 /* 14010 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14011 * any interesting requests and then jump to the real instruction 14012 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14013 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14014 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14015 * bail to the real handler if breakFlags==0. 14016 */ 14017 ldrb r3, [rSELF, #offThread_breakFlags] 14018 adrl lr, dvmAsmInstructionStart + (165 * 64) 14019 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14020 cmp r3, #0 14021 bxeq lr @ nothing to do - jump to real handler 14022 EXPORT_PC() 14023 mov r0, rPC @ arg0 14024 mov r1, rFP @ arg1 14025 mov r2, rSELF @ arg2 14026 b dvmCheckBefore @ (dPC,dFP,self) tail call 14027 14028 /* ------------------------------ */ 14029 .balign 64 14030 .L_ALT_OP_ADD_FLOAT: /* 0xa6 */ 14031 /* File: armv5te/alt_stub.S */ 14032 /* 14033 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14034 * any interesting requests and then jump to the real instruction 14035 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14036 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14037 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14038 * bail to the real handler if breakFlags==0. 14039 */ 14040 ldrb r3, [rSELF, #offThread_breakFlags] 14041 adrl lr, dvmAsmInstructionStart + (166 * 64) 14042 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14043 cmp r3, #0 14044 bxeq lr @ nothing to do - jump to real handler 14045 EXPORT_PC() 14046 mov r0, rPC @ arg0 14047 mov r1, rFP @ arg1 14048 mov r2, rSELF @ arg2 14049 b dvmCheckBefore @ (dPC,dFP,self) tail call 14050 14051 /* ------------------------------ */ 14052 .balign 64 14053 .L_ALT_OP_SUB_FLOAT: /* 0xa7 */ 14054 /* File: armv5te/alt_stub.S */ 14055 /* 14056 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14057 * any interesting requests and then jump to the real instruction 14058 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14059 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14060 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14061 * bail to the real handler if breakFlags==0. 14062 */ 14063 ldrb r3, [rSELF, #offThread_breakFlags] 14064 adrl lr, dvmAsmInstructionStart + (167 * 64) 14065 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14066 cmp r3, #0 14067 bxeq lr @ nothing to do - jump to real handler 14068 EXPORT_PC() 14069 mov r0, rPC @ arg0 14070 mov r1, rFP @ arg1 14071 mov r2, rSELF @ arg2 14072 b dvmCheckBefore @ (dPC,dFP,self) tail call 14073 14074 /* ------------------------------ */ 14075 .balign 64 14076 .L_ALT_OP_MUL_FLOAT: /* 0xa8 */ 14077 /* File: armv5te/alt_stub.S */ 14078 /* 14079 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14080 * any interesting requests and then jump to the real instruction 14081 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14082 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14083 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14084 * bail to the real handler if breakFlags==0. 14085 */ 14086 ldrb r3, [rSELF, #offThread_breakFlags] 14087 adrl lr, dvmAsmInstructionStart + (168 * 64) 14088 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14089 cmp r3, #0 14090 bxeq lr @ nothing to do - jump to real handler 14091 EXPORT_PC() 14092 mov r0, rPC @ arg0 14093 mov r1, rFP @ arg1 14094 mov r2, rSELF @ arg2 14095 b dvmCheckBefore @ (dPC,dFP,self) tail call 14096 14097 /* ------------------------------ */ 14098 .balign 64 14099 .L_ALT_OP_DIV_FLOAT: /* 0xa9 */ 14100 /* File: armv5te/alt_stub.S */ 14101 /* 14102 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14103 * any interesting requests and then jump to the real instruction 14104 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14105 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14106 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14107 * bail to the real handler if breakFlags==0. 14108 */ 14109 ldrb r3, [rSELF, #offThread_breakFlags] 14110 adrl lr, dvmAsmInstructionStart + (169 * 64) 14111 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14112 cmp r3, #0 14113 bxeq lr @ nothing to do - jump to real handler 14114 EXPORT_PC() 14115 mov r0, rPC @ arg0 14116 mov r1, rFP @ arg1 14117 mov r2, rSELF @ arg2 14118 b dvmCheckBefore @ (dPC,dFP,self) tail call 14119 14120 /* ------------------------------ */ 14121 .balign 64 14122 .L_ALT_OP_REM_FLOAT: /* 0xaa */ 14123 /* File: armv5te/alt_stub.S */ 14124 /* 14125 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14126 * any interesting requests and then jump to the real instruction 14127 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14128 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14129 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14130 * bail to the real handler if breakFlags==0. 14131 */ 14132 ldrb r3, [rSELF, #offThread_breakFlags] 14133 adrl lr, dvmAsmInstructionStart + (170 * 64) 14134 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14135 cmp r3, #0 14136 bxeq lr @ nothing to do - jump to real handler 14137 EXPORT_PC() 14138 mov r0, rPC @ arg0 14139 mov r1, rFP @ arg1 14140 mov r2, rSELF @ arg2 14141 b dvmCheckBefore @ (dPC,dFP,self) tail call 14142 14143 /* ------------------------------ */ 14144 .balign 64 14145 .L_ALT_OP_ADD_DOUBLE: /* 0xab */ 14146 /* File: armv5te/alt_stub.S */ 14147 /* 14148 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14149 * any interesting requests and then jump to the real instruction 14150 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14151 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14152 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14153 * bail to the real handler if breakFlags==0. 14154 */ 14155 ldrb r3, [rSELF, #offThread_breakFlags] 14156 adrl lr, dvmAsmInstructionStart + (171 * 64) 14157 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14158 cmp r3, #0 14159 bxeq lr @ nothing to do - jump to real handler 14160 EXPORT_PC() 14161 mov r0, rPC @ arg0 14162 mov r1, rFP @ arg1 14163 mov r2, rSELF @ arg2 14164 b dvmCheckBefore @ (dPC,dFP,self) tail call 14165 14166 /* ------------------------------ */ 14167 .balign 64 14168 .L_ALT_OP_SUB_DOUBLE: /* 0xac */ 14169 /* File: armv5te/alt_stub.S */ 14170 /* 14171 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14172 * any interesting requests and then jump to the real instruction 14173 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14174 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14175 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14176 * bail to the real handler if breakFlags==0. 14177 */ 14178 ldrb r3, [rSELF, #offThread_breakFlags] 14179 adrl lr, dvmAsmInstructionStart + (172 * 64) 14180 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14181 cmp r3, #0 14182 bxeq lr @ nothing to do - jump to real handler 14183 EXPORT_PC() 14184 mov r0, rPC @ arg0 14185 mov r1, rFP @ arg1 14186 mov r2, rSELF @ arg2 14187 b dvmCheckBefore @ (dPC,dFP,self) tail call 14188 14189 /* ------------------------------ */ 14190 .balign 64 14191 .L_ALT_OP_MUL_DOUBLE: /* 0xad */ 14192 /* File: armv5te/alt_stub.S */ 14193 /* 14194 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14195 * any interesting requests and then jump to the real instruction 14196 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14197 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14198 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14199 * bail to the real handler if breakFlags==0. 14200 */ 14201 ldrb r3, [rSELF, #offThread_breakFlags] 14202 adrl lr, dvmAsmInstructionStart + (173 * 64) 14203 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14204 cmp r3, #0 14205 bxeq lr @ nothing to do - jump to real handler 14206 EXPORT_PC() 14207 mov r0, rPC @ arg0 14208 mov r1, rFP @ arg1 14209 mov r2, rSELF @ arg2 14210 b dvmCheckBefore @ (dPC,dFP,self) tail call 14211 14212 /* ------------------------------ */ 14213 .balign 64 14214 .L_ALT_OP_DIV_DOUBLE: /* 0xae */ 14215 /* File: armv5te/alt_stub.S */ 14216 /* 14217 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14218 * any interesting requests and then jump to the real instruction 14219 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14220 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14221 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14222 * bail to the real handler if breakFlags==0. 14223 */ 14224 ldrb r3, [rSELF, #offThread_breakFlags] 14225 adrl lr, dvmAsmInstructionStart + (174 * 64) 14226 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14227 cmp r3, #0 14228 bxeq lr @ nothing to do - jump to real handler 14229 EXPORT_PC() 14230 mov r0, rPC @ arg0 14231 mov r1, rFP @ arg1 14232 mov r2, rSELF @ arg2 14233 b dvmCheckBefore @ (dPC,dFP,self) tail call 14234 14235 /* ------------------------------ */ 14236 .balign 64 14237 .L_ALT_OP_REM_DOUBLE: /* 0xaf */ 14238 /* File: armv5te/alt_stub.S */ 14239 /* 14240 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14241 * any interesting requests and then jump to the real instruction 14242 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14243 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14244 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14245 * bail to the real handler if breakFlags==0. 14246 */ 14247 ldrb r3, [rSELF, #offThread_breakFlags] 14248 adrl lr, dvmAsmInstructionStart + (175 * 64) 14249 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14250 cmp r3, #0 14251 bxeq lr @ nothing to do - jump to real handler 14252 EXPORT_PC() 14253 mov r0, rPC @ arg0 14254 mov r1, rFP @ arg1 14255 mov r2, rSELF @ arg2 14256 b dvmCheckBefore @ (dPC,dFP,self) tail call 14257 14258 /* ------------------------------ */ 14259 .balign 64 14260 .L_ALT_OP_ADD_INT_2ADDR: /* 0xb0 */ 14261 /* File: armv5te/alt_stub.S */ 14262 /* 14263 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14264 * any interesting requests and then jump to the real instruction 14265 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14266 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14267 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14268 * bail to the real handler if breakFlags==0. 14269 */ 14270 ldrb r3, [rSELF, #offThread_breakFlags] 14271 adrl lr, dvmAsmInstructionStart + (176 * 64) 14272 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14273 cmp r3, #0 14274 bxeq lr @ nothing to do - jump to real handler 14275 EXPORT_PC() 14276 mov r0, rPC @ arg0 14277 mov r1, rFP @ arg1 14278 mov r2, rSELF @ arg2 14279 b dvmCheckBefore @ (dPC,dFP,self) tail call 14280 14281 /* ------------------------------ */ 14282 .balign 64 14283 .L_ALT_OP_SUB_INT_2ADDR: /* 0xb1 */ 14284 /* File: armv5te/alt_stub.S */ 14285 /* 14286 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14287 * any interesting requests and then jump to the real instruction 14288 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14289 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14290 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14291 * bail to the real handler if breakFlags==0. 14292 */ 14293 ldrb r3, [rSELF, #offThread_breakFlags] 14294 adrl lr, dvmAsmInstructionStart + (177 * 64) 14295 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14296 cmp r3, #0 14297 bxeq lr @ nothing to do - jump to real handler 14298 EXPORT_PC() 14299 mov r0, rPC @ arg0 14300 mov r1, rFP @ arg1 14301 mov r2, rSELF @ arg2 14302 b dvmCheckBefore @ (dPC,dFP,self) tail call 14303 14304 /* ------------------------------ */ 14305 .balign 64 14306 .L_ALT_OP_MUL_INT_2ADDR: /* 0xb2 */ 14307 /* File: armv5te/alt_stub.S */ 14308 /* 14309 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14310 * any interesting requests and then jump to the real instruction 14311 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14312 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14313 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14314 * bail to the real handler if breakFlags==0. 14315 */ 14316 ldrb r3, [rSELF, #offThread_breakFlags] 14317 adrl lr, dvmAsmInstructionStart + (178 * 64) 14318 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14319 cmp r3, #0 14320 bxeq lr @ nothing to do - jump to real handler 14321 EXPORT_PC() 14322 mov r0, rPC @ arg0 14323 mov r1, rFP @ arg1 14324 mov r2, rSELF @ arg2 14325 b dvmCheckBefore @ (dPC,dFP,self) tail call 14326 14327 /* ------------------------------ */ 14328 .balign 64 14329 .L_ALT_OP_DIV_INT_2ADDR: /* 0xb3 */ 14330 /* File: armv5te/alt_stub.S */ 14331 /* 14332 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14333 * any interesting requests and then jump to the real instruction 14334 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14335 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14336 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14337 * bail to the real handler if breakFlags==0. 14338 */ 14339 ldrb r3, [rSELF, #offThread_breakFlags] 14340 adrl lr, dvmAsmInstructionStart + (179 * 64) 14341 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14342 cmp r3, #0 14343 bxeq lr @ nothing to do - jump to real handler 14344 EXPORT_PC() 14345 mov r0, rPC @ arg0 14346 mov r1, rFP @ arg1 14347 mov r2, rSELF @ arg2 14348 b dvmCheckBefore @ (dPC,dFP,self) tail call 14349 14350 /* ------------------------------ */ 14351 .balign 64 14352 .L_ALT_OP_REM_INT_2ADDR: /* 0xb4 */ 14353 /* File: armv5te/alt_stub.S */ 14354 /* 14355 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14356 * any interesting requests and then jump to the real instruction 14357 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14358 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14359 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14360 * bail to the real handler if breakFlags==0. 14361 */ 14362 ldrb r3, [rSELF, #offThread_breakFlags] 14363 adrl lr, dvmAsmInstructionStart + (180 * 64) 14364 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14365 cmp r3, #0 14366 bxeq lr @ nothing to do - jump to real handler 14367 EXPORT_PC() 14368 mov r0, rPC @ arg0 14369 mov r1, rFP @ arg1 14370 mov r2, rSELF @ arg2 14371 b dvmCheckBefore @ (dPC,dFP,self) tail call 14372 14373 /* ------------------------------ */ 14374 .balign 64 14375 .L_ALT_OP_AND_INT_2ADDR: /* 0xb5 */ 14376 /* File: armv5te/alt_stub.S */ 14377 /* 14378 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14379 * any interesting requests and then jump to the real instruction 14380 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14381 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14382 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14383 * bail to the real handler if breakFlags==0. 14384 */ 14385 ldrb r3, [rSELF, #offThread_breakFlags] 14386 adrl lr, dvmAsmInstructionStart + (181 * 64) 14387 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14388 cmp r3, #0 14389 bxeq lr @ nothing to do - jump to real handler 14390 EXPORT_PC() 14391 mov r0, rPC @ arg0 14392 mov r1, rFP @ arg1 14393 mov r2, rSELF @ arg2 14394 b dvmCheckBefore @ (dPC,dFP,self) tail call 14395 14396 /* ------------------------------ */ 14397 .balign 64 14398 .L_ALT_OP_OR_INT_2ADDR: /* 0xb6 */ 14399 /* File: armv5te/alt_stub.S */ 14400 /* 14401 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14402 * any interesting requests and then jump to the real instruction 14403 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14404 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14405 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14406 * bail to the real handler if breakFlags==0. 14407 */ 14408 ldrb r3, [rSELF, #offThread_breakFlags] 14409 adrl lr, dvmAsmInstructionStart + (182 * 64) 14410 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14411 cmp r3, #0 14412 bxeq lr @ nothing to do - jump to real handler 14413 EXPORT_PC() 14414 mov r0, rPC @ arg0 14415 mov r1, rFP @ arg1 14416 mov r2, rSELF @ arg2 14417 b dvmCheckBefore @ (dPC,dFP,self) tail call 14418 14419 /* ------------------------------ */ 14420 .balign 64 14421 .L_ALT_OP_XOR_INT_2ADDR: /* 0xb7 */ 14422 /* File: armv5te/alt_stub.S */ 14423 /* 14424 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14425 * any interesting requests and then jump to the real instruction 14426 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14427 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14428 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14429 * bail to the real handler if breakFlags==0. 14430 */ 14431 ldrb r3, [rSELF, #offThread_breakFlags] 14432 adrl lr, dvmAsmInstructionStart + (183 * 64) 14433 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14434 cmp r3, #0 14435 bxeq lr @ nothing to do - jump to real handler 14436 EXPORT_PC() 14437 mov r0, rPC @ arg0 14438 mov r1, rFP @ arg1 14439 mov r2, rSELF @ arg2 14440 b dvmCheckBefore @ (dPC,dFP,self) tail call 14441 14442 /* ------------------------------ */ 14443 .balign 64 14444 .L_ALT_OP_SHL_INT_2ADDR: /* 0xb8 */ 14445 /* File: armv5te/alt_stub.S */ 14446 /* 14447 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14448 * any interesting requests and then jump to the real instruction 14449 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14450 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14451 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14452 * bail to the real handler if breakFlags==0. 14453 */ 14454 ldrb r3, [rSELF, #offThread_breakFlags] 14455 adrl lr, dvmAsmInstructionStart + (184 * 64) 14456 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14457 cmp r3, #0 14458 bxeq lr @ nothing to do - jump to real handler 14459 EXPORT_PC() 14460 mov r0, rPC @ arg0 14461 mov r1, rFP @ arg1 14462 mov r2, rSELF @ arg2 14463 b dvmCheckBefore @ (dPC,dFP,self) tail call 14464 14465 /* ------------------------------ */ 14466 .balign 64 14467 .L_ALT_OP_SHR_INT_2ADDR: /* 0xb9 */ 14468 /* File: armv5te/alt_stub.S */ 14469 /* 14470 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14471 * any interesting requests and then jump to the real instruction 14472 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14473 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14474 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14475 * bail to the real handler if breakFlags==0. 14476 */ 14477 ldrb r3, [rSELF, #offThread_breakFlags] 14478 adrl lr, dvmAsmInstructionStart + (185 * 64) 14479 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14480 cmp r3, #0 14481 bxeq lr @ nothing to do - jump to real handler 14482 EXPORT_PC() 14483 mov r0, rPC @ arg0 14484 mov r1, rFP @ arg1 14485 mov r2, rSELF @ arg2 14486 b dvmCheckBefore @ (dPC,dFP,self) tail call 14487 14488 /* ------------------------------ */ 14489 .balign 64 14490 .L_ALT_OP_USHR_INT_2ADDR: /* 0xba */ 14491 /* File: armv5te/alt_stub.S */ 14492 /* 14493 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14494 * any interesting requests and then jump to the real instruction 14495 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14496 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14497 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14498 * bail to the real handler if breakFlags==0. 14499 */ 14500 ldrb r3, [rSELF, #offThread_breakFlags] 14501 adrl lr, dvmAsmInstructionStart + (186 * 64) 14502 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14503 cmp r3, #0 14504 bxeq lr @ nothing to do - jump to real handler 14505 EXPORT_PC() 14506 mov r0, rPC @ arg0 14507 mov r1, rFP @ arg1 14508 mov r2, rSELF @ arg2 14509 b dvmCheckBefore @ (dPC,dFP,self) tail call 14510 14511 /* ------------------------------ */ 14512 .balign 64 14513 .L_ALT_OP_ADD_LONG_2ADDR: /* 0xbb */ 14514 /* File: armv5te/alt_stub.S */ 14515 /* 14516 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14517 * any interesting requests and then jump to the real instruction 14518 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14519 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14520 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14521 * bail to the real handler if breakFlags==0. 14522 */ 14523 ldrb r3, [rSELF, #offThread_breakFlags] 14524 adrl lr, dvmAsmInstructionStart + (187 * 64) 14525 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14526 cmp r3, #0 14527 bxeq lr @ nothing to do - jump to real handler 14528 EXPORT_PC() 14529 mov r0, rPC @ arg0 14530 mov r1, rFP @ arg1 14531 mov r2, rSELF @ arg2 14532 b dvmCheckBefore @ (dPC,dFP,self) tail call 14533 14534 /* ------------------------------ */ 14535 .balign 64 14536 .L_ALT_OP_SUB_LONG_2ADDR: /* 0xbc */ 14537 /* File: armv5te/alt_stub.S */ 14538 /* 14539 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14540 * any interesting requests and then jump to the real instruction 14541 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14542 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14543 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14544 * bail to the real handler if breakFlags==0. 14545 */ 14546 ldrb r3, [rSELF, #offThread_breakFlags] 14547 adrl lr, dvmAsmInstructionStart + (188 * 64) 14548 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14549 cmp r3, #0 14550 bxeq lr @ nothing to do - jump to real handler 14551 EXPORT_PC() 14552 mov r0, rPC @ arg0 14553 mov r1, rFP @ arg1 14554 mov r2, rSELF @ arg2 14555 b dvmCheckBefore @ (dPC,dFP,self) tail call 14556 14557 /* ------------------------------ */ 14558 .balign 64 14559 .L_ALT_OP_MUL_LONG_2ADDR: /* 0xbd */ 14560 /* File: armv5te/alt_stub.S */ 14561 /* 14562 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14563 * any interesting requests and then jump to the real instruction 14564 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14565 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14566 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14567 * bail to the real handler if breakFlags==0. 14568 */ 14569 ldrb r3, [rSELF, #offThread_breakFlags] 14570 adrl lr, dvmAsmInstructionStart + (189 * 64) 14571 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14572 cmp r3, #0 14573 bxeq lr @ nothing to do - jump to real handler 14574 EXPORT_PC() 14575 mov r0, rPC @ arg0 14576 mov r1, rFP @ arg1 14577 mov r2, rSELF @ arg2 14578 b dvmCheckBefore @ (dPC,dFP,self) tail call 14579 14580 /* ------------------------------ */ 14581 .balign 64 14582 .L_ALT_OP_DIV_LONG_2ADDR: /* 0xbe */ 14583 /* File: armv5te/alt_stub.S */ 14584 /* 14585 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14586 * any interesting requests and then jump to the real instruction 14587 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14588 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14589 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14590 * bail to the real handler if breakFlags==0. 14591 */ 14592 ldrb r3, [rSELF, #offThread_breakFlags] 14593 adrl lr, dvmAsmInstructionStart + (190 * 64) 14594 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14595 cmp r3, #0 14596 bxeq lr @ nothing to do - jump to real handler 14597 EXPORT_PC() 14598 mov r0, rPC @ arg0 14599 mov r1, rFP @ arg1 14600 mov r2, rSELF @ arg2 14601 b dvmCheckBefore @ (dPC,dFP,self) tail call 14602 14603 /* ------------------------------ */ 14604 .balign 64 14605 .L_ALT_OP_REM_LONG_2ADDR: /* 0xbf */ 14606 /* File: armv5te/alt_stub.S */ 14607 /* 14608 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14609 * any interesting requests and then jump to the real instruction 14610 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14611 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14612 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14613 * bail to the real handler if breakFlags==0. 14614 */ 14615 ldrb r3, [rSELF, #offThread_breakFlags] 14616 adrl lr, dvmAsmInstructionStart + (191 * 64) 14617 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14618 cmp r3, #0 14619 bxeq lr @ nothing to do - jump to real handler 14620 EXPORT_PC() 14621 mov r0, rPC @ arg0 14622 mov r1, rFP @ arg1 14623 mov r2, rSELF @ arg2 14624 b dvmCheckBefore @ (dPC,dFP,self) tail call 14625 14626 /* ------------------------------ */ 14627 .balign 64 14628 .L_ALT_OP_AND_LONG_2ADDR: /* 0xc0 */ 14629 /* File: armv5te/alt_stub.S */ 14630 /* 14631 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14632 * any interesting requests and then jump to the real instruction 14633 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14634 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14635 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14636 * bail to the real handler if breakFlags==0. 14637 */ 14638 ldrb r3, [rSELF, #offThread_breakFlags] 14639 adrl lr, dvmAsmInstructionStart + (192 * 64) 14640 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14641 cmp r3, #0 14642 bxeq lr @ nothing to do - jump to real handler 14643 EXPORT_PC() 14644 mov r0, rPC @ arg0 14645 mov r1, rFP @ arg1 14646 mov r2, rSELF @ arg2 14647 b dvmCheckBefore @ (dPC,dFP,self) tail call 14648 14649 /* ------------------------------ */ 14650 .balign 64 14651 .L_ALT_OP_OR_LONG_2ADDR: /* 0xc1 */ 14652 /* File: armv5te/alt_stub.S */ 14653 /* 14654 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14655 * any interesting requests and then jump to the real instruction 14656 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14657 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14658 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14659 * bail to the real handler if breakFlags==0. 14660 */ 14661 ldrb r3, [rSELF, #offThread_breakFlags] 14662 adrl lr, dvmAsmInstructionStart + (193 * 64) 14663 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14664 cmp r3, #0 14665 bxeq lr @ nothing to do - jump to real handler 14666 EXPORT_PC() 14667 mov r0, rPC @ arg0 14668 mov r1, rFP @ arg1 14669 mov r2, rSELF @ arg2 14670 b dvmCheckBefore @ (dPC,dFP,self) tail call 14671 14672 /* ------------------------------ */ 14673 .balign 64 14674 .L_ALT_OP_XOR_LONG_2ADDR: /* 0xc2 */ 14675 /* File: armv5te/alt_stub.S */ 14676 /* 14677 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14678 * any interesting requests and then jump to the real instruction 14679 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14680 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14681 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14682 * bail to the real handler if breakFlags==0. 14683 */ 14684 ldrb r3, [rSELF, #offThread_breakFlags] 14685 adrl lr, dvmAsmInstructionStart + (194 * 64) 14686 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14687 cmp r3, #0 14688 bxeq lr @ nothing to do - jump to real handler 14689 EXPORT_PC() 14690 mov r0, rPC @ arg0 14691 mov r1, rFP @ arg1 14692 mov r2, rSELF @ arg2 14693 b dvmCheckBefore @ (dPC,dFP,self) tail call 14694 14695 /* ------------------------------ */ 14696 .balign 64 14697 .L_ALT_OP_SHL_LONG_2ADDR: /* 0xc3 */ 14698 /* File: armv5te/alt_stub.S */ 14699 /* 14700 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14701 * any interesting requests and then jump to the real instruction 14702 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14703 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14704 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14705 * bail to the real handler if breakFlags==0. 14706 */ 14707 ldrb r3, [rSELF, #offThread_breakFlags] 14708 adrl lr, dvmAsmInstructionStart + (195 * 64) 14709 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14710 cmp r3, #0 14711 bxeq lr @ nothing to do - jump to real handler 14712 EXPORT_PC() 14713 mov r0, rPC @ arg0 14714 mov r1, rFP @ arg1 14715 mov r2, rSELF @ arg2 14716 b dvmCheckBefore @ (dPC,dFP,self) tail call 14717 14718 /* ------------------------------ */ 14719 .balign 64 14720 .L_ALT_OP_SHR_LONG_2ADDR: /* 0xc4 */ 14721 /* File: armv5te/alt_stub.S */ 14722 /* 14723 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14724 * any interesting requests and then jump to the real instruction 14725 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14726 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14727 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14728 * bail to the real handler if breakFlags==0. 14729 */ 14730 ldrb r3, [rSELF, #offThread_breakFlags] 14731 adrl lr, dvmAsmInstructionStart + (196 * 64) 14732 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14733 cmp r3, #0 14734 bxeq lr @ nothing to do - jump to real handler 14735 EXPORT_PC() 14736 mov r0, rPC @ arg0 14737 mov r1, rFP @ arg1 14738 mov r2, rSELF @ arg2 14739 b dvmCheckBefore @ (dPC,dFP,self) tail call 14740 14741 /* ------------------------------ */ 14742 .balign 64 14743 .L_ALT_OP_USHR_LONG_2ADDR: /* 0xc5 */ 14744 /* File: armv5te/alt_stub.S */ 14745 /* 14746 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14747 * any interesting requests and then jump to the real instruction 14748 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14749 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14750 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14751 * bail to the real handler if breakFlags==0. 14752 */ 14753 ldrb r3, [rSELF, #offThread_breakFlags] 14754 adrl lr, dvmAsmInstructionStart + (197 * 64) 14755 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14756 cmp r3, #0 14757 bxeq lr @ nothing to do - jump to real handler 14758 EXPORT_PC() 14759 mov r0, rPC @ arg0 14760 mov r1, rFP @ arg1 14761 mov r2, rSELF @ arg2 14762 b dvmCheckBefore @ (dPC,dFP,self) tail call 14763 14764 /* ------------------------------ */ 14765 .balign 64 14766 .L_ALT_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 14767 /* File: armv5te/alt_stub.S */ 14768 /* 14769 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14770 * any interesting requests and then jump to the real instruction 14771 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14772 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14773 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14774 * bail to the real handler if breakFlags==0. 14775 */ 14776 ldrb r3, [rSELF, #offThread_breakFlags] 14777 adrl lr, dvmAsmInstructionStart + (198 * 64) 14778 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14779 cmp r3, #0 14780 bxeq lr @ nothing to do - jump to real handler 14781 EXPORT_PC() 14782 mov r0, rPC @ arg0 14783 mov r1, rFP @ arg1 14784 mov r2, rSELF @ arg2 14785 b dvmCheckBefore @ (dPC,dFP,self) tail call 14786 14787 /* ------------------------------ */ 14788 .balign 64 14789 .L_ALT_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 14790 /* File: armv5te/alt_stub.S */ 14791 /* 14792 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14793 * any interesting requests and then jump to the real instruction 14794 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14795 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14796 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14797 * bail to the real handler if breakFlags==0. 14798 */ 14799 ldrb r3, [rSELF, #offThread_breakFlags] 14800 adrl lr, dvmAsmInstructionStart + (199 * 64) 14801 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14802 cmp r3, #0 14803 bxeq lr @ nothing to do - jump to real handler 14804 EXPORT_PC() 14805 mov r0, rPC @ arg0 14806 mov r1, rFP @ arg1 14807 mov r2, rSELF @ arg2 14808 b dvmCheckBefore @ (dPC,dFP,self) tail call 14809 14810 /* ------------------------------ */ 14811 .balign 64 14812 .L_ALT_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 14813 /* File: armv5te/alt_stub.S */ 14814 /* 14815 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14816 * any interesting requests and then jump to the real instruction 14817 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14818 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14819 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14820 * bail to the real handler if breakFlags==0. 14821 */ 14822 ldrb r3, [rSELF, #offThread_breakFlags] 14823 adrl lr, dvmAsmInstructionStart + (200 * 64) 14824 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14825 cmp r3, #0 14826 bxeq lr @ nothing to do - jump to real handler 14827 EXPORT_PC() 14828 mov r0, rPC @ arg0 14829 mov r1, rFP @ arg1 14830 mov r2, rSELF @ arg2 14831 b dvmCheckBefore @ (dPC,dFP,self) tail call 14832 14833 /* ------------------------------ */ 14834 .balign 64 14835 .L_ALT_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 14836 /* File: armv5te/alt_stub.S */ 14837 /* 14838 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14839 * any interesting requests and then jump to the real instruction 14840 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14841 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14842 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14843 * bail to the real handler if breakFlags==0. 14844 */ 14845 ldrb r3, [rSELF, #offThread_breakFlags] 14846 adrl lr, dvmAsmInstructionStart + (201 * 64) 14847 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14848 cmp r3, #0 14849 bxeq lr @ nothing to do - jump to real handler 14850 EXPORT_PC() 14851 mov r0, rPC @ arg0 14852 mov r1, rFP @ arg1 14853 mov r2, rSELF @ arg2 14854 b dvmCheckBefore @ (dPC,dFP,self) tail call 14855 14856 /* ------------------------------ */ 14857 .balign 64 14858 .L_ALT_OP_REM_FLOAT_2ADDR: /* 0xca */ 14859 /* File: armv5te/alt_stub.S */ 14860 /* 14861 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14862 * any interesting requests and then jump to the real instruction 14863 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14864 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14865 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14866 * bail to the real handler if breakFlags==0. 14867 */ 14868 ldrb r3, [rSELF, #offThread_breakFlags] 14869 adrl lr, dvmAsmInstructionStart + (202 * 64) 14870 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14871 cmp r3, #0 14872 bxeq lr @ nothing to do - jump to real handler 14873 EXPORT_PC() 14874 mov r0, rPC @ arg0 14875 mov r1, rFP @ arg1 14876 mov r2, rSELF @ arg2 14877 b dvmCheckBefore @ (dPC,dFP,self) tail call 14878 14879 /* ------------------------------ */ 14880 .balign 64 14881 .L_ALT_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 14882 /* File: armv5te/alt_stub.S */ 14883 /* 14884 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14885 * any interesting requests and then jump to the real instruction 14886 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14887 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14888 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14889 * bail to the real handler if breakFlags==0. 14890 */ 14891 ldrb r3, [rSELF, #offThread_breakFlags] 14892 adrl lr, dvmAsmInstructionStart + (203 * 64) 14893 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14894 cmp r3, #0 14895 bxeq lr @ nothing to do - jump to real handler 14896 EXPORT_PC() 14897 mov r0, rPC @ arg0 14898 mov r1, rFP @ arg1 14899 mov r2, rSELF @ arg2 14900 b dvmCheckBefore @ (dPC,dFP,self) tail call 14901 14902 /* ------------------------------ */ 14903 .balign 64 14904 .L_ALT_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 14905 /* File: armv5te/alt_stub.S */ 14906 /* 14907 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14908 * any interesting requests and then jump to the real instruction 14909 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14910 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14911 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14912 * bail to the real handler if breakFlags==0. 14913 */ 14914 ldrb r3, [rSELF, #offThread_breakFlags] 14915 adrl lr, dvmAsmInstructionStart + (204 * 64) 14916 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14917 cmp r3, #0 14918 bxeq lr @ nothing to do - jump to real handler 14919 EXPORT_PC() 14920 mov r0, rPC @ arg0 14921 mov r1, rFP @ arg1 14922 mov r2, rSELF @ arg2 14923 b dvmCheckBefore @ (dPC,dFP,self) tail call 14924 14925 /* ------------------------------ */ 14926 .balign 64 14927 .L_ALT_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 14928 /* File: armv5te/alt_stub.S */ 14929 /* 14930 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14931 * any interesting requests and then jump to the real instruction 14932 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14933 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14934 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14935 * bail to the real handler if breakFlags==0. 14936 */ 14937 ldrb r3, [rSELF, #offThread_breakFlags] 14938 adrl lr, dvmAsmInstructionStart + (205 * 64) 14939 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14940 cmp r3, #0 14941 bxeq lr @ nothing to do - jump to real handler 14942 EXPORT_PC() 14943 mov r0, rPC @ arg0 14944 mov r1, rFP @ arg1 14945 mov r2, rSELF @ arg2 14946 b dvmCheckBefore @ (dPC,dFP,self) tail call 14947 14948 /* ------------------------------ */ 14949 .balign 64 14950 .L_ALT_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 14951 /* File: armv5te/alt_stub.S */ 14952 /* 14953 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14954 * any interesting requests and then jump to the real instruction 14955 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14956 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14957 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14958 * bail to the real handler if breakFlags==0. 14959 */ 14960 ldrb r3, [rSELF, #offThread_breakFlags] 14961 adrl lr, dvmAsmInstructionStart + (206 * 64) 14962 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14963 cmp r3, #0 14964 bxeq lr @ nothing to do - jump to real handler 14965 EXPORT_PC() 14966 mov r0, rPC @ arg0 14967 mov r1, rFP @ arg1 14968 mov r2, rSELF @ arg2 14969 b dvmCheckBefore @ (dPC,dFP,self) tail call 14970 14971 /* ------------------------------ */ 14972 .balign 64 14973 .L_ALT_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 14974 /* File: armv5te/alt_stub.S */ 14975 /* 14976 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14977 * any interesting requests and then jump to the real instruction 14978 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14979 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14980 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14981 * bail to the real handler if breakFlags==0. 14982 */ 14983 ldrb r3, [rSELF, #offThread_breakFlags] 14984 adrl lr, dvmAsmInstructionStart + (207 * 64) 14985 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14986 cmp r3, #0 14987 bxeq lr @ nothing to do - jump to real handler 14988 EXPORT_PC() 14989 mov r0, rPC @ arg0 14990 mov r1, rFP @ arg1 14991 mov r2, rSELF @ arg2 14992 b dvmCheckBefore @ (dPC,dFP,self) tail call 14993 14994 /* ------------------------------ */ 14995 .balign 64 14996 .L_ALT_OP_ADD_INT_LIT16: /* 0xd0 */ 14997 /* File: armv5te/alt_stub.S */ 14998 /* 14999 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15000 * any interesting requests and then jump to the real instruction 15001 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15002 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15003 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15004 * bail to the real handler if breakFlags==0. 15005 */ 15006 ldrb r3, [rSELF, #offThread_breakFlags] 15007 adrl lr, dvmAsmInstructionStart + (208 * 64) 15008 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15009 cmp r3, #0 15010 bxeq lr @ nothing to do - jump to real handler 15011 EXPORT_PC() 15012 mov r0, rPC @ arg0 15013 mov r1, rFP @ arg1 15014 mov r2, rSELF @ arg2 15015 b dvmCheckBefore @ (dPC,dFP,self) tail call 15016 15017 /* ------------------------------ */ 15018 .balign 64 15019 .L_ALT_OP_RSUB_INT: /* 0xd1 */ 15020 /* File: armv5te/alt_stub.S */ 15021 /* 15022 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15023 * any interesting requests and then jump to the real instruction 15024 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15025 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15026 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15027 * bail to the real handler if breakFlags==0. 15028 */ 15029 ldrb r3, [rSELF, #offThread_breakFlags] 15030 adrl lr, dvmAsmInstructionStart + (209 * 64) 15031 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15032 cmp r3, #0 15033 bxeq lr @ nothing to do - jump to real handler 15034 EXPORT_PC() 15035 mov r0, rPC @ arg0 15036 mov r1, rFP @ arg1 15037 mov r2, rSELF @ arg2 15038 b dvmCheckBefore @ (dPC,dFP,self) tail call 15039 15040 /* ------------------------------ */ 15041 .balign 64 15042 .L_ALT_OP_MUL_INT_LIT16: /* 0xd2 */ 15043 /* File: armv5te/alt_stub.S */ 15044 /* 15045 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15046 * any interesting requests and then jump to the real instruction 15047 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15048 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15049 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15050 * bail to the real handler if breakFlags==0. 15051 */ 15052 ldrb r3, [rSELF, #offThread_breakFlags] 15053 adrl lr, dvmAsmInstructionStart + (210 * 64) 15054 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15055 cmp r3, #0 15056 bxeq lr @ nothing to do - jump to real handler 15057 EXPORT_PC() 15058 mov r0, rPC @ arg0 15059 mov r1, rFP @ arg1 15060 mov r2, rSELF @ arg2 15061 b dvmCheckBefore @ (dPC,dFP,self) tail call 15062 15063 /* ------------------------------ */ 15064 .balign 64 15065 .L_ALT_OP_DIV_INT_LIT16: /* 0xd3 */ 15066 /* File: armv5te/alt_stub.S */ 15067 /* 15068 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15069 * any interesting requests and then jump to the real instruction 15070 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15071 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15072 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15073 * bail to the real handler if breakFlags==0. 15074 */ 15075 ldrb r3, [rSELF, #offThread_breakFlags] 15076 adrl lr, dvmAsmInstructionStart + (211 * 64) 15077 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15078 cmp r3, #0 15079 bxeq lr @ nothing to do - jump to real handler 15080 EXPORT_PC() 15081 mov r0, rPC @ arg0 15082 mov r1, rFP @ arg1 15083 mov r2, rSELF @ arg2 15084 b dvmCheckBefore @ (dPC,dFP,self) tail call 15085 15086 /* ------------------------------ */ 15087 .balign 64 15088 .L_ALT_OP_REM_INT_LIT16: /* 0xd4 */ 15089 /* File: armv5te/alt_stub.S */ 15090 /* 15091 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15092 * any interesting requests and then jump to the real instruction 15093 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15094 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15095 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15096 * bail to the real handler if breakFlags==0. 15097 */ 15098 ldrb r3, [rSELF, #offThread_breakFlags] 15099 adrl lr, dvmAsmInstructionStart + (212 * 64) 15100 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15101 cmp r3, #0 15102 bxeq lr @ nothing to do - jump to real handler 15103 EXPORT_PC() 15104 mov r0, rPC @ arg0 15105 mov r1, rFP @ arg1 15106 mov r2, rSELF @ arg2 15107 b dvmCheckBefore @ (dPC,dFP,self) tail call 15108 15109 /* ------------------------------ */ 15110 .balign 64 15111 .L_ALT_OP_AND_INT_LIT16: /* 0xd5 */ 15112 /* File: armv5te/alt_stub.S */ 15113 /* 15114 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15115 * any interesting requests and then jump to the real instruction 15116 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15117 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15118 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15119 * bail to the real handler if breakFlags==0. 15120 */ 15121 ldrb r3, [rSELF, #offThread_breakFlags] 15122 adrl lr, dvmAsmInstructionStart + (213 * 64) 15123 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15124 cmp r3, #0 15125 bxeq lr @ nothing to do - jump to real handler 15126 EXPORT_PC() 15127 mov r0, rPC @ arg0 15128 mov r1, rFP @ arg1 15129 mov r2, rSELF @ arg2 15130 b dvmCheckBefore @ (dPC,dFP,self) tail call 15131 15132 /* ------------------------------ */ 15133 .balign 64 15134 .L_ALT_OP_OR_INT_LIT16: /* 0xd6 */ 15135 /* File: armv5te/alt_stub.S */ 15136 /* 15137 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15138 * any interesting requests and then jump to the real instruction 15139 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15140 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15141 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15142 * bail to the real handler if breakFlags==0. 15143 */ 15144 ldrb r3, [rSELF, #offThread_breakFlags] 15145 adrl lr, dvmAsmInstructionStart + (214 * 64) 15146 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15147 cmp r3, #0 15148 bxeq lr @ nothing to do - jump to real handler 15149 EXPORT_PC() 15150 mov r0, rPC @ arg0 15151 mov r1, rFP @ arg1 15152 mov r2, rSELF @ arg2 15153 b dvmCheckBefore @ (dPC,dFP,self) tail call 15154 15155 /* ------------------------------ */ 15156 .balign 64 15157 .L_ALT_OP_XOR_INT_LIT16: /* 0xd7 */ 15158 /* File: armv5te/alt_stub.S */ 15159 /* 15160 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15161 * any interesting requests and then jump to the real instruction 15162 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15163 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15164 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15165 * bail to the real handler if breakFlags==0. 15166 */ 15167 ldrb r3, [rSELF, #offThread_breakFlags] 15168 adrl lr, dvmAsmInstructionStart + (215 * 64) 15169 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15170 cmp r3, #0 15171 bxeq lr @ nothing to do - jump to real handler 15172 EXPORT_PC() 15173 mov r0, rPC @ arg0 15174 mov r1, rFP @ arg1 15175 mov r2, rSELF @ arg2 15176 b dvmCheckBefore @ (dPC,dFP,self) tail call 15177 15178 /* ------------------------------ */ 15179 .balign 64 15180 .L_ALT_OP_ADD_INT_LIT8: /* 0xd8 */ 15181 /* File: armv5te/alt_stub.S */ 15182 /* 15183 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15184 * any interesting requests and then jump to the real instruction 15185 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15186 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15187 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15188 * bail to the real handler if breakFlags==0. 15189 */ 15190 ldrb r3, [rSELF, #offThread_breakFlags] 15191 adrl lr, dvmAsmInstructionStart + (216 * 64) 15192 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15193 cmp r3, #0 15194 bxeq lr @ nothing to do - jump to real handler 15195 EXPORT_PC() 15196 mov r0, rPC @ arg0 15197 mov r1, rFP @ arg1 15198 mov r2, rSELF @ arg2 15199 b dvmCheckBefore @ (dPC,dFP,self) tail call 15200 15201 /* ------------------------------ */ 15202 .balign 64 15203 .L_ALT_OP_RSUB_INT_LIT8: /* 0xd9 */ 15204 /* File: armv5te/alt_stub.S */ 15205 /* 15206 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15207 * any interesting requests and then jump to the real instruction 15208 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15209 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15210 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15211 * bail to the real handler if breakFlags==0. 15212 */ 15213 ldrb r3, [rSELF, #offThread_breakFlags] 15214 adrl lr, dvmAsmInstructionStart + (217 * 64) 15215 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15216 cmp r3, #0 15217 bxeq lr @ nothing to do - jump to real handler 15218 EXPORT_PC() 15219 mov r0, rPC @ arg0 15220 mov r1, rFP @ arg1 15221 mov r2, rSELF @ arg2 15222 b dvmCheckBefore @ (dPC,dFP,self) tail call 15223 15224 /* ------------------------------ */ 15225 .balign 64 15226 .L_ALT_OP_MUL_INT_LIT8: /* 0xda */ 15227 /* File: armv5te/alt_stub.S */ 15228 /* 15229 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15230 * any interesting requests and then jump to the real instruction 15231 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15232 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15233 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15234 * bail to the real handler if breakFlags==0. 15235 */ 15236 ldrb r3, [rSELF, #offThread_breakFlags] 15237 adrl lr, dvmAsmInstructionStart + (218 * 64) 15238 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15239 cmp r3, #0 15240 bxeq lr @ nothing to do - jump to real handler 15241 EXPORT_PC() 15242 mov r0, rPC @ arg0 15243 mov r1, rFP @ arg1 15244 mov r2, rSELF @ arg2 15245 b dvmCheckBefore @ (dPC,dFP,self) tail call 15246 15247 /* ------------------------------ */ 15248 .balign 64 15249 .L_ALT_OP_DIV_INT_LIT8: /* 0xdb */ 15250 /* File: armv5te/alt_stub.S */ 15251 /* 15252 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15253 * any interesting requests and then jump to the real instruction 15254 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15255 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15256 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15257 * bail to the real handler if breakFlags==0. 15258 */ 15259 ldrb r3, [rSELF, #offThread_breakFlags] 15260 adrl lr, dvmAsmInstructionStart + (219 * 64) 15261 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15262 cmp r3, #0 15263 bxeq lr @ nothing to do - jump to real handler 15264 EXPORT_PC() 15265 mov r0, rPC @ arg0 15266 mov r1, rFP @ arg1 15267 mov r2, rSELF @ arg2 15268 b dvmCheckBefore @ (dPC,dFP,self) tail call 15269 15270 /* ------------------------------ */ 15271 .balign 64 15272 .L_ALT_OP_REM_INT_LIT8: /* 0xdc */ 15273 /* File: armv5te/alt_stub.S */ 15274 /* 15275 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15276 * any interesting requests and then jump to the real instruction 15277 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15278 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15279 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15280 * bail to the real handler if breakFlags==0. 15281 */ 15282 ldrb r3, [rSELF, #offThread_breakFlags] 15283 adrl lr, dvmAsmInstructionStart + (220 * 64) 15284 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15285 cmp r3, #0 15286 bxeq lr @ nothing to do - jump to real handler 15287 EXPORT_PC() 15288 mov r0, rPC @ arg0 15289 mov r1, rFP @ arg1 15290 mov r2, rSELF @ arg2 15291 b dvmCheckBefore @ (dPC,dFP,self) tail call 15292 15293 /* ------------------------------ */ 15294 .balign 64 15295 .L_ALT_OP_AND_INT_LIT8: /* 0xdd */ 15296 /* File: armv5te/alt_stub.S */ 15297 /* 15298 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15299 * any interesting requests and then jump to the real instruction 15300 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15301 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15302 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15303 * bail to the real handler if breakFlags==0. 15304 */ 15305 ldrb r3, [rSELF, #offThread_breakFlags] 15306 adrl lr, dvmAsmInstructionStart + (221 * 64) 15307 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15308 cmp r3, #0 15309 bxeq lr @ nothing to do - jump to real handler 15310 EXPORT_PC() 15311 mov r0, rPC @ arg0 15312 mov r1, rFP @ arg1 15313 mov r2, rSELF @ arg2 15314 b dvmCheckBefore @ (dPC,dFP,self) tail call 15315 15316 /* ------------------------------ */ 15317 .balign 64 15318 .L_ALT_OP_OR_INT_LIT8: /* 0xde */ 15319 /* File: armv5te/alt_stub.S */ 15320 /* 15321 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15322 * any interesting requests and then jump to the real instruction 15323 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15324 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15325 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15326 * bail to the real handler if breakFlags==0. 15327 */ 15328 ldrb r3, [rSELF, #offThread_breakFlags] 15329 adrl lr, dvmAsmInstructionStart + (222 * 64) 15330 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15331 cmp r3, #0 15332 bxeq lr @ nothing to do - jump to real handler 15333 EXPORT_PC() 15334 mov r0, rPC @ arg0 15335 mov r1, rFP @ arg1 15336 mov r2, rSELF @ arg2 15337 b dvmCheckBefore @ (dPC,dFP,self) tail call 15338 15339 /* ------------------------------ */ 15340 .balign 64 15341 .L_ALT_OP_XOR_INT_LIT8: /* 0xdf */ 15342 /* File: armv5te/alt_stub.S */ 15343 /* 15344 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15345 * any interesting requests and then jump to the real instruction 15346 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15347 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15348 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15349 * bail to the real handler if breakFlags==0. 15350 */ 15351 ldrb r3, [rSELF, #offThread_breakFlags] 15352 adrl lr, dvmAsmInstructionStart + (223 * 64) 15353 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15354 cmp r3, #0 15355 bxeq lr @ nothing to do - jump to real handler 15356 EXPORT_PC() 15357 mov r0, rPC @ arg0 15358 mov r1, rFP @ arg1 15359 mov r2, rSELF @ arg2 15360 b dvmCheckBefore @ (dPC,dFP,self) tail call 15361 15362 /* ------------------------------ */ 15363 .balign 64 15364 .L_ALT_OP_SHL_INT_LIT8: /* 0xe0 */ 15365 /* File: armv5te/alt_stub.S */ 15366 /* 15367 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15368 * any interesting requests and then jump to the real instruction 15369 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15370 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15371 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15372 * bail to the real handler if breakFlags==0. 15373 */ 15374 ldrb r3, [rSELF, #offThread_breakFlags] 15375 adrl lr, dvmAsmInstructionStart + (224 * 64) 15376 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15377 cmp r3, #0 15378 bxeq lr @ nothing to do - jump to real handler 15379 EXPORT_PC() 15380 mov r0, rPC @ arg0 15381 mov r1, rFP @ arg1 15382 mov r2, rSELF @ arg2 15383 b dvmCheckBefore @ (dPC,dFP,self) tail call 15384 15385 /* ------------------------------ */ 15386 .balign 64 15387 .L_ALT_OP_SHR_INT_LIT8: /* 0xe1 */ 15388 /* File: armv5te/alt_stub.S */ 15389 /* 15390 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15391 * any interesting requests and then jump to the real instruction 15392 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15393 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15394 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15395 * bail to the real handler if breakFlags==0. 15396 */ 15397 ldrb r3, [rSELF, #offThread_breakFlags] 15398 adrl lr, dvmAsmInstructionStart + (225 * 64) 15399 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15400 cmp r3, #0 15401 bxeq lr @ nothing to do - jump to real handler 15402 EXPORT_PC() 15403 mov r0, rPC @ arg0 15404 mov r1, rFP @ arg1 15405 mov r2, rSELF @ arg2 15406 b dvmCheckBefore @ (dPC,dFP,self) tail call 15407 15408 /* ------------------------------ */ 15409 .balign 64 15410 .L_ALT_OP_USHR_INT_LIT8: /* 0xe2 */ 15411 /* File: armv5te/alt_stub.S */ 15412 /* 15413 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15414 * any interesting requests and then jump to the real instruction 15415 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15416 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15417 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15418 * bail to the real handler if breakFlags==0. 15419 */ 15420 ldrb r3, [rSELF, #offThread_breakFlags] 15421 adrl lr, dvmAsmInstructionStart + (226 * 64) 15422 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15423 cmp r3, #0 15424 bxeq lr @ nothing to do - jump to real handler 15425 EXPORT_PC() 15426 mov r0, rPC @ arg0 15427 mov r1, rFP @ arg1 15428 mov r2, rSELF @ arg2 15429 b dvmCheckBefore @ (dPC,dFP,self) tail call 15430 15431 /* ------------------------------ */ 15432 .balign 64 15433 .L_ALT_OP_IGET_VOLATILE: /* 0xe3 */ 15434 /* File: armv5te/alt_stub.S */ 15435 /* 15436 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15437 * any interesting requests and then jump to the real instruction 15438 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15439 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15440 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15441 * bail to the real handler if breakFlags==0. 15442 */ 15443 ldrb r3, [rSELF, #offThread_breakFlags] 15444 adrl lr, dvmAsmInstructionStart + (227 * 64) 15445 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15446 cmp r3, #0 15447 bxeq lr @ nothing to do - jump to real handler 15448 EXPORT_PC() 15449 mov r0, rPC @ arg0 15450 mov r1, rFP @ arg1 15451 mov r2, rSELF @ arg2 15452 b dvmCheckBefore @ (dPC,dFP,self) tail call 15453 15454 /* ------------------------------ */ 15455 .balign 64 15456 .L_ALT_OP_IPUT_VOLATILE: /* 0xe4 */ 15457 /* File: armv5te/alt_stub.S */ 15458 /* 15459 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15460 * any interesting requests and then jump to the real instruction 15461 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15462 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15463 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15464 * bail to the real handler if breakFlags==0. 15465 */ 15466 ldrb r3, [rSELF, #offThread_breakFlags] 15467 adrl lr, dvmAsmInstructionStart + (228 * 64) 15468 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15469 cmp r3, #0 15470 bxeq lr @ nothing to do - jump to real handler 15471 EXPORT_PC() 15472 mov r0, rPC @ arg0 15473 mov r1, rFP @ arg1 15474 mov r2, rSELF @ arg2 15475 b dvmCheckBefore @ (dPC,dFP,self) tail call 15476 15477 /* ------------------------------ */ 15478 .balign 64 15479 .L_ALT_OP_SGET_VOLATILE: /* 0xe5 */ 15480 /* File: armv5te/alt_stub.S */ 15481 /* 15482 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15483 * any interesting requests and then jump to the real instruction 15484 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15485 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15486 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15487 * bail to the real handler if breakFlags==0. 15488 */ 15489 ldrb r3, [rSELF, #offThread_breakFlags] 15490 adrl lr, dvmAsmInstructionStart + (229 * 64) 15491 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15492 cmp r3, #0 15493 bxeq lr @ nothing to do - jump to real handler 15494 EXPORT_PC() 15495 mov r0, rPC @ arg0 15496 mov r1, rFP @ arg1 15497 mov r2, rSELF @ arg2 15498 b dvmCheckBefore @ (dPC,dFP,self) tail call 15499 15500 /* ------------------------------ */ 15501 .balign 64 15502 .L_ALT_OP_SPUT_VOLATILE: /* 0xe6 */ 15503 /* File: armv5te/alt_stub.S */ 15504 /* 15505 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15506 * any interesting requests and then jump to the real instruction 15507 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15508 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15509 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15510 * bail to the real handler if breakFlags==0. 15511 */ 15512 ldrb r3, [rSELF, #offThread_breakFlags] 15513 adrl lr, dvmAsmInstructionStart + (230 * 64) 15514 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15515 cmp r3, #0 15516 bxeq lr @ nothing to do - jump to real handler 15517 EXPORT_PC() 15518 mov r0, rPC @ arg0 15519 mov r1, rFP @ arg1 15520 mov r2, rSELF @ arg2 15521 b dvmCheckBefore @ (dPC,dFP,self) tail call 15522 15523 /* ------------------------------ */ 15524 .balign 64 15525 .L_ALT_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 15526 /* File: armv5te/alt_stub.S */ 15527 /* 15528 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15529 * any interesting requests and then jump to the real instruction 15530 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15531 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15532 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15533 * bail to the real handler if breakFlags==0. 15534 */ 15535 ldrb r3, [rSELF, #offThread_breakFlags] 15536 adrl lr, dvmAsmInstructionStart + (231 * 64) 15537 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15538 cmp r3, #0 15539 bxeq lr @ nothing to do - jump to real handler 15540 EXPORT_PC() 15541 mov r0, rPC @ arg0 15542 mov r1, rFP @ arg1 15543 mov r2, rSELF @ arg2 15544 b dvmCheckBefore @ (dPC,dFP,self) tail call 15545 15546 /* ------------------------------ */ 15547 .balign 64 15548 .L_ALT_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 15549 /* File: armv5te/alt_stub.S */ 15550 /* 15551 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15552 * any interesting requests and then jump to the real instruction 15553 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15554 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15555 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15556 * bail to the real handler if breakFlags==0. 15557 */ 15558 ldrb r3, [rSELF, #offThread_breakFlags] 15559 adrl lr, dvmAsmInstructionStart + (232 * 64) 15560 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15561 cmp r3, #0 15562 bxeq lr @ nothing to do - jump to real handler 15563 EXPORT_PC() 15564 mov r0, rPC @ arg0 15565 mov r1, rFP @ arg1 15566 mov r2, rSELF @ arg2 15567 b dvmCheckBefore @ (dPC,dFP,self) tail call 15568 15569 /* ------------------------------ */ 15570 .balign 64 15571 .L_ALT_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 15572 /* File: armv5te/alt_stub.S */ 15573 /* 15574 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15575 * any interesting requests and then jump to the real instruction 15576 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15577 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15578 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15579 * bail to the real handler if breakFlags==0. 15580 */ 15581 ldrb r3, [rSELF, #offThread_breakFlags] 15582 adrl lr, dvmAsmInstructionStart + (233 * 64) 15583 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15584 cmp r3, #0 15585 bxeq lr @ nothing to do - jump to real handler 15586 EXPORT_PC() 15587 mov r0, rPC @ arg0 15588 mov r1, rFP @ arg1 15589 mov r2, rSELF @ arg2 15590 b dvmCheckBefore @ (dPC,dFP,self) tail call 15591 15592 /* ------------------------------ */ 15593 .balign 64 15594 .L_ALT_OP_SGET_WIDE_VOLATILE: /* 0xea */ 15595 /* File: armv5te/alt_stub.S */ 15596 /* 15597 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15598 * any interesting requests and then jump to the real instruction 15599 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15600 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15601 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15602 * bail to the real handler if breakFlags==0. 15603 */ 15604 ldrb r3, [rSELF, #offThread_breakFlags] 15605 adrl lr, dvmAsmInstructionStart + (234 * 64) 15606 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15607 cmp r3, #0 15608 bxeq lr @ nothing to do - jump to real handler 15609 EXPORT_PC() 15610 mov r0, rPC @ arg0 15611 mov r1, rFP @ arg1 15612 mov r2, rSELF @ arg2 15613 b dvmCheckBefore @ (dPC,dFP,self) tail call 15614 15615 /* ------------------------------ */ 15616 .balign 64 15617 .L_ALT_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 15618 /* File: armv5te/alt_stub.S */ 15619 /* 15620 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15621 * any interesting requests and then jump to the real instruction 15622 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15623 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15624 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15625 * bail to the real handler if breakFlags==0. 15626 */ 15627 ldrb r3, [rSELF, #offThread_breakFlags] 15628 adrl lr, dvmAsmInstructionStart + (235 * 64) 15629 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15630 cmp r3, #0 15631 bxeq lr @ nothing to do - jump to real handler 15632 EXPORT_PC() 15633 mov r0, rPC @ arg0 15634 mov r1, rFP @ arg1 15635 mov r2, rSELF @ arg2 15636 b dvmCheckBefore @ (dPC,dFP,self) tail call 15637 15638 /* ------------------------------ */ 15639 .balign 64 15640 .L_ALT_OP_BREAKPOINT: /* 0xec */ 15641 /* File: armv5te/alt_stub.S */ 15642 /* 15643 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15644 * any interesting requests and then jump to the real instruction 15645 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15646 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15647 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15648 * bail to the real handler if breakFlags==0. 15649 */ 15650 ldrb r3, [rSELF, #offThread_breakFlags] 15651 adrl lr, dvmAsmInstructionStart + (236 * 64) 15652 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15653 cmp r3, #0 15654 bxeq lr @ nothing to do - jump to real handler 15655 EXPORT_PC() 15656 mov r0, rPC @ arg0 15657 mov r1, rFP @ arg1 15658 mov r2, rSELF @ arg2 15659 b dvmCheckBefore @ (dPC,dFP,self) tail call 15660 15661 /* ------------------------------ */ 15662 .balign 64 15663 .L_ALT_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 15664 /* File: armv5te/alt_stub.S */ 15665 /* 15666 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15667 * any interesting requests and then jump to the real instruction 15668 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15669 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15670 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15671 * bail to the real handler if breakFlags==0. 15672 */ 15673 ldrb r3, [rSELF, #offThread_breakFlags] 15674 adrl lr, dvmAsmInstructionStart + (237 * 64) 15675 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15676 cmp r3, #0 15677 bxeq lr @ nothing to do - jump to real handler 15678 EXPORT_PC() 15679 mov r0, rPC @ arg0 15680 mov r1, rFP @ arg1 15681 mov r2, rSELF @ arg2 15682 b dvmCheckBefore @ (dPC,dFP,self) tail call 15683 15684 /* ------------------------------ */ 15685 .balign 64 15686 .L_ALT_OP_EXECUTE_INLINE: /* 0xee */ 15687 /* File: armv5te/alt_stub.S */ 15688 /* 15689 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15690 * any interesting requests and then jump to the real instruction 15691 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15692 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15693 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15694 * bail to the real handler if breakFlags==0. 15695 */ 15696 ldrb r3, [rSELF, #offThread_breakFlags] 15697 adrl lr, dvmAsmInstructionStart + (238 * 64) 15698 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15699 cmp r3, #0 15700 bxeq lr @ nothing to do - jump to real handler 15701 EXPORT_PC() 15702 mov r0, rPC @ arg0 15703 mov r1, rFP @ arg1 15704 mov r2, rSELF @ arg2 15705 b dvmCheckBefore @ (dPC,dFP,self) tail call 15706 15707 /* ------------------------------ */ 15708 .balign 64 15709 .L_ALT_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 15710 /* File: armv5te/alt_stub.S */ 15711 /* 15712 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15713 * any interesting requests and then jump to the real instruction 15714 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15715 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15716 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15717 * bail to the real handler if breakFlags==0. 15718 */ 15719 ldrb r3, [rSELF, #offThread_breakFlags] 15720 adrl lr, dvmAsmInstructionStart + (239 * 64) 15721 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15722 cmp r3, #0 15723 bxeq lr @ nothing to do - jump to real handler 15724 EXPORT_PC() 15725 mov r0, rPC @ arg0 15726 mov r1, rFP @ arg1 15727 mov r2, rSELF @ arg2 15728 b dvmCheckBefore @ (dPC,dFP,self) tail call 15729 15730 /* ------------------------------ */ 15731 .balign 64 15732 .L_ALT_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */ 15733 /* File: armv5te/alt_stub.S */ 15734 /* 15735 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15736 * any interesting requests and then jump to the real instruction 15737 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15738 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15739 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15740 * bail to the real handler if breakFlags==0. 15741 */ 15742 ldrb r3, [rSELF, #offThread_breakFlags] 15743 adrl lr, dvmAsmInstructionStart + (240 * 64) 15744 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15745 cmp r3, #0 15746 bxeq lr @ nothing to do - jump to real handler 15747 EXPORT_PC() 15748 mov r0, rPC @ arg0 15749 mov r1, rFP @ arg1 15750 mov r2, rSELF @ arg2 15751 b dvmCheckBefore @ (dPC,dFP,self) tail call 15752 15753 /* ------------------------------ */ 15754 .balign 64 15755 .L_ALT_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 15756 /* File: armv5te/alt_stub.S */ 15757 /* 15758 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15759 * any interesting requests and then jump to the real instruction 15760 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15761 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15762 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15763 * bail to the real handler if breakFlags==0. 15764 */ 15765 ldrb r3, [rSELF, #offThread_breakFlags] 15766 adrl lr, dvmAsmInstructionStart + (241 * 64) 15767 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15768 cmp r3, #0 15769 bxeq lr @ nothing to do - jump to real handler 15770 EXPORT_PC() 15771 mov r0, rPC @ arg0 15772 mov r1, rFP @ arg1 15773 mov r2, rSELF @ arg2 15774 b dvmCheckBefore @ (dPC,dFP,self) tail call 15775 15776 /* ------------------------------ */ 15777 .balign 64 15778 .L_ALT_OP_IGET_QUICK: /* 0xf2 */ 15779 /* File: armv5te/alt_stub.S */ 15780 /* 15781 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15782 * any interesting requests and then jump to the real instruction 15783 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15784 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15785 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15786 * bail to the real handler if breakFlags==0. 15787 */ 15788 ldrb r3, [rSELF, #offThread_breakFlags] 15789 adrl lr, dvmAsmInstructionStart + (242 * 64) 15790 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15791 cmp r3, #0 15792 bxeq lr @ nothing to do - jump to real handler 15793 EXPORT_PC() 15794 mov r0, rPC @ arg0 15795 mov r1, rFP @ arg1 15796 mov r2, rSELF @ arg2 15797 b dvmCheckBefore @ (dPC,dFP,self) tail call 15798 15799 /* ------------------------------ */ 15800 .balign 64 15801 .L_ALT_OP_IGET_WIDE_QUICK: /* 0xf3 */ 15802 /* File: armv5te/alt_stub.S */ 15803 /* 15804 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15805 * any interesting requests and then jump to the real instruction 15806 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15807 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15808 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15809 * bail to the real handler if breakFlags==0. 15810 */ 15811 ldrb r3, [rSELF, #offThread_breakFlags] 15812 adrl lr, dvmAsmInstructionStart + (243 * 64) 15813 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15814 cmp r3, #0 15815 bxeq lr @ nothing to do - jump to real handler 15816 EXPORT_PC() 15817 mov r0, rPC @ arg0 15818 mov r1, rFP @ arg1 15819 mov r2, rSELF @ arg2 15820 b dvmCheckBefore @ (dPC,dFP,self) tail call 15821 15822 /* ------------------------------ */ 15823 .balign 64 15824 .L_ALT_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 15825 /* File: armv5te/alt_stub.S */ 15826 /* 15827 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15828 * any interesting requests and then jump to the real instruction 15829 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15830 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15831 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15832 * bail to the real handler if breakFlags==0. 15833 */ 15834 ldrb r3, [rSELF, #offThread_breakFlags] 15835 adrl lr, dvmAsmInstructionStart + (244 * 64) 15836 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15837 cmp r3, #0 15838 bxeq lr @ nothing to do - jump to real handler 15839 EXPORT_PC() 15840 mov r0, rPC @ arg0 15841 mov r1, rFP @ arg1 15842 mov r2, rSELF @ arg2 15843 b dvmCheckBefore @ (dPC,dFP,self) tail call 15844 15845 /* ------------------------------ */ 15846 .balign 64 15847 .L_ALT_OP_IPUT_QUICK: /* 0xf5 */ 15848 /* File: armv5te/alt_stub.S */ 15849 /* 15850 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15851 * any interesting requests and then jump to the real instruction 15852 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15853 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15854 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15855 * bail to the real handler if breakFlags==0. 15856 */ 15857 ldrb r3, [rSELF, #offThread_breakFlags] 15858 adrl lr, dvmAsmInstructionStart + (245 * 64) 15859 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15860 cmp r3, #0 15861 bxeq lr @ nothing to do - jump to real handler 15862 EXPORT_PC() 15863 mov r0, rPC @ arg0 15864 mov r1, rFP @ arg1 15865 mov r2, rSELF @ arg2 15866 b dvmCheckBefore @ (dPC,dFP,self) tail call 15867 15868 /* ------------------------------ */ 15869 .balign 64 15870 .L_ALT_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 15871 /* File: armv5te/alt_stub.S */ 15872 /* 15873 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15874 * any interesting requests and then jump to the real instruction 15875 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15876 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15877 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15878 * bail to the real handler if breakFlags==0. 15879 */ 15880 ldrb r3, [rSELF, #offThread_breakFlags] 15881 adrl lr, dvmAsmInstructionStart + (246 * 64) 15882 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15883 cmp r3, #0 15884 bxeq lr @ nothing to do - jump to real handler 15885 EXPORT_PC() 15886 mov r0, rPC @ arg0 15887 mov r1, rFP @ arg1 15888 mov r2, rSELF @ arg2 15889 b dvmCheckBefore @ (dPC,dFP,self) tail call 15890 15891 /* ------------------------------ */ 15892 .balign 64 15893 .L_ALT_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 15894 /* File: armv5te/alt_stub.S */ 15895 /* 15896 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15897 * any interesting requests and then jump to the real instruction 15898 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15899 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15900 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15901 * bail to the real handler if breakFlags==0. 15902 */ 15903 ldrb r3, [rSELF, #offThread_breakFlags] 15904 adrl lr, dvmAsmInstructionStart + (247 * 64) 15905 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15906 cmp r3, #0 15907 bxeq lr @ nothing to do - jump to real handler 15908 EXPORT_PC() 15909 mov r0, rPC @ arg0 15910 mov r1, rFP @ arg1 15911 mov r2, rSELF @ arg2 15912 b dvmCheckBefore @ (dPC,dFP,self) tail call 15913 15914 /* ------------------------------ */ 15915 .balign 64 15916 .L_ALT_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 15917 /* File: armv5te/alt_stub.S */ 15918 /* 15919 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15920 * any interesting requests and then jump to the real instruction 15921 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15922 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15923 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15924 * bail to the real handler if breakFlags==0. 15925 */ 15926 ldrb r3, [rSELF, #offThread_breakFlags] 15927 adrl lr, dvmAsmInstructionStart + (248 * 64) 15928 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15929 cmp r3, #0 15930 bxeq lr @ nothing to do - jump to real handler 15931 EXPORT_PC() 15932 mov r0, rPC @ arg0 15933 mov r1, rFP @ arg1 15934 mov r2, rSELF @ arg2 15935 b dvmCheckBefore @ (dPC,dFP,self) tail call 15936 15937 /* ------------------------------ */ 15938 .balign 64 15939 .L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 15940 /* File: armv5te/alt_stub.S */ 15941 /* 15942 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15943 * any interesting requests and then jump to the real instruction 15944 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15945 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15946 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15947 * bail to the real handler if breakFlags==0. 15948 */ 15949 ldrb r3, [rSELF, #offThread_breakFlags] 15950 adrl lr, dvmAsmInstructionStart + (249 * 64) 15951 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15952 cmp r3, #0 15953 bxeq lr @ nothing to do - jump to real handler 15954 EXPORT_PC() 15955 mov r0, rPC @ arg0 15956 mov r1, rFP @ arg1 15957 mov r2, rSELF @ arg2 15958 b dvmCheckBefore @ (dPC,dFP,self) tail call 15959 15960 /* ------------------------------ */ 15961 .balign 64 15962 .L_ALT_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 15963 /* File: armv5te/alt_stub.S */ 15964 /* 15965 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15966 * any interesting requests and then jump to the real instruction 15967 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15968 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15969 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15970 * bail to the real handler if breakFlags==0. 15971 */ 15972 ldrb r3, [rSELF, #offThread_breakFlags] 15973 adrl lr, dvmAsmInstructionStart + (250 * 64) 15974 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15975 cmp r3, #0 15976 bxeq lr @ nothing to do - jump to real handler 15977 EXPORT_PC() 15978 mov r0, rPC @ arg0 15979 mov r1, rFP @ arg1 15980 mov r2, rSELF @ arg2 15981 b dvmCheckBefore @ (dPC,dFP,self) tail call 15982 15983 /* ------------------------------ */ 15984 .balign 64 15985 .L_ALT_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 15986 /* File: armv5te/alt_stub.S */ 15987 /* 15988 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15989 * any interesting requests and then jump to the real instruction 15990 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15991 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15992 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15993 * bail to the real handler if breakFlags==0. 15994 */ 15995 ldrb r3, [rSELF, #offThread_breakFlags] 15996 adrl lr, dvmAsmInstructionStart + (251 * 64) 15997 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15998 cmp r3, #0 15999 bxeq lr @ nothing to do - jump to real handler 16000 EXPORT_PC() 16001 mov r0, rPC @ arg0 16002 mov r1, rFP @ arg1 16003 mov r2, rSELF @ arg2 16004 b dvmCheckBefore @ (dPC,dFP,self) tail call 16005 16006 /* ------------------------------ */ 16007 .balign 64 16008 .L_ALT_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 16009 /* File: armv5te/alt_stub.S */ 16010 /* 16011 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 16012 * any interesting requests and then jump to the real instruction 16013 * handler. Note that the call to dvmCheckBefore is done as a tail call. 16014 * rIBASE updates won't be seen until a refresh, and we can tell we have a 16015 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 16016 * bail to the real handler if breakFlags==0. 16017 */ 16018 ldrb r3, [rSELF, #offThread_breakFlags] 16019 adrl lr, dvmAsmInstructionStart + (252 * 64) 16020 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16021 cmp r3, #0 16022 bxeq lr @ nothing to do - jump to real handler 16023 EXPORT_PC() 16024 mov r0, rPC @ arg0 16025 mov r1, rFP @ arg1 16026 mov r2, rSELF @ arg2 16027 b dvmCheckBefore @ (dPC,dFP,self) tail call 16028 16029 /* ------------------------------ */ 16030 .balign 64 16031 .L_ALT_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 16032 /* File: armv5te/alt_stub.S */ 16033 /* 16034 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 16035 * any interesting requests and then jump to the real instruction 16036 * handler. Note that the call to dvmCheckBefore is done as a tail call. 16037 * rIBASE updates won't be seen until a refresh, and we can tell we have a 16038 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 16039 * bail to the real handler if breakFlags==0. 16040 */ 16041 ldrb r3, [rSELF, #offThread_breakFlags] 16042 adrl lr, dvmAsmInstructionStart + (253 * 64) 16043 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16044 cmp r3, #0 16045 bxeq lr @ nothing to do - jump to real handler 16046 EXPORT_PC() 16047 mov r0, rPC @ arg0 16048 mov r1, rFP @ arg1 16049 mov r2, rSELF @ arg2 16050 b dvmCheckBefore @ (dPC,dFP,self) tail call 16051 16052 /* ------------------------------ */ 16053 .balign 64 16054 .L_ALT_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 16055 /* File: armv5te/alt_stub.S */ 16056 /* 16057 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 16058 * any interesting requests and then jump to the real instruction 16059 * handler. Note that the call to dvmCheckBefore is done as a tail call. 16060 * rIBASE updates won't be seen until a refresh, and we can tell we have a 16061 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 16062 * bail to the real handler if breakFlags==0. 16063 */ 16064 ldrb r3, [rSELF, #offThread_breakFlags] 16065 adrl lr, dvmAsmInstructionStart + (254 * 64) 16066 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16067 cmp r3, #0 16068 bxeq lr @ nothing to do - jump to real handler 16069 EXPORT_PC() 16070 mov r0, rPC @ arg0 16071 mov r1, rFP @ arg1 16072 mov r2, rSELF @ arg2 16073 b dvmCheckBefore @ (dPC,dFP,self) tail call 16074 16075 /* ------------------------------ */ 16076 .balign 64 16077 .L_ALT_OP_UNUSED_FF: /* 0xff */ 16078 /* File: armv5te/alt_stub.S */ 16079 /* 16080 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 16081 * any interesting requests and then jump to the real instruction 16082 * handler. Note that the call to dvmCheckBefore is done as a tail call. 16083 * rIBASE updates won't be seen until a refresh, and we can tell we have a 16084 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 16085 * bail to the real handler if breakFlags==0. 16086 */ 16087 ldrb r3, [rSELF, #offThread_breakFlags] 16088 adrl lr, dvmAsmInstructionStart + (255 * 64) 16089 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16090 cmp r3, #0 16091 bxeq lr @ nothing to do - jump to real handler 16092 EXPORT_PC() 16093 mov r0, rPC @ arg0 16094 mov r1, rFP @ arg1 16095 mov r2, rSELF @ arg2 16096 b dvmCheckBefore @ (dPC,dFP,self) tail call 16097 16098 .balign 64 16099 .size dvmAsmAltInstructionStart, .-dvmAsmAltInstructionStart 16100 .global dvmAsmAltInstructionEnd 16101 dvmAsmAltInstructionEnd: 16102 /* File: armv5te/footer.S */ 16103 /* 16104 * =========================================================================== 16105 * Common subroutines and data 16106 * =========================================================================== 16107 */ 16108 16109 .text 16110 .align 2 16111 16112 #if defined(WITH_JIT) 16113 16114 #if defined(WITH_SELF_VERIFICATION) 16115 /* 16116 * "longjmp" to a translation after single-stepping. Before returning 16117 * to translation, must save state for self-verification. 16118 */ 16119 .global dvmJitResumeTranslation @ (Thread* self, u4* dFP) 16120 dvmJitResumeTranslation: 16121 mov rSELF, r0 @ restore self 16122 mov rPC, r1 @ restore Dalvik pc 16123 mov rFP, r2 @ restore Dalvik fp 16124 ldr r10, [rSELF,#offThread_jitResumeNPC] @ resume address 16125 mov r2, #0 16126 str r2, [rSELF,#offThread_jitResumeNPC] @ reset resume address 16127 ldr sp, [rSELF,#offThread_jitResumeNSP] @ cut back native stack 16128 b jitSVShadowRunStart @ resume as if cache hit 16129 @ expects resume addr in r10 16130 16131 .global dvmJitToInterpPunt 16132 dvmJitToInterpPunt: 16133 mov r2,#kSVSPunt @ r2<- interpreter entry point 16134 mov r3, #0 16135 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 16136 b jitSVShadowRunEnd @ doesn't return 16137 16138 .global dvmJitToInterpSingleStep 16139 dvmJitToInterpSingleStep: 16140 mov rPC, r0 @ set up dalvik pc 16141 EXPORT_PC() 16142 str lr, [rSELF,#offThread_jitResumeNPC] 16143 str sp, [rSELF,#offThread_jitResumeNSP] 16144 str r1, [rSELF,#offThread_jitResumeDPC] 16145 mov r2,#kSVSSingleStep @ r2<- interpreter entry point 16146 b jitSVShadowRunEnd @ doesn't return 16147 16148 16149 .global dvmJitToInterpNoChainNoProfile 16150 dvmJitToInterpNoChainNoProfile: 16151 mov r0,rPC @ pass our target PC 16152 mov r2,#kSVSNoProfile @ r2<- interpreter entry point 16153 mov r3, #0 @ 0 means !inJitCodeCache 16154 str r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 16155 b jitSVShadowRunEnd @ doesn't return 16156 16157 .global dvmJitToInterpTraceSelectNoChain 16158 dvmJitToInterpTraceSelectNoChain: 16159 mov r0,rPC @ pass our target PC 16160 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 16161 mov r3, #0 @ 0 means !inJitCodeCache 16162 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 16163 b jitSVShadowRunEnd @ doesn't return 16164 16165 .global dvmJitToInterpTraceSelect 16166 dvmJitToInterpTraceSelect: 16167 ldr r0,[lr, #-1] @ pass our target PC 16168 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 16169 mov r3, #0 @ 0 means !inJitCodeCache 16170 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 16171 b jitSVShadowRunEnd @ doesn't return 16172 16173 .global dvmJitToInterpBackwardBranch 16174 dvmJitToInterpBackwardBranch: 16175 ldr r0,[lr, #-1] @ pass our target PC 16176 mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point 16177 mov r3, #0 @ 0 means !inJitCodeCache 16178 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 16179 b jitSVShadowRunEnd @ doesn't return 16180 16181 .global dvmJitToInterpNormal 16182 dvmJitToInterpNormal: 16183 ldr r0,[lr, #-1] @ pass our target PC 16184 mov r2,#kSVSNormal @ r2<- interpreter entry point 16185 mov r3, #0 @ 0 means !inJitCodeCache 16186 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 16187 b jitSVShadowRunEnd @ doesn't return 16188 16189 .global dvmJitToInterpNoChain 16190 dvmJitToInterpNoChain: 16191 mov r0,rPC @ pass our target PC 16192 mov r2,#kSVSNoChain @ r2<- interpreter entry point 16193 mov r3, #0 @ 0 means !inJitCodeCache 16194 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 16195 b jitSVShadowRunEnd @ doesn't return 16196 #else 16197 16198 /* 16199 * "longjmp" to a translation after single-stepping. 16200 */ 16201 .global dvmJitResumeTranslation @ (Thread* self, u4* dFP) 16202 dvmJitResumeTranslation: 16203 mov rSELF, r0 @ restore self 16204 mov rPC, r1 @ restore Dalvik pc 16205 mov rFP, r2 @ restore Dalvik fp 16206 ldr r0, [rSELF,#offThread_jitResumeNPC] 16207 mov r2, #0 16208 str r2, [rSELF,#offThread_jitResumeNPC] @ reset resume address 16209 ldr sp, [rSELF,#offThread_jitResumeNSP] @ cut back native stack 16210 bx r0 @ resume translation 16211 16212 /* 16213 * Return from the translation cache to the interpreter when the compiler is 16214 * having issues translating/executing a Dalvik instruction. We have to skip 16215 * the code cache lookup otherwise it is possible to indefinitely bouce 16216 * between the interpreter and the code cache if the instruction that fails 16217 * to be compiled happens to be at a trace start. 16218 */ 16219 .global dvmJitToInterpPunt 16220 dvmJitToInterpPunt: 16221 mov rPC, r0 16222 #if defined(WITH_JIT_TUNING) 16223 mov r0,lr 16224 bl dvmBumpPunt; 16225 #endif 16226 EXPORT_PC() 16227 mov r0, #0 16228 str r0, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 16229 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16230 FETCH_INST() 16231 GET_INST_OPCODE(ip) 16232 GOTO_OPCODE(ip) 16233 16234 /* 16235 * Return to the interpreter to handle a single instruction. 16236 * We'll use the normal single-stepping mechanism via interpBreak, 16237 * but also save the native pc of the resume point in the translation 16238 * and the native sp so that we can later do the equivalent of a 16239 * longjmp() to resume. 16240 * On entry: 16241 * dPC <= Dalvik PC of instrucion to interpret 16242 * lr <= resume point in translation 16243 * r1 <= Dalvik PC of next instruction 16244 */ 16245 .global dvmJitToInterpSingleStep 16246 dvmJitToInterpSingleStep: 16247 mov rPC, r0 @ set up dalvik pc 16248 EXPORT_PC() 16249 str lr, [rSELF,#offThread_jitResumeNPC] 16250 str sp, [rSELF,#offThread_jitResumeNSP] 16251 str r1, [rSELF,#offThread_jitResumeDPC] 16252 mov r1, #1 16253 str r1, [rSELF,#offThread_singleStepCount] @ just step once 16254 mov r0, rSELF 16255 mov r1, #kSubModeCountedStep 16256 bl dvmEnableSubMode @ (self, newMode) 16257 ldr rIBASE, [rSELF,#offThread_curHandlerTable] 16258 FETCH_INST() 16259 GET_INST_OPCODE(ip) 16260 GOTO_OPCODE(ip) 16261 16262 /* 16263 * Return from the translation cache and immediately request 16264 * a translation for the exit target. Commonly used for callees. 16265 */ 16266 .global dvmJitToInterpTraceSelectNoChain 16267 dvmJitToInterpTraceSelectNoChain: 16268 #if defined(WITH_JIT_TUNING) 16269 bl dvmBumpNoChain 16270 #endif 16271 mov r0,rPC 16272 mov r1,rSELF 16273 bl dvmJitGetTraceAddrThread @ (pc, self) 16274 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 16275 mov r1, rPC @ arg1 of translation may need this 16276 mov lr, #0 @ in case target is HANDLER_INTERPRET 16277 cmp r0,#0 @ !0 means translation exists 16278 bxne r0 @ continue native execution if so 16279 b 2f @ branch over to use the interpreter 16280 16281 /* 16282 * Return from the translation cache and immediately request 16283 * a translation for the exit target. Commonly used following 16284 * invokes. 16285 */ 16286 .global dvmJitToInterpTraceSelect 16287 dvmJitToInterpTraceSelect: 16288 ldr rPC,[lr, #-1] @ get our target PC 16289 add rINST,lr,#-5 @ save start of chain branch 16290 add rINST, #-4 @ .. which is 9 bytes back 16291 mov r0,rPC 16292 mov r1,rSELF 16293 bl dvmJitGetTraceAddrThread @ (pc, self) 16294 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 16295 cmp r0,#0 16296 beq 2f 16297 mov r1,rINST 16298 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 16299 mov r1, rPC @ arg1 of translation may need this 16300 mov lr, #0 @ in case target is HANDLER_INTERPRET 16301 cmp r0,#0 @ successful chain? 16302 bxne r0 @ continue native execution 16303 b toInterpreter @ didn't chain - resume with interpreter 16304 16305 /* No translation, so request one if profiling isn't disabled*/ 16306 2: 16307 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16308 ldr r0, [rSELF, #offThread_pJitProfTable] 16309 FETCH_INST() 16310 cmp r0, #0 16311 movne r2,#kJitTSelectRequestHot @ ask for trace selection 16312 bne common_selectTrace 16313 GET_INST_OPCODE(ip) 16314 GOTO_OPCODE(ip) 16315 16316 /* 16317 * Return from the translation cache to the interpreter. 16318 * The return was done with a BLX from thumb mode, and 16319 * the following 32-bit word contains the target rPC value. 16320 * Note that lr (r14) will have its low-order bit set to denote 16321 * its thumb-mode origin. 16322 * 16323 * We'll need to stash our lr origin away, recover the new 16324 * target and then check to see if there is a translation available 16325 * for our new target. If so, we do a translation chain and 16326 * go back to native execution. Otherwise, it's back to the 16327 * interpreter (after treating this entry as a potential 16328 * trace start). 16329 */ 16330 .global dvmJitToInterpNormal 16331 dvmJitToInterpNormal: 16332 ldr rPC,[lr, #-1] @ get our target PC 16333 add rINST,lr,#-5 @ save start of chain branch 16334 add rINST,#-4 @ .. which is 9 bytes back 16335 #if defined(WITH_JIT_TUNING) 16336 bl dvmBumpNormal 16337 #endif 16338 mov r0,rPC 16339 mov r1,rSELF 16340 bl dvmJitGetTraceAddrThread @ (pc, self) 16341 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 16342 cmp r0,#0 16343 beq toInterpreter @ go if not, otherwise do chain 16344 mov r1,rINST 16345 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 16346 mov r1, rPC @ arg1 of translation may need this 16347 mov lr, #0 @ in case target is HANDLER_INTERPRET 16348 cmp r0,#0 @ successful chain? 16349 bxne r0 @ continue native execution 16350 b toInterpreter @ didn't chain - resume with interpreter 16351 16352 /* 16353 * Return from the translation cache to the interpreter to do method invocation. 16354 * Check if translation exists for the callee, but don't chain to it. 16355 */ 16356 .global dvmJitToInterpNoChainNoProfile 16357 dvmJitToInterpNoChainNoProfile: 16358 #if defined(WITH_JIT_TUNING) 16359 bl dvmBumpNoChain 16360 #endif 16361 mov r0,rPC 16362 mov r1,rSELF 16363 bl dvmJitGetTraceAddrThread @ (pc, self) 16364 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 16365 mov r1, rPC @ arg1 of translation may need this 16366 mov lr, #0 @ in case target is HANDLER_INTERPRET 16367 cmp r0,#0 16368 bxne r0 @ continue native execution if so 16369 EXPORT_PC() 16370 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16371 FETCH_INST() 16372 GET_INST_OPCODE(ip) @ extract opcode from rINST 16373 GOTO_OPCODE(ip) @ jump to next instruction 16374 16375 /* 16376 * Return from the translation cache to the interpreter to do method invocation. 16377 * Check if translation exists for the callee, but don't chain to it. 16378 */ 16379 .global dvmJitToInterpNoChain 16380 dvmJitToInterpNoChain: 16381 #if defined(WITH_JIT_TUNING) 16382 bl dvmBumpNoChain 16383 #endif 16384 mov r0,rPC 16385 mov r1,rSELF 16386 bl dvmJitGetTraceAddrThread @ (pc, self) 16387 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 16388 mov r1, rPC @ arg1 of translation may need this 16389 mov lr, #0 @ in case target is HANDLER_INTERPRET 16390 cmp r0,#0 16391 bxne r0 @ continue native execution if so 16392 #endif 16393 16394 /* 16395 * No translation, restore interpreter regs and start interpreting. 16396 * rSELF & rFP were preserved in the translated code, and rPC has 16397 * already been restored by the time we get here. We'll need to set 16398 * up rIBASE & rINST, and load the address of the JitTable into r0. 16399 */ 16400 toInterpreter: 16401 EXPORT_PC() 16402 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16403 FETCH_INST() 16404 ldr r0, [rSELF, #offThread_pJitProfTable] 16405 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16406 @ NOTE: intended fallthrough 16407 16408 /* 16409 * Similar to common_updateProfile, but tests for null pJitProfTable 16410 * r0 holds pJifProfTAble, rINST is loaded, rPC is current and 16411 * rIBASE has been recently refreshed. 16412 */ 16413 common_testUpdateProfile: 16414 cmp r0, #0 @ JIT switched off? 16415 beq 4f @ return to interp if so 16416 16417 /* 16418 * Common code to update potential trace start counter, and initiate 16419 * a trace-build if appropriate. 16420 * On entry here: 16421 * r0 <= pJitProfTable (verified non-NULL) 16422 * rPC <= Dalvik PC 16423 * rINST <= next instruction 16424 */ 16425 common_updateProfile: 16426 eor r3,rPC,rPC,lsr #12 @ cheap, but fast hash function 16427 lsl r3,r3,#(32 - JIT_PROF_SIZE_LOG_2) @ shift out excess bits 16428 ldrb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter 16429 GET_INST_OPCODE(ip) 16430 subs r1,r1,#1 @ decrement counter 16431 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it 16432 GOTO_OPCODE_IFNE(ip) @ if not threshold, fallthrough otherwise */ 16433 16434 /* Looks good, reset the counter */ 16435 ldr r1, [rSELF, #offThread_jitThreshold] 16436 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter 16437 EXPORT_PC() 16438 mov r0,rPC 16439 mov r1,rSELF 16440 bl dvmJitGetTraceAddrThread @ (pc, self) 16441 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 16442 mov r1, rPC @ arg1 of translation may need this 16443 mov lr, #0 @ in case target is HANDLER_INTERPRET 16444 cmp r0,#0 16445 #if !defined(WITH_SELF_VERIFICATION) 16446 bxne r0 @ jump to the translation 16447 mov r2,#kJitTSelectRequest @ ask for trace selection 16448 @ fall-through to common_selectTrace 16449 #else 16450 moveq r2,#kJitTSelectRequest @ ask for trace selection 16451 beq common_selectTrace 16452 /* 16453 * At this point, we have a target translation. However, if 16454 * that translation is actually the interpret-only pseudo-translation 16455 * we want to treat it the same as no translation. 16456 */ 16457 mov r10, r0 @ save target 16458 bl dvmCompilerGetInterpretTemplate 16459 cmp r0, r10 @ special case? 16460 bne jitSVShadowRunStart @ set up self verification shadow space 16461 @ Need to clear the inJitCodeCache flag 16462 mov r3, #0 @ 0 means not in the JIT code cache 16463 str r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 16464 GET_INST_OPCODE(ip) 16465 GOTO_OPCODE(ip) 16466 /* no return */ 16467 #endif 16468 16469 /* 16470 * On entry: 16471 * r2 is jit state. 16472 */ 16473 common_selectTrace: 16474 ldrh r0,[rSELF,#offThread_subMode] 16475 ands r0, #(kSubModeJitTraceBuild | kSubModeJitSV) 16476 bne 3f @ already doing JIT work, continue 16477 str r2,[rSELF,#offThread_jitState] 16478 mov r0, rSELF 16479 /* 16480 * Call out to validate trace-building request. If successful, 16481 * rIBASE will be swapped to to send us into single-stepping trace 16482 * building mode, so we need to refresh before we continue. 16483 */ 16484 EXPORT_PC() 16485 SAVE_PC_FP_TO_SELF() @ copy of pc/fp to Thread 16486 bl dvmJitCheckTraceRequest 16487 3: 16488 FETCH_INST() 16489 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16490 4: 16491 GET_INST_OPCODE(ip) @ extract opcode from rINST 16492 GOTO_OPCODE(ip) 16493 /* no return */ 16494 #endif 16495 16496 #if defined(WITH_SELF_VERIFICATION) 16497 /* 16498 * Save PC and registers to shadow memory for self verification mode 16499 * before jumping to native translation. 16500 * On entry: 16501 * rPC, rFP, rSELF: the values that they should contain 16502 * r10: the address of the target translation. 16503 */ 16504 jitSVShadowRunStart: 16505 mov r0,rPC @ r0<- program counter 16506 mov r1,rFP @ r1<- frame pointer 16507 mov r2,rSELF @ r2<- self (Thread) pointer 16508 mov r3,r10 @ r3<- target translation 16509 bl dvmSelfVerificationSaveState @ save registers to shadow space 16510 ldr rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space 16511 bx r10 @ jump to the translation 16512 16513 /* 16514 * Restore PC, registers, and interpreter state to original values 16515 * before jumping back to the interpreter. 16516 * On entry: 16517 * r0: dPC 16518 * r2: self verification state 16519 */ 16520 jitSVShadowRunEnd: 16521 mov r1,rFP @ pass ending fp 16522 mov r3,rSELF @ pass self ptr for convenience 16523 bl dvmSelfVerificationRestoreState @ restore pc and fp values 16524 LOAD_PC_FP_FROM_SELF() @ restore pc, fp 16525 ldr r1,[r0,#offShadowSpace_svState] @ get self verification state 16526 cmp r1,#0 @ check for punt condition 16527 beq 1f 16528 @ Set up SV single-stepping 16529 mov r0, rSELF 16530 mov r1, #kSubModeJitSV 16531 bl dvmEnableSubMode @ (self, subMode) 16532 mov r2,#kJitSelfVerification @ ask for self verification 16533 str r2,[rSELF,#offThread_jitState] 16534 @ intentional fallthrough 16535 1: @ exit to interpreter without check 16536 EXPORT_PC() 16537 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16538 FETCH_INST() 16539 GET_INST_OPCODE(ip) 16540 GOTO_OPCODE(ip) 16541 #endif 16542 16543 /* 16544 * The equivalent of "goto bail", this calls through the "bail handler". 16545 * It will end this interpreter activation, and return to the caller 16546 * of dvmMterpStdRun. 16547 * 16548 * State registers will be saved to the "thread" area before bailing 16549 * debugging purposes 16550 */ 16551 common_gotoBail: 16552 SAVE_PC_FP_TO_SELF() @ export state to "thread" 16553 mov r0, rSELF @ r0<- self ptr 16554 b dvmMterpStdBail @ call(self, changeInterp) 16555 16556 /* 16557 * The JIT's invoke method needs to remember the callsite class and 16558 * target pair. Save them here so that they are available to 16559 * dvmCheckJit following the interpretation of this invoke. 16560 */ 16561 #if defined(WITH_JIT) 16562 save_callsiteinfo: 16563 cmp r9, #0 16564 ldrne r9, [r9, #offObject_clazz] 16565 str r0, [rSELF, #offThread_methodToCall] 16566 str r9, [rSELF, #offThread_callsiteClass] 16567 bx lr 16568 #endif 16569 16570 /* 16571 * Common code for method invocation with range. 16572 * 16573 * On entry: 16574 * r0 is "Method* methodToCall", r9 is "this" 16575 */ 16576 common_invokeMethodRange: 16577 .LinvokeNewRange: 16578 #if defined(WITH_JIT) 16579 ldrh r1, [rSELF, #offThread_subMode] 16580 ands r1, #kSubModeJitTraceBuild 16581 blne save_callsiteinfo 16582 #endif 16583 @ prepare to copy args to "outs" area of current frame 16584 movs r2, rINST, lsr #8 @ r2<- AA (arg count) -- test for zero 16585 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 16586 beq .LinvokeArgsDone @ if no args, skip the rest 16587 FETCH(r1, 2) @ r1<- CCCC 16588 16589 .LinvokeRangeArgs: 16590 @ r0=methodToCall, r1=CCCC, r2=count, r10=outs 16591 @ (very few methods have > 10 args; could unroll for common cases) 16592 add r3, rFP, r1, lsl #2 @ r3<- &fp[CCCC] 16593 sub r10, r10, r2, lsl #2 @ r10<- "outs" area, for call args 16594 1: ldr r1, [r3], #4 @ val = *fp++ 16595 subs r2, r2, #1 @ count-- 16596 str r1, [r10], #4 @ *outs++ = val 16597 bne 1b @ ...while count != 0 16598 b .LinvokeArgsDone 16599 16600 /* 16601 * Common code for method invocation without range. 16602 * 16603 * On entry: 16604 * r0 is "Method* methodToCall", r9 is "this" 16605 */ 16606 common_invokeMethodNoRange: 16607 .LinvokeNewNoRange: 16608 #if defined(WITH_JIT) 16609 ldrh r1, [rSELF, #offThread_subMode] 16610 ands r1, #kSubModeJitTraceBuild 16611 blne save_callsiteinfo 16612 #endif 16613 @ prepare to copy args to "outs" area of current frame 16614 movs r2, rINST, lsr #12 @ r2<- B (arg count) -- test for zero 16615 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 16616 FETCH(r1, 2) @ r1<- GFED (load here to hide latency) 16617 beq .LinvokeArgsDone 16618 16619 @ r0=methodToCall, r1=GFED, r2=count, r10=outs 16620 .LinvokeNonRange: 16621 rsb r2, r2, #5 @ r2<- 5-r2 16622 add pc, pc, r2, lsl #4 @ computed goto, 4 instrs each 16623 bl common_abort @ (skipped due to ARM prefetch) 16624 5: and ip, rINST, #0x0f00 @ isolate A 16625 ldr r2, [rFP, ip, lsr #6] @ r2<- vA (shift right 8, left 2) 16626 mov r0, r0 @ nop 16627 str r2, [r10, #-4]! @ *--outs = vA 16628 4: and ip, r1, #0xf000 @ isolate G 16629 ldr r2, [rFP, ip, lsr #10] @ r2<- vG (shift right 12, left 2) 16630 mov r0, r0 @ nop 16631 str r2, [r10, #-4]! @ *--outs = vG 16632 3: and ip, r1, #0x0f00 @ isolate F 16633 ldr r2, [rFP, ip, lsr #6] @ r2<- vF 16634 mov r0, r0 @ nop 16635 str r2, [r10, #-4]! @ *--outs = vF 16636 2: and ip, r1, #0x00f0 @ isolate E 16637 ldr r2, [rFP, ip, lsr #2] @ r2<- vE 16638 mov r0, r0 @ nop 16639 str r2, [r10, #-4]! @ *--outs = vE 16640 1: and ip, r1, #0x000f @ isolate D 16641 ldr r2, [rFP, ip, lsl #2] @ r2<- vD 16642 mov r0, r0 @ nop 16643 str r2, [r10, #-4]! @ *--outs = vD 16644 0: @ fall through to .LinvokeArgsDone 16645 16646 .LinvokeArgsDone: @ r0=methodToCall 16647 ldrh r9, [r0, #offMethod_registersSize] @ r9<- methodToCall->regsSize 16648 ldrh r3, [r0, #offMethod_outsSize] @ r3<- methodToCall->outsSize 16649 ldr r2, [r0, #offMethod_insns] @ r2<- method->insns 16650 ldr rINST, [r0, #offMethod_clazz] @ rINST<- method->clazz 16651 @ find space for the new stack frame, check for overflow 16652 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area 16653 sub r1, r1, r9, lsl #2 @ r1<- newFp (old savearea - regsSize) 16654 SAVEAREA_FROM_FP(r10, r1) @ r10<- newSaveArea 16655 @ bl common_dumpRegs 16656 ldr r9, [rSELF, #offThread_interpStackEnd] @ r9<- interpStackEnd 16657 sub r3, r10, r3, lsl #2 @ r3<- bottom (newsave - outsSize) 16658 cmp r3, r9 @ bottom < interpStackEnd? 16659 ldrh lr, [rSELF, #offThread_subMode] 16660 ldr r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags 16661 blo .LstackOverflow @ yes, this frame will overflow stack 16662 16663 @ set up newSaveArea 16664 #ifdef EASY_GDB 16665 SAVEAREA_FROM_FP(ip, rFP) @ ip<- stack save area 16666 str ip, [r10, #offStackSaveArea_prevSave] 16667 #endif 16668 str rFP, [r10, #offStackSaveArea_prevFrame] 16669 str rPC, [r10, #offStackSaveArea_savedPc] 16670 #if defined(WITH_JIT) 16671 mov r9, #0 16672 str r9, [r10, #offStackSaveArea_returnAddr] 16673 #endif 16674 str r0, [r10, #offStackSaveArea_method] 16675 16676 @ Profiling? 16677 cmp lr, #0 @ any special modes happening? 16678 bne 2f @ go if so 16679 1: 16680 tst r3, #ACC_NATIVE 16681 bne .LinvokeNative 16682 16683 /* 16684 stmfd sp!, {r0-r3} 16685 bl common_printNewline 16686 mov r0, rFP 16687 mov r1, #0 16688 bl dvmDumpFp 16689 ldmfd sp!, {r0-r3} 16690 stmfd sp!, {r0-r3} 16691 mov r0, r1 16692 mov r1, r10 16693 bl dvmDumpFp 16694 bl common_printNewline 16695 ldmfd sp!, {r0-r3} 16696 */ 16697 16698 ldrh r9, [r2] @ r9 <- load INST from new PC 16699 ldr r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex 16700 mov rPC, r2 @ publish new rPC 16701 16702 @ Update state values for the new method 16703 @ r0=methodToCall, r1=newFp, r3=newMethodClass, r9=newINST 16704 str r0, [rSELF, #offThread_method] @ self->method = methodToCall 16705 str r3, [rSELF, #offThread_methodClassDex] @ self->methodClassDex = ... 16706 mov r2, #1 16707 str r2, [rSELF, #offThread_debugIsMethodEntry] 16708 #if defined(WITH_JIT) 16709 ldr r0, [rSELF, #offThread_pJitProfTable] 16710 mov rFP, r1 @ fp = newFp 16711 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 16712 mov rINST, r9 @ publish new rINST 16713 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16714 cmp r0,#0 16715 bne common_updateProfile 16716 GOTO_OPCODE(ip) @ jump to next instruction 16717 #else 16718 mov rFP, r1 @ fp = newFp 16719 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 16720 mov rINST, r9 @ publish new rINST 16721 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16722 GOTO_OPCODE(ip) @ jump to next instruction 16723 #endif 16724 16725 2: 16726 @ Profiling - record method entry. r0: methodToCall 16727 stmfd sp!, {r0-r3} @ preserve r0-r3 16728 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16729 mov r1, r0 16730 mov r0, rSELF 16731 bl dvmReportInvoke @ (self, method) 16732 ldmfd sp!, {r0-r3} @ restore r0-r3 16733 b 1b 16734 16735 .LinvokeNative: 16736 @ Prep for the native call 16737 @ r0=methodToCall, r1=newFp, r10=newSaveArea 16738 ldrh lr, [rSELF, #offThread_subMode] 16739 ldr r9, [rSELF, #offThread_jniLocal_topCookie]@r9<-thread->localRef->... 16740 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16741 str r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top 16742 mov r2, r0 @ r2<- methodToCall 16743 mov r0, r1 @ r0<- newFp (points to args) 16744 add r1, rSELF, #offThread_retval @ r1<- &retval 16745 mov r3, rSELF @ arg3<- self 16746 16747 #ifdef ASSIST_DEBUGGER 16748 /* insert fake function header to help gdb find the stack frame */ 16749 b .Lskip 16750 .type dalvik_mterp, %function 16751 dalvik_mterp: 16752 .fnstart 16753 MTERP_ENTRY1 16754 MTERP_ENTRY2 16755 .Lskip: 16756 #endif 16757 16758 cmp lr, #0 @ any special SubModes active? 16759 bne 11f @ go handle them if so 16760 ldr ip, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 16761 blx ip 16762 7: 16763 16764 @ native return; r10=newSaveArea 16765 @ equivalent to dvmPopJniLocals 16766 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top 16767 ldr r1, [rSELF, #offThread_exception] @ check for exception 16768 str rFP, [rSELF, #offThread_curFrame] @ curFrame = fp 16769 cmp r1, #0 @ null? 16770 str r0, [rSELF, #offThread_jniLocal_topCookie] @ new top <- old top 16771 bne common_exceptionThrown @ no, handle exception 16772 16773 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 16774 GET_INST_OPCODE(ip) @ extract opcode from rINST 16775 GOTO_OPCODE(ip) @ jump to next instruction 16776 16777 11: 16778 @ r0=newFp, r1=&retval, r2=methodToCall, r3=self, lr=subModes 16779 stmfd sp!, {r0-r3} @ save all but subModes 16780 mov r0, r2 @ r0<- methodToCall 16781 mov r1, rSELF 16782 mov r2, rFP 16783 bl dvmReportPreNativeInvoke @ (methodToCall, self, fp) 16784 ldmfd sp, {r0-r3} @ refresh. NOTE: no sp autoincrement 16785 16786 @ Call the native method 16787 ldr ip, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 16788 blx ip 16789 16790 @ Restore the pre-call arguments 16791 ldmfd sp!, {r0-r3} @ r2<- methodToCall (others unneeded) 16792 16793 @ Finish up any post-invoke subMode requirements 16794 mov r0, r2 @ r0<- methodToCall 16795 mov r1, rSELF 16796 mov r2, rFP 16797 bl dvmReportPostNativeInvoke @ (methodToCall, self, fp) 16798 b 7b @ resume 16799 16800 .LstackOverflow: @ r0=methodToCall 16801 mov r1, r0 @ r1<- methodToCall 16802 mov r0, rSELF @ r0<- self 16803 bl dvmHandleStackOverflow 16804 b common_exceptionThrown 16805 #ifdef ASSIST_DEBUGGER 16806 .fnend 16807 .size dalvik_mterp, .-dalvik_mterp 16808 #endif 16809 16810 16811 /* 16812 * Common code for method invocation, calling through "glue code". 16813 * 16814 * TODO: now that we have range and non-range invoke handlers, this 16815 * needs to be split into two. Maybe just create entry points 16816 * that set r9 and jump here? 16817 * 16818 * On entry: 16819 * r0 is "Method* methodToCall", the method we're trying to call 16820 * r9 is "bool methodCallRange", indicating if this is a /range variant 16821 */ 16822 .if 0 16823 .LinvokeOld: 16824 sub sp, sp, #8 @ space for args + pad 16825 FETCH(ip, 2) @ ip<- FEDC or CCCC 16826 mov r2, r0 @ A2<- methodToCall 16827 mov r0, rSELF @ A0<- self 16828 SAVE_PC_FP_TO_SELF() @ export state to "self" 16829 mov r1, r9 @ A1<- methodCallRange 16830 mov r3, rINST, lsr #8 @ A3<- AA 16831 str ip, [sp, #0] @ A4<- ip 16832 bl dvmMterp_invokeMethod @ call the C invokeMethod 16833 add sp, sp, #8 @ remove arg area 16834 b common_resumeAfterGlueCall @ continue to next instruction 16835 .endif 16836 16837 16838 16839 /* 16840 * Common code for handling a return instruction. 16841 * 16842 * This does not return. 16843 */ 16844 common_returnFromMethod: 16845 .LreturnNew: 16846 ldrh lr, [rSELF, #offThread_subMode] 16847 SAVEAREA_FROM_FP(r0, rFP) 16848 ldr r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc 16849 cmp lr, #0 @ any special subMode handling needed? 16850 bne 19f 16851 14: 16852 ldr rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame 16853 ldr r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)] 16854 @ r2<- method we're returning to 16855 cmp r2, #0 @ is this a break frame? 16856 #if defined(WORKAROUND_CORTEX_A9_745320) 16857 /* Don't use conditional loads if the HW defect exists */ 16858 beq 15f 16859 ldr r10, [r2, #offMethod_clazz] @ r10<- method->clazz 16860 15: 16861 #else 16862 ldrne r10, [r2, #offMethod_clazz] @ r10<- method->clazz 16863 #endif 16864 beq common_gotoBail @ break frame, bail out completely 16865 16866 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 16867 PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST 16868 str r2, [rSELF, #offThread_method]@ self->method = newSave->method 16869 ldr r1, [r10, #offClassObject_pDvmDex] @ r1<- method->clazz->pDvmDex 16870 str rFP, [rSELF, #offThread_curFrame] @ curFrame = fp 16871 #if defined(WITH_JIT) 16872 ldr r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr 16873 mov rPC, r9 @ publish new rPC 16874 str r1, [rSELF, #offThread_methodClassDex] 16875 str r10, [rSELF, #offThread_inJitCodeCache] @ may return to JIT'ed land 16876 cmp r10, #0 @ caller is compiled code 16877 blxne r10 16878 GET_INST_OPCODE(ip) @ extract opcode from rINST 16879 GOTO_OPCODE(ip) @ jump to next instruction 16880 #else 16881 GET_INST_OPCODE(ip) @ extract opcode from rINST 16882 mov rPC, r9 @ publish new rPC 16883 str r1, [rSELF, #offThread_methodClassDex] 16884 GOTO_OPCODE(ip) @ jump to next instruction 16885 #endif 16886 16887 19: 16888 @ Handle special actions 16889 @ On entry, r0: StackSaveArea 16890 ldr r1, [r0, #offStackSaveArea_prevFrame] @ r2<- prevFP 16891 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16892 str r1, [rSELF, #offThread_curFrame] @ update interpSave.curFrame 16893 mov r0, rSELF 16894 bl dvmReportReturn @ (self) 16895 SAVEAREA_FROM_FP(r0, rFP) @ restore StackSaveArea 16896 b 14b @ continue 16897 16898 /* 16899 * Return handling, calls through "glue code". 16900 */ 16901 .if 0 16902 .LreturnOld: 16903 SAVE_PC_FP_TO_SELF() @ export state 16904 mov r0, rSELF @ arg to function 16905 bl dvmMterp_returnFromMethod 16906 b common_resumeAfterGlueCall 16907 .endif 16908 16909 16910 /* 16911 * Somebody has thrown an exception. Handle it. 16912 * 16913 * If the exception processing code returns to us (instead of falling 16914 * out of the interpreter), continue with whatever the next instruction 16915 * now happens to be. 16916 * 16917 * This does not return. 16918 */ 16919 .global dvmMterpCommonExceptionThrown 16920 dvmMterpCommonExceptionThrown: 16921 common_exceptionThrown: 16922 .LexceptionNew: 16923 16924 EXPORT_PC() 16925 16926 mov r0, rSELF 16927 bl dvmCheckSuspendPending 16928 16929 ldr r9, [rSELF, #offThread_exception] @ r9<- self->exception 16930 mov r1, rSELF @ r1<- self 16931 mov r0, r9 @ r0<- exception 16932 bl dvmAddTrackedAlloc @ don't let the exception be GCed 16933 ldrh r2, [rSELF, #offThread_subMode] @ get subMode flags 16934 mov r3, #0 @ r3<- NULL 16935 str r3, [rSELF, #offThread_exception] @ self->exception = NULL 16936 16937 @ Special subMode? 16938 cmp r2, #0 @ any special subMode handling needed? 16939 bne 7f @ go if so 16940 8: 16941 /* set up args and a local for "&fp" */ 16942 /* (str sp, [sp, #-4]! would be perfect here, but is discouraged) */ 16943 str rFP, [sp, #-4]! @ *--sp = fp 16944 mov ip, sp @ ip<- &fp 16945 mov r3, #0 @ r3<- false 16946 str ip, [sp, #-4]! @ *--sp = &fp 16947 ldr r1, [rSELF, #offThread_method] @ r1<- self->method 16948 mov r0, rSELF @ r0<- self 16949 ldr r1, [r1, #offMethod_insns] @ r1<- method->insns 16950 mov r2, r9 @ r2<- exception 16951 sub r1, rPC, r1 @ r1<- pc - method->insns 16952 mov r1, r1, asr #1 @ r1<- offset in code units 16953 16954 /* call, r0 gets catchRelPc (a code-unit offset) */ 16955 bl dvmFindCatchBlock @ call(self, relPc, exc, scan?, &fp) 16956 16957 /* fix earlier stack overflow if necessary; may trash rFP */ 16958 ldrb r1, [rSELF, #offThread_stackOverflowed] 16959 cmp r1, #0 @ did we overflow earlier? 16960 beq 1f @ no, skip ahead 16961 mov rFP, r0 @ save relPc result in rFP 16962 mov r0, rSELF @ r0<- self 16963 mov r1, r9 @ r1<- exception 16964 bl dvmCleanupStackOverflow @ call(self) 16965 mov r0, rFP @ restore result 16966 1: 16967 16968 /* update frame pointer and check result from dvmFindCatchBlock */ 16969 ldr rFP, [sp, #4] @ retrieve the updated rFP 16970 cmp r0, #0 @ is catchRelPc < 0? 16971 add sp, sp, #8 @ restore stack 16972 bmi .LnotCaughtLocally 16973 16974 /* adjust locals to match self->interpSave.curFrame and updated PC */ 16975 SAVEAREA_FROM_FP(r1, rFP) @ r1<- new save area 16976 ldr r1, [r1, #offStackSaveArea_method] @ r1<- new method 16977 str r1, [rSELF, #offThread_method] @ self->method = new method 16978 ldr r2, [r1, #offMethod_clazz] @ r2<- method->clazz 16979 ldr r3, [r1, #offMethod_insns] @ r3<- method->insns 16980 ldr r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex 16981 add rPC, r3, r0, asl #1 @ rPC<- method->insns + catchRelPc 16982 str r2, [rSELF, #offThread_methodClassDex] @ self->pDvmDex = meth... 16983 16984 /* release the tracked alloc on the exception */ 16985 mov r0, r9 @ r0<- exception 16986 mov r1, rSELF @ r1<- self 16987 bl dvmReleaseTrackedAlloc @ release the exception 16988 16989 /* restore the exception if the handler wants it */ 16990 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 16991 FETCH_INST() @ load rINST from rPC 16992 GET_INST_OPCODE(ip) @ extract opcode from rINST 16993 cmp ip, #OP_MOVE_EXCEPTION @ is it "move-exception"? 16994 streq r9, [rSELF, #offThread_exception] @ yes, restore the exception 16995 GOTO_OPCODE(ip) @ jump to next instruction 16996 16997 @ Manage debugger bookkeeping 16998 7: 16999 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 17000 str rFP, [rSELF, #offThread_curFrame] @ update interpSave.curFrame 17001 mov r0, rSELF @ arg0<- self 17002 mov r1, r9 @ arg1<- exception 17003 bl dvmReportExceptionThrow @ (self, exception) 17004 b 8b @ resume with normal handling 17005 17006 .LnotCaughtLocally: @ r9=exception 17007 /* fix stack overflow if necessary */ 17008 ldrb r1, [rSELF, #offThread_stackOverflowed] 17009 cmp r1, #0 @ did we overflow earlier? 17010 movne r0, rSELF @ if yes: r0<- self 17011 movne r1, r9 @ if yes: r1<- exception 17012 blne dvmCleanupStackOverflow @ if yes: call(self) 17013 17014 @ may want to show "not caught locally" debug messages here 17015 #if DVM_SHOW_EXCEPTION >= 2 17016 /* call __android_log_print(prio, tag, format, ...) */ 17017 /* "Exception %s from %s:%d not caught locally" */ 17018 @ dvmLineNumFromPC(method, pc - method->insns) 17019 ldr r0, [rSELF, #offThread_method] 17020 ldr r1, [r0, #offMethod_insns] 17021 sub r1, rPC, r1 17022 asr r1, r1, #1 17023 bl dvmLineNumFromPC 17024 str r0, [sp, #-4]! 17025 @ dvmGetMethodSourceFile(method) 17026 ldr r0, [rSELF, #offThread_method] 17027 bl dvmGetMethodSourceFile 17028 str r0, [sp, #-4]! 17029 @ exception->clazz->descriptor 17030 ldr r3, [r9, #offObject_clazz] 17031 ldr r3, [r3, #offClassObject_descriptor] 17032 @ 17033 ldr r2, strExceptionNotCaughtLocally 17034 0: add r2, pc 17035 ldr r1, strLogTag 17036 1: add r1, pc 17037 mov r0, #3 @ LOG_DEBUG 17038 bl __android_log_print 17039 #endif 17040 str r9, [rSELF, #offThread_exception] @ restore exception 17041 mov r0, r9 @ r0<- exception 17042 mov r1, rSELF @ r1<- self 17043 bl dvmReleaseTrackedAlloc @ release the exception 17044 b common_gotoBail @ bail out 17045 17046 strExceptionNotCaughtLocally: 17047 .word PCREL_REF(.LstrExceptionNotCaughtLocally,0b) 17048 strLogTag: 17049 .word PCREL_REF(.LstrLogTag,1b) 17050 17051 /* 17052 * Exception handling, calls through "glue code". 17053 */ 17054 .if 0 17055 .LexceptionOld: 17056 SAVE_PC_FP_TO_SELF() @ export state 17057 mov r0, rSELF @ arg to function 17058 bl dvmMterp_exceptionThrown 17059 b common_resumeAfterGlueCall 17060 .endif 17061 17062 #if defined(WITH_JIT) 17063 /* 17064 * If the JIT is actively building a trace we need to make sure 17065 * that the field is fully resolved before including the current 17066 * instruction. 17067 * 17068 * On entry: 17069 * r10: &dvmDex->pResFields[field] 17070 * r0: field pointer (must preserve) 17071 */ 17072 common_verifyField: 17073 ldrh r3, [rSELF, #offThread_subMode] @ r3 <- submode byte 17074 ands r3, #kSubModeJitTraceBuild 17075 bxeq lr @ Not building trace, continue 17076 ldr r1, [r10] @ r1<- reload resolved StaticField ptr 17077 cmp r1, #0 @ resolution complete? 17078 bxne lr @ yes, continue 17079 stmfd sp!, {r0-r2,lr} @ save regs 17080 mov r0, rSELF 17081 mov r1, rPC 17082 bl dvmJitEndTraceSelect @ (self,pc) end trace before this inst 17083 ldmfd sp!, {r0-r2, lr} 17084 bx lr @ return 17085 #endif 17086 17087 /* 17088 * After returning from a "glued" function, pull out the updated 17089 * values and start executing at the next instruction. 17090 */ 17091 common_resumeAfterGlueCall: 17092 LOAD_PC_FP_FROM_SELF() @ pull rPC and rFP out of thread 17093 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh 17094 FETCH_INST() @ load rINST from rPC 17095 GET_INST_OPCODE(ip) @ extract opcode from rINST 17096 GOTO_OPCODE(ip) @ jump to next instruction 17097 17098 /* 17099 * Invalid array index. Note that our calling convention is strange; we use r1 17100 * and r3 because those just happen to be the registers all our callers are 17101 * using. We move r3 before calling the C function, but r1 happens to match. 17102 * r1: index 17103 * r3: size 17104 */ 17105 common_errArrayIndex: 17106 EXPORT_PC() 17107 mov r0, r3 17108 bl dvmThrowArrayIndexOutOfBoundsException 17109 b common_exceptionThrown 17110 17111 /* 17112 * Integer divide or mod by zero. 17113 */ 17114 common_errDivideByZero: 17115 EXPORT_PC() 17116 ldr r0, strDivideByZero 17117 0: add r0, pc 17118 bl dvmThrowArithmeticException 17119 b common_exceptionThrown 17120 17121 strDivideByZero: 17122 .word PCREL_REF(.LstrDivideByZero,0b) 17123 17124 /* 17125 * Attempt to allocate an array with a negative size. 17126 * On entry: length in r1 17127 */ 17128 common_errNegativeArraySize: 17129 EXPORT_PC() 17130 mov r0, r1 @ arg0 <- len 17131 bl dvmThrowNegativeArraySizeException @ (len) 17132 b common_exceptionThrown 17133 17134 /* 17135 * Invocation of a non-existent method. 17136 * On entry: method name in r1 17137 */ 17138 common_errNoSuchMethod: 17139 EXPORT_PC() 17140 mov r0, r1 17141 bl dvmThrowNoSuchMethodError 17142 b common_exceptionThrown 17143 17144 /* 17145 * We encountered a null object when we weren't expecting one. We 17146 * export the PC, throw a NullPointerException, and goto the exception 17147 * processing code. 17148 */ 17149 common_errNullObject: 17150 EXPORT_PC() 17151 mov r0, #0 17152 bl dvmThrowNullPointerException 17153 b common_exceptionThrown 17154 17155 /* 17156 * For debugging, cause an immediate fault. The source address will 17157 * be in lr (use a bl instruction to jump here). 17158 */ 17159 common_abort: 17160 ldr pc, .LdeadFood 17161 .LdeadFood: 17162 .word 0xdeadf00d 17163 17164 /* 17165 * Spit out a "we were here", preserving all registers. (The attempt 17166 * to save ip won't work, but we need to save an even number of 17167 * registers for EABI 64-bit stack alignment.) 17168 */ 17169 .macro SQUEAK num 17170 common_squeak\num: 17171 stmfd sp!, {r0, r1, r2, r3, ip, lr} 17172 ldr r0, strSqueak\num 17173 0: add r0, pc 17174 mov r1, #\num 17175 bl printf 17176 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 17177 bx lr 17178 17179 strSqueak\num: 17180 .word PCREL_REF(.LstrSqueak,0b) 17181 .endm 17182 17183 SQUEAK 0 17184 SQUEAK 1 17185 SQUEAK 2 17186 SQUEAK 3 17187 SQUEAK 4 17188 SQUEAK 5 17189 17190 /* 17191 * Spit out the number in r0, preserving registers. 17192 */ 17193 common_printNum: 17194 stmfd sp!, {r0, r1, r2, r3, ip, lr} 17195 mov r1, r0 17196 ldr r0, strSqueak 17197 0: add r0, pc 17198 bl printf 17199 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 17200 bx lr 17201 17202 strSqueak: 17203 .word PCREL_REF(.LstrSqueak,0b) 17204 17205 /* 17206 * Print a newline, preserving registers. 17207 */ 17208 common_printNewline: 17209 stmfd sp!, {r0, r1, r2, r3, ip, lr} 17210 ldr r0, strNewline 17211 0: add r0, pc 17212 bl printf 17213 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 17214 bx lr 17215 17216 strNewline: 17217 .word PCREL_REF(.LstrNewline,0b) 17218 17219 /* 17220 * Print the 32-bit quantity in r0 as a hex value, preserving registers. 17221 */ 17222 common_printHex: 17223 stmfd sp!, {r0, r1, r2, r3, ip, lr} 17224 mov r1, r0 17225 ldr r0, strPrintHex 17226 0: add r0, pc 17227 bl printf 17228 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 17229 bx lr 17230 17231 strPrintHex: 17232 .word PCREL_REF(.LstrPrintHex,0b) 17233 17234 /* 17235 * Print the 64-bit quantity in r0-r1, preserving registers. 17236 */ 17237 common_printLong: 17238 stmfd sp!, {r0, r1, r2, r3, ip, lr} 17239 mov r3, r1 17240 mov r2, r0 17241 ldr r0, strPrintLong 17242 0: add r0, pc 17243 bl printf 17244 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 17245 bx lr 17246 17247 strPrintLong: 17248 .word PCREL_REF(.LstrPrintLong,0b) 17249 17250 /* 17251 * Print full method info. Pass the Method* in r0. Preserves regs. 17252 */ 17253 common_printMethod: 17254 stmfd sp!, {r0, r1, r2, r3, ip, lr} 17255 bl dvmMterpPrintMethod 17256 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 17257 bx lr 17258 17259 /* 17260 * Call a C helper function that dumps regs and possibly some 17261 * additional info. Requires the C function to be compiled in. 17262 */ 17263 .if 0 17264 common_dumpRegs: 17265 stmfd sp!, {r0, r1, r2, r3, ip, lr} 17266 bl dvmMterpDumpArmRegs 17267 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 17268 bx lr 17269 .endif 17270 17271 #if 0 17272 /* 17273 * Experiment on VFP mode. 17274 * 17275 * uint32_t setFPSCR(uint32_t val, uint32_t mask) 17276 * 17277 * Updates the bits specified by "mask", setting them to the values in "val". 17278 */ 17279 setFPSCR: 17280 and r0, r0, r1 @ make sure no stray bits are set 17281 fmrx r2, fpscr @ get VFP reg 17282 mvn r1, r1 @ bit-invert mask 17283 and r2, r2, r1 @ clear masked bits 17284 orr r2, r2, r0 @ set specified bits 17285 fmxr fpscr, r2 @ set VFP reg 17286 mov r0, r2 @ return new value 17287 bx lr 17288 17289 .align 2 17290 .global dvmConfigureFP 17291 .type dvmConfigureFP, %function 17292 dvmConfigureFP: 17293 stmfd sp!, {ip, lr} 17294 /* 0x03000000 sets DN/FZ */ 17295 /* 0x00009f00 clears the six exception enable flags */ 17296 bl common_squeak0 17297 mov r0, #0x03000000 @ r0<- 0x03000000 17298 add r1, r0, #0x9f00 @ r1<- 0x03009f00 17299 bl setFPSCR 17300 ldmfd sp!, {ip, pc} 17301 #endif 17302 17303 17304 17305 /* 17306 * Zero-terminated ASCII string data. 17307 * 17308 * On ARM we have two choices: do like gcc does, and LDR from a .word 17309 * with the address, or use an ADR pseudo-op to get the address 17310 * directly. ADR saves 4 bytes and an indirection, but it's using a 17311 * PC-relative addressing mode and hence has a limited range, which 17312 * makes it not work well with mergeable string sections. 17313 */ 17314 .section .rodata.str1.4,"aMS",%progbits,1 17315 17316 .LstrBadEntryPoint: 17317 .asciz "Bad entry point %d\n" 17318 .LstrFilledNewArrayNotImpl: 17319 .asciz "filled-new-array only implemented for objects and 'int'" 17320 .LstrDivideByZero: 17321 .asciz "divide by zero" 17322 .LstrLogTag: 17323 .asciz "mterp" 17324 .LstrExceptionNotCaughtLocally: 17325 .asciz "Exception %s from %s:%d not caught locally\n" 17326 17327 .LstrNewline: 17328 .asciz "\n" 17329 .LstrSqueak: 17330 .asciz "<%d>" 17331 .LstrPrintHex: 17332 .asciz "<%#x>" 17333 .LstrPrintLong: 17334 .asciz "<%lld>" 17335 17336