1/* 2 * This file was generated automatically by gen-mterp.py for 'armv5te-vfp'. 3 * 4 * --> DO NOT EDIT <-- 5 */ 6 7/* File: armv5te/header.S */ 8/* 9 * Copyright (C) 2008 The Android Open Source Project 10 * 11 * Licensed under the Apache License, Version 2.0 (the "License"); 12 * you may not use this file except in compliance with the License. 13 * You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, software 18 * distributed under the License is distributed on an "AS IS" BASIS, 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 * See the License for the specific language governing permissions and 21 * limitations under the License. 22 */ 23 24/* 25 * ARMv5 definitions and declarations. 26 */ 27 28/* 29ARM EABI general notes: 30 31r0-r3 hold first 4 args to a method; they are not preserved across method calls 32r4-r8 are available for general use 33r9 is given special treatment in some situations, but not for us 34r10 (sl) seems to be generally available 35r11 (fp) is used by gcc (unless -fomit-frame-pointer is set) 36r12 (ip) is scratch -- not preserved across method calls 37r13 (sp) should be managed carefully in case a signal arrives 38r14 (lr) must be preserved 39r15 (pc) can be tinkered with directly 40 41r0 holds returns of <= 4 bytes 42r0-r1 hold returns of 8 bytes, low word in r0 43 44Callee must save/restore r4+ (except r12) if it modifies them. If VFP 45is present, registers s16-s31 (a/k/a d8-d15, a/k/a q4-q7) must be preserved, 46s0-s15 (d0-d7, q0-a3) do not need to be. 47 48Stack is "full descending". Only the arguments that don't fit in the first 4 49registers are placed on the stack. "sp" points at the first stacked argument 50(i.e. the 5th arg). 51 52VFP: single-precision results in s0, double-precision results in d0. 53 54In the EABI, "sp" must be 64-bit aligned on entry to a function, and any 5564-bit quantities (long long, double) must be 64-bit aligned. 56*/ 57 58/* 59Mterp and ARM notes: 60 61The 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 70Macros are provided for common operations. Each macro MUST emit only 71one instruction to make instruction-counting easier. They MUST NOT alter 72unspecified 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 */ 269dvmMterpStdRun: 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 3101: 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 3220: add r0, pc 323 @ r1 holds value of entryPoint 324 bl printf 325 bl dvmAbort 326 .fnend 327 .size dvmMterpStdRun, .-dvmMterpStdRun 328 329strBadEntryPoint: 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 */ 347dvmMterpStdBail: 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 356dvmAsmInstructionStart = .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 370dalvik_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 8421: 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 9928: 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 10208: 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: arm-vfp/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 * int compare(x, y) { 1231 * if (x == y) { 1232 * return 0; 1233 * } else if (x > y) { 1234 * return 1; 1235 * } else if (x < y) { 1236 * return -1; 1237 * } else { 1238 * return -1; 1239 * } 1240 * } 1241 */ 1242 /* op vAA, vBB, vCC */ 1243 FETCH(r0, 1) @ r0<- CCBB 1244 mov r9, rINST, lsr #8 @ r9<- AA 1245 and r2, r0, #255 @ r2<- BB 1246 mov r3, r0, lsr #8 @ r3<- CC 1247 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1248 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1249 flds s0, [r2] @ s0<- vBB 1250 flds s1, [r3] @ s1<- vCC 1251 fcmpes s0, s1 @ compare (vBB, vCC) 1252 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1253 mvn r0, #0 @ r0<- -1 (default) 1254 GET_INST_OPCODE(ip) @ extract opcode from rINST 1255 fmstat @ export status flags 1256 movgt r0, #1 @ (greater than) r1<- 1 1257 moveq r0, #0 @ (equal) r1<- 0 1258 b .LOP_CMPL_FLOAT_finish @ argh 1259 1260 1261/* ------------------------------ */ 1262 .balign 64 1263.L_OP_CMPG_FLOAT: /* 0x2e */ 1264/* File: arm-vfp/OP_CMPG_FLOAT.S */ 1265 /* 1266 * Compare two floating-point values. Puts 0, 1, or -1 into the 1267 * destination register based on the results of the comparison. 1268 * 1269 * int compare(x, y) { 1270 * if (x == y) { 1271 * return 0; 1272 * } else if (x < y) { 1273 * return -1; 1274 * } else if (x > y) { 1275 * return 1; 1276 * } else { 1277 * return 1; 1278 * } 1279 * } 1280 */ 1281 /* op vAA, vBB, vCC */ 1282 FETCH(r0, 1) @ r0<- CCBB 1283 mov r9, rINST, lsr #8 @ r9<- AA 1284 and r2, r0, #255 @ r2<- BB 1285 mov r3, r0, lsr #8 @ r3<- CC 1286 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1287 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1288 flds s0, [r2] @ s0<- vBB 1289 flds s1, [r3] @ s1<- vCC 1290 fcmpes s0, s1 @ compare (vBB, vCC) 1291 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1292 mov r0, #1 @ r0<- 1 (default) 1293 GET_INST_OPCODE(ip) @ extract opcode from rINST 1294 fmstat @ export status flags 1295 mvnmi r0, #0 @ (less than) r1<- -1 1296 moveq r0, #0 @ (equal) r1<- 0 1297 b .LOP_CMPG_FLOAT_finish @ argh 1298 1299 1300/* ------------------------------ */ 1301 .balign 64 1302.L_OP_CMPL_DOUBLE: /* 0x2f */ 1303/* File: arm-vfp/OP_CMPL_DOUBLE.S */ 1304 /* 1305 * Compare two floating-point values. Puts 0, 1, or -1 into the 1306 * destination register based on the results of the comparison. 1307 * 1308 * int compare(x, y) { 1309 * if (x == y) { 1310 * return 0; 1311 * } else if (x > y) { 1312 * return 1; 1313 * } else if (x < y) { 1314 * return -1; 1315 * } else { 1316 * return -1; 1317 * } 1318 * } 1319 */ 1320 /* op vAA, vBB, vCC */ 1321 FETCH(r0, 1) @ r0<- CCBB 1322 mov r9, rINST, lsr #8 @ r9<- AA 1323 and r2, r0, #255 @ r2<- BB 1324 mov r3, r0, lsr #8 @ r3<- CC 1325 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1326 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1327 fldd d0, [r2] @ d0<- vBB 1328 fldd d1, [r3] @ d1<- vCC 1329 fcmped d0, d1 @ compare (vBB, vCC) 1330 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1331 mvn r0, #0 @ r0<- -1 (default) 1332 GET_INST_OPCODE(ip) @ extract opcode from rINST 1333 fmstat @ export status flags 1334 movgt r0, #1 @ (greater than) r1<- 1 1335 moveq r0, #0 @ (equal) r1<- 0 1336 b .LOP_CMPL_DOUBLE_finish @ argh 1337 1338 1339/* ------------------------------ */ 1340 .balign 64 1341.L_OP_CMPG_DOUBLE: /* 0x30 */ 1342/* File: arm-vfp/OP_CMPG_DOUBLE.S */ 1343 /* 1344 * Compare two floating-point values. Puts 0, 1, or -1 into the 1345 * destination register based on the results of the comparison. 1346 * 1347 * int compare(x, y) { 1348 * if (x == y) { 1349 * return 0; 1350 * } else if (x < y) { 1351 * return -1; 1352 * } else if (x > y) { 1353 * return 1; 1354 * } else { 1355 * return 1; 1356 * } 1357 * } 1358 */ 1359 /* op vAA, vBB, vCC */ 1360 FETCH(r0, 1) @ r0<- CCBB 1361 mov r9, rINST, lsr #8 @ r9<- AA 1362 and r2, r0, #255 @ r2<- BB 1363 mov r3, r0, lsr #8 @ r3<- CC 1364 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1365 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1366 fldd d0, [r2] @ d0<- vBB 1367 fldd d1, [r3] @ d1<- vCC 1368 fcmped d0, d1 @ compare (vBB, vCC) 1369 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1370 mov r0, #1 @ r0<- 1 (default) 1371 GET_INST_OPCODE(ip) @ extract opcode from rINST 1372 fmstat @ export status flags 1373 mvnmi r0, #0 @ (less than) r1<- -1 1374 moveq r0, #0 @ (equal) r1<- 0 1375 b .LOP_CMPG_DOUBLE_finish @ argh 1376 1377 1378/* ------------------------------ */ 1379 .balign 64 1380.L_OP_CMP_LONG: /* 0x31 */ 1381/* File: armv5te/OP_CMP_LONG.S */ 1382 /* 1383 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 1384 * register based on the results of the comparison. 1385 * 1386 * We load the full values with LDM, but in practice many values could 1387 * be resolved by only looking at the high word. This could be made 1388 * faster or slower by splitting the LDM into a pair of LDRs. 1389 * 1390 * If we just wanted to set condition flags, we could do this: 1391 * subs ip, r0, r2 1392 * sbcs ip, r1, r3 1393 * subeqs ip, r0, r2 1394 * Leaving { <0, 0, >0 } in ip. However, we have to set it to a specific 1395 * integer value, which we can do with 2 conditional mov/mvn instructions 1396 * (set 1, set -1; if they're equal we already have 0 in ip), giving 1397 * us a constant 5-cycle path plus a branch at the end to the 1398 * instruction epilogue code. The multi-compare approach below needs 1399 * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch 1400 * in the worst case (the 64-bit values are equal). 1401 */ 1402 /* cmp-long vAA, vBB, vCC */ 1403 FETCH(r0, 1) @ r0<- CCBB 1404 mov r9, rINST, lsr #8 @ r9<- AA 1405 and r2, r0, #255 @ r2<- BB 1406 mov r3, r0, lsr #8 @ r3<- CC 1407 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 1408 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 1409 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 1410 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 1411 cmp r1, r3 @ compare (vBB+1, vCC+1) 1412 blt .LOP_CMP_LONG_less @ signed compare on high part 1413 bgt .LOP_CMP_LONG_greater 1414 subs r1, r0, r2 @ r1<- r0 - r2 1415 bhi .LOP_CMP_LONG_greater @ unsigned compare on low part 1416 bne .LOP_CMP_LONG_less 1417 b .LOP_CMP_LONG_finish @ equal; r1 already holds 0 1418 1419/* ------------------------------ */ 1420 .balign 64 1421.L_OP_IF_EQ: /* 0x32 */ 1422/* File: armv5te/OP_IF_EQ.S */ 1423/* File: armv5te/bincmp.S */ 1424 /* 1425 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1426 * fragment that specifies the *reverse* comparison to perform, e.g. 1427 * for "if-le" you would use "gt". 1428 * 1429 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1430 */ 1431 /* if-cmp vA, vB, +CCCC */ 1432 mov r0, rINST, lsr #8 @ r0<- A+ 1433 mov r1, rINST, lsr #12 @ r1<- B 1434 and r0, r0, #15 1435 GET_VREG(r3, r1) @ r3<- vB 1436 GET_VREG(r2, r0) @ r2<- vA 1437 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1438 cmp r2, r3 @ compare (vA, vB) 1439 movne r1, #2 @ r1<- BYTE branch dist for not-taken 1440 adds r2, r1, r1 @ convert to bytes, check sign 1441 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1442#if defined(WITH_JIT) 1443 ldr r0, [rSELF, #offThread_pJitProfTable] 1444 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1445 cmp r0,#0 1446 bne common_updateProfile 1447#else 1448 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1449#endif 1450 GET_INST_OPCODE(ip) @ extract opcode from rINST 1451 GOTO_OPCODE(ip) @ jump to next instruction 1452 1453 1454/* ------------------------------ */ 1455 .balign 64 1456.L_OP_IF_NE: /* 0x33 */ 1457/* File: armv5te/OP_IF_NE.S */ 1458/* File: armv5te/bincmp.S */ 1459 /* 1460 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1461 * fragment that specifies the *reverse* comparison to perform, e.g. 1462 * for "if-le" you would use "gt". 1463 * 1464 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1465 */ 1466 /* if-cmp vA, vB, +CCCC */ 1467 mov r0, rINST, lsr #8 @ r0<- A+ 1468 mov r1, rINST, lsr #12 @ r1<- B 1469 and r0, r0, #15 1470 GET_VREG(r3, r1) @ r3<- vB 1471 GET_VREG(r2, r0) @ r2<- vA 1472 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1473 cmp r2, r3 @ compare (vA, vB) 1474 moveq r1, #2 @ r1<- BYTE branch dist for not-taken 1475 adds r2, r1, r1 @ convert to bytes, check sign 1476 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1477#if defined(WITH_JIT) 1478 ldr r0, [rSELF, #offThread_pJitProfTable] 1479 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1480 cmp r0,#0 1481 bne common_updateProfile 1482#else 1483 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1484#endif 1485 GET_INST_OPCODE(ip) @ extract opcode from rINST 1486 GOTO_OPCODE(ip) @ jump to next instruction 1487 1488 1489/* ------------------------------ */ 1490 .balign 64 1491.L_OP_IF_LT: /* 0x34 */ 1492/* File: armv5te/OP_IF_LT.S */ 1493/* File: armv5te/bincmp.S */ 1494 /* 1495 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1496 * fragment that specifies the *reverse* comparison to perform, e.g. 1497 * for "if-le" you would use "gt". 1498 * 1499 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1500 */ 1501 /* if-cmp vA, vB, +CCCC */ 1502 mov r0, rINST, lsr #8 @ r0<- A+ 1503 mov r1, rINST, lsr #12 @ r1<- B 1504 and r0, r0, #15 1505 GET_VREG(r3, r1) @ r3<- vB 1506 GET_VREG(r2, r0) @ r2<- vA 1507 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1508 cmp r2, r3 @ compare (vA, vB) 1509 movge r1, #2 @ r1<- BYTE branch dist for not-taken 1510 adds r2, r1, r1 @ convert to bytes, check sign 1511 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1512#if defined(WITH_JIT) 1513 ldr r0, [rSELF, #offThread_pJitProfTable] 1514 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1515 cmp r0,#0 1516 bne common_updateProfile 1517#else 1518 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1519#endif 1520 GET_INST_OPCODE(ip) @ extract opcode from rINST 1521 GOTO_OPCODE(ip) @ jump to next instruction 1522 1523 1524/* ------------------------------ */ 1525 .balign 64 1526.L_OP_IF_GE: /* 0x35 */ 1527/* File: armv5te/OP_IF_GE.S */ 1528/* File: armv5te/bincmp.S */ 1529 /* 1530 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1531 * fragment that specifies the *reverse* comparison to perform, e.g. 1532 * for "if-le" you would use "gt". 1533 * 1534 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1535 */ 1536 /* if-cmp vA, vB, +CCCC */ 1537 mov r0, rINST, lsr #8 @ r0<- A+ 1538 mov r1, rINST, lsr #12 @ r1<- B 1539 and r0, r0, #15 1540 GET_VREG(r3, r1) @ r3<- vB 1541 GET_VREG(r2, r0) @ r2<- vA 1542 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1543 cmp r2, r3 @ compare (vA, vB) 1544 movlt r1, #2 @ r1<- BYTE branch dist for not-taken 1545 adds r2, r1, r1 @ convert to bytes, check sign 1546 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1547#if defined(WITH_JIT) 1548 ldr r0, [rSELF, #offThread_pJitProfTable] 1549 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1550 cmp r0,#0 1551 bne common_updateProfile 1552#else 1553 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1554#endif 1555 GET_INST_OPCODE(ip) @ extract opcode from rINST 1556 GOTO_OPCODE(ip) @ jump to next instruction 1557 1558 1559/* ------------------------------ */ 1560 .balign 64 1561.L_OP_IF_GT: /* 0x36 */ 1562/* File: armv5te/OP_IF_GT.S */ 1563/* File: armv5te/bincmp.S */ 1564 /* 1565 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1566 * fragment that specifies the *reverse* comparison to perform, e.g. 1567 * for "if-le" you would use "gt". 1568 * 1569 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1570 */ 1571 /* if-cmp vA, vB, +CCCC */ 1572 mov r0, rINST, lsr #8 @ r0<- A+ 1573 mov r1, rINST, lsr #12 @ r1<- B 1574 and r0, r0, #15 1575 GET_VREG(r3, r1) @ r3<- vB 1576 GET_VREG(r2, r0) @ r2<- vA 1577 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1578 cmp r2, r3 @ compare (vA, vB) 1579 movle r1, #2 @ r1<- BYTE branch dist for not-taken 1580 adds r2, r1, r1 @ convert to bytes, check sign 1581 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1582#if defined(WITH_JIT) 1583 ldr r0, [rSELF, #offThread_pJitProfTable] 1584 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1585 cmp r0,#0 1586 bne common_updateProfile 1587#else 1588 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1589#endif 1590 GET_INST_OPCODE(ip) @ extract opcode from rINST 1591 GOTO_OPCODE(ip) @ jump to next instruction 1592 1593 1594/* ------------------------------ */ 1595 .balign 64 1596.L_OP_IF_LE: /* 0x37 */ 1597/* File: armv5te/OP_IF_LE.S */ 1598/* File: armv5te/bincmp.S */ 1599 /* 1600 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1601 * fragment that specifies the *reverse* comparison to perform, e.g. 1602 * for "if-le" you would use "gt". 1603 * 1604 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1605 */ 1606 /* if-cmp vA, vB, +CCCC */ 1607 mov r0, rINST, lsr #8 @ r0<- A+ 1608 mov r1, rINST, lsr #12 @ r1<- B 1609 and r0, r0, #15 1610 GET_VREG(r3, r1) @ r3<- vB 1611 GET_VREG(r2, r0) @ r2<- vA 1612 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1613 cmp r2, r3 @ compare (vA, vB) 1614 movgt r1, #2 @ r1<- BYTE branch dist for not-taken 1615 adds r2, r1, r1 @ convert to bytes, check sign 1616 FETCH_ADVANCE_INST_RB(r2) @ update rPC, load rINST 1617#if defined(WITH_JIT) 1618 ldr r0, [rSELF, #offThread_pJitProfTable] 1619 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1620 cmp r0,#0 1621 bne common_updateProfile 1622#else 1623 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 1624#endif 1625 GET_INST_OPCODE(ip) @ extract opcode from rINST 1626 GOTO_OPCODE(ip) @ jump to next instruction 1627 1628 1629/* ------------------------------ */ 1630 .balign 64 1631.L_OP_IF_EQZ: /* 0x38 */ 1632/* File: armv5te/OP_IF_EQZ.S */ 1633/* File: armv5te/zcmp.S */ 1634 /* 1635 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1636 * fragment that specifies the *reverse* comparison to perform, e.g. 1637 * for "if-le" you would use "gt". 1638 * 1639 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1640 */ 1641 /* if-cmp vAA, +BBBB */ 1642 mov r0, rINST, lsr #8 @ r0<- AA 1643 GET_VREG(r2, r0) @ r2<- vAA 1644 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1645 cmp r2, #0 @ compare (vA, 0) 1646 movne r1, #2 @ r1<- inst branch dist for not-taken 1647 adds r1, r1, r1 @ convert to bytes & set flags 1648 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1649#if defined(WITH_JIT) 1650 ldr r0, [rSELF, #offThread_pJitProfTable] 1651 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1652 cmp r0,#0 1653 bne common_updateProfile @ test for JIT off at target 1654#else 1655 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1656#endif 1657 GET_INST_OPCODE(ip) @ extract opcode from rINST 1658 GOTO_OPCODE(ip) @ jump to next instruction 1659 1660 1661/* ------------------------------ */ 1662 .balign 64 1663.L_OP_IF_NEZ: /* 0x39 */ 1664/* File: armv5te/OP_IF_NEZ.S */ 1665/* File: armv5te/zcmp.S */ 1666 /* 1667 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1668 * fragment that specifies the *reverse* comparison to perform, e.g. 1669 * for "if-le" you would use "gt". 1670 * 1671 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1672 */ 1673 /* if-cmp vAA, +BBBB */ 1674 mov r0, rINST, lsr #8 @ r0<- AA 1675 GET_VREG(r2, r0) @ r2<- vAA 1676 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1677 cmp r2, #0 @ compare (vA, 0) 1678 moveq r1, #2 @ r1<- inst branch dist for not-taken 1679 adds r1, r1, r1 @ convert to bytes & set flags 1680 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1681#if defined(WITH_JIT) 1682 ldr r0, [rSELF, #offThread_pJitProfTable] 1683 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1684 cmp r0,#0 1685 bne common_updateProfile @ test for JIT off at target 1686#else 1687 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1688#endif 1689 GET_INST_OPCODE(ip) @ extract opcode from rINST 1690 GOTO_OPCODE(ip) @ jump to next instruction 1691 1692 1693/* ------------------------------ */ 1694 .balign 64 1695.L_OP_IF_LTZ: /* 0x3a */ 1696/* File: armv5te/OP_IF_LTZ.S */ 1697/* File: armv5te/zcmp.S */ 1698 /* 1699 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1700 * fragment that specifies the *reverse* comparison to perform, e.g. 1701 * for "if-le" you would use "gt". 1702 * 1703 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1704 */ 1705 /* if-cmp vAA, +BBBB */ 1706 mov r0, rINST, lsr #8 @ r0<- AA 1707 GET_VREG(r2, r0) @ r2<- vAA 1708 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1709 cmp r2, #0 @ compare (vA, 0) 1710 movge r1, #2 @ r1<- inst branch dist for not-taken 1711 adds r1, r1, r1 @ convert to bytes & set flags 1712 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1713#if defined(WITH_JIT) 1714 ldr r0, [rSELF, #offThread_pJitProfTable] 1715 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1716 cmp r0,#0 1717 bne common_updateProfile @ test for JIT off at target 1718#else 1719 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1720#endif 1721 GET_INST_OPCODE(ip) @ extract opcode from rINST 1722 GOTO_OPCODE(ip) @ jump to next instruction 1723 1724 1725/* ------------------------------ */ 1726 .balign 64 1727.L_OP_IF_GEZ: /* 0x3b */ 1728/* File: armv5te/OP_IF_GEZ.S */ 1729/* File: armv5te/zcmp.S */ 1730 /* 1731 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1732 * fragment that specifies the *reverse* comparison to perform, e.g. 1733 * for "if-le" you would use "gt". 1734 * 1735 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1736 */ 1737 /* if-cmp vAA, +BBBB */ 1738 mov r0, rINST, lsr #8 @ r0<- AA 1739 GET_VREG(r2, r0) @ r2<- vAA 1740 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1741 cmp r2, #0 @ compare (vA, 0) 1742 movlt r1, #2 @ r1<- inst branch dist for not-taken 1743 adds r1, r1, r1 @ convert to bytes & set flags 1744 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1745#if defined(WITH_JIT) 1746 ldr r0, [rSELF, #offThread_pJitProfTable] 1747 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1748 cmp r0,#0 1749 bne common_updateProfile @ test for JIT off at target 1750#else 1751 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1752#endif 1753 GET_INST_OPCODE(ip) @ extract opcode from rINST 1754 GOTO_OPCODE(ip) @ jump to next instruction 1755 1756 1757/* ------------------------------ */ 1758 .balign 64 1759.L_OP_IF_GTZ: /* 0x3c */ 1760/* File: armv5te/OP_IF_GTZ.S */ 1761/* File: armv5te/zcmp.S */ 1762 /* 1763 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1764 * fragment that specifies the *reverse* comparison to perform, e.g. 1765 * for "if-le" you would use "gt". 1766 * 1767 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1768 */ 1769 /* if-cmp vAA, +BBBB */ 1770 mov r0, rINST, lsr #8 @ r0<- AA 1771 GET_VREG(r2, r0) @ r2<- vAA 1772 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1773 cmp r2, #0 @ compare (vA, 0) 1774 movle r1, #2 @ r1<- inst branch dist for not-taken 1775 adds r1, r1, r1 @ convert to bytes & set flags 1776 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1777#if defined(WITH_JIT) 1778 ldr r0, [rSELF, #offThread_pJitProfTable] 1779 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1780 cmp r0,#0 1781 bne common_updateProfile @ test for JIT off at target 1782#else 1783 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1784#endif 1785 GET_INST_OPCODE(ip) @ extract opcode from rINST 1786 GOTO_OPCODE(ip) @ jump to next instruction 1787 1788 1789/* ------------------------------ */ 1790 .balign 64 1791.L_OP_IF_LEZ: /* 0x3d */ 1792/* File: armv5te/OP_IF_LEZ.S */ 1793/* File: armv5te/zcmp.S */ 1794 /* 1795 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1796 * fragment that specifies the *reverse* comparison to perform, e.g. 1797 * for "if-le" you would use "gt". 1798 * 1799 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1800 */ 1801 /* if-cmp vAA, +BBBB */ 1802 mov r0, rINST, lsr #8 @ r0<- AA 1803 GET_VREG(r2, r0) @ r2<- vAA 1804 FETCH_S(r1, 1) @ r1<- branch offset, in code units 1805 cmp r2, #0 @ compare (vA, 0) 1806 movgt r1, #2 @ r1<- inst branch dist for not-taken 1807 adds r1, r1, r1 @ convert to bytes & set flags 1808 FETCH_ADVANCE_INST_RB(r1) @ update rPC, load rINST 1809#if defined(WITH_JIT) 1810 ldr r0, [rSELF, #offThread_pJitProfTable] 1811 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1812 cmp r0,#0 1813 bne common_updateProfile @ test for JIT off at target 1814#else 1815 ldrmi rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh table base 1816#endif 1817 GET_INST_OPCODE(ip) @ extract opcode from rINST 1818 GOTO_OPCODE(ip) @ jump to next instruction 1819 1820 1821/* ------------------------------ */ 1822 .balign 64 1823.L_OP_UNUSED_3E: /* 0x3e */ 1824/* File: armv5te/OP_UNUSED_3E.S */ 1825/* File: armv5te/unused.S */ 1826 bl common_abort 1827 1828 1829/* ------------------------------ */ 1830 .balign 64 1831.L_OP_UNUSED_3F: /* 0x3f */ 1832/* File: armv5te/OP_UNUSED_3F.S */ 1833/* File: armv5te/unused.S */ 1834 bl common_abort 1835 1836 1837/* ------------------------------ */ 1838 .balign 64 1839.L_OP_UNUSED_40: /* 0x40 */ 1840/* File: armv5te/OP_UNUSED_40.S */ 1841/* File: armv5te/unused.S */ 1842 bl common_abort 1843 1844 1845/* ------------------------------ */ 1846 .balign 64 1847.L_OP_UNUSED_41: /* 0x41 */ 1848/* File: armv5te/OP_UNUSED_41.S */ 1849/* File: armv5te/unused.S */ 1850 bl common_abort 1851 1852 1853/* ------------------------------ */ 1854 .balign 64 1855.L_OP_UNUSED_42: /* 0x42 */ 1856/* File: armv5te/OP_UNUSED_42.S */ 1857/* File: armv5te/unused.S */ 1858 bl common_abort 1859 1860 1861/* ------------------------------ */ 1862 .balign 64 1863.L_OP_UNUSED_43: /* 0x43 */ 1864/* File: armv5te/OP_UNUSED_43.S */ 1865/* File: armv5te/unused.S */ 1866 bl common_abort 1867 1868 1869/* ------------------------------ */ 1870 .balign 64 1871.L_OP_AGET: /* 0x44 */ 1872/* File: armv5te/OP_AGET.S */ 1873 /* 1874 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1875 * 1876 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1877 * instructions. We use a pair of FETCH_Bs instead. 1878 * 1879 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1880 */ 1881 /* op vAA, vBB, vCC */ 1882 FETCH_B(r2, 1, 0) @ r2<- BB 1883 mov r9, rINST, lsr #8 @ r9<- AA 1884 FETCH_B(r3, 1, 1) @ r3<- CC 1885 GET_VREG(r0, r2) @ r0<- vBB (array object) 1886 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1887 cmp r0, #0 @ null array object? 1888 beq common_errNullObject @ yes, bail 1889 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1890 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1891 cmp r1, r3 @ compare unsigned index, length 1892 bcs common_errArrayIndex @ index >= length, bail 1893 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1894 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1895 GET_INST_OPCODE(ip) @ extract opcode from rINST 1896 SET_VREG(r2, r9) @ vAA<- r2 1897 GOTO_OPCODE(ip) @ jump to next instruction 1898 1899/* ------------------------------ */ 1900 .balign 64 1901.L_OP_AGET_WIDE: /* 0x45 */ 1902/* File: armv5te/OP_AGET_WIDE.S */ 1903 /* 1904 * Array get, 64 bits. vAA <- vBB[vCC]. 1905 * 1906 * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD. 1907 */ 1908 /* aget-wide vAA, vBB, vCC */ 1909 FETCH(r0, 1) @ r0<- CCBB 1910 mov r9, rINST, lsr #8 @ r9<- AA 1911 and r2, r0, #255 @ r2<- BB 1912 mov r3, r0, lsr #8 @ r3<- CC 1913 GET_VREG(r0, r2) @ r0<- vBB (array object) 1914 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1915 cmp r0, #0 @ null array object? 1916 beq common_errNullObject @ yes, bail 1917 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1918 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 1919 cmp r1, r3 @ compare unsigned index, length 1920 bcc .LOP_AGET_WIDE_finish @ okay, continue below 1921 b common_errArrayIndex @ index >= length, bail 1922 @ May want to swap the order of these two branches depending on how the 1923 @ branch prediction (if any) handles conditional forward branches vs. 1924 @ unconditional forward branches. 1925 1926/* ------------------------------ */ 1927 .balign 64 1928.L_OP_AGET_OBJECT: /* 0x46 */ 1929/* File: armv5te/OP_AGET_OBJECT.S */ 1930/* File: armv5te/OP_AGET.S */ 1931 /* 1932 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1933 * 1934 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1935 * instructions. We use a pair of FETCH_Bs instead. 1936 * 1937 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1938 */ 1939 /* op vAA, vBB, vCC */ 1940 FETCH_B(r2, 1, 0) @ r2<- BB 1941 mov r9, rINST, lsr #8 @ r9<- AA 1942 FETCH_B(r3, 1, 1) @ r3<- CC 1943 GET_VREG(r0, r2) @ r0<- vBB (array object) 1944 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1945 cmp r0, #0 @ null array object? 1946 beq common_errNullObject @ yes, bail 1947 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1948 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1949 cmp r1, r3 @ compare unsigned index, length 1950 bcs common_errArrayIndex @ index >= length, bail 1951 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1952 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1953 GET_INST_OPCODE(ip) @ extract opcode from rINST 1954 SET_VREG(r2, r9) @ vAA<- r2 1955 GOTO_OPCODE(ip) @ jump to next instruction 1956 1957 1958/* ------------------------------ */ 1959 .balign 64 1960.L_OP_AGET_BOOLEAN: /* 0x47 */ 1961/* File: armv5te/OP_AGET_BOOLEAN.S */ 1962/* File: armv5te/OP_AGET.S */ 1963 /* 1964 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1965 * 1966 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1967 * instructions. We use a pair of FETCH_Bs instead. 1968 * 1969 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1970 */ 1971 /* op vAA, vBB, vCC */ 1972 FETCH_B(r2, 1, 0) @ r2<- BB 1973 mov r9, rINST, lsr #8 @ r9<- AA 1974 FETCH_B(r3, 1, 1) @ r3<- CC 1975 GET_VREG(r0, r2) @ r0<- vBB (array object) 1976 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1977 cmp r0, #0 @ null array object? 1978 beq common_errNullObject @ yes, bail 1979 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1980 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 1981 cmp r1, r3 @ compare unsigned index, length 1982 bcs common_errArrayIndex @ index >= length, bail 1983 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1984 ldrb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1985 GET_INST_OPCODE(ip) @ extract opcode from rINST 1986 SET_VREG(r2, r9) @ vAA<- r2 1987 GOTO_OPCODE(ip) @ jump to next instruction 1988 1989 1990/* ------------------------------ */ 1991 .balign 64 1992.L_OP_AGET_BYTE: /* 0x48 */ 1993/* File: armv5te/OP_AGET_BYTE.S */ 1994/* File: armv5te/OP_AGET.S */ 1995 /* 1996 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1997 * 1998 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1999 * instructions. We use a pair of FETCH_Bs instead. 2000 * 2001 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2002 */ 2003 /* op vAA, vBB, vCC */ 2004 FETCH_B(r2, 1, 0) @ r2<- BB 2005 mov r9, rINST, lsr #8 @ r9<- AA 2006 FETCH_B(r3, 1, 1) @ r3<- CC 2007 GET_VREG(r0, r2) @ r0<- vBB (array object) 2008 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2009 cmp r0, #0 @ null array object? 2010 beq common_errNullObject @ yes, bail 2011 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2012 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2013 cmp r1, r3 @ compare unsigned index, length 2014 bcs common_errArrayIndex @ index >= length, bail 2015 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2016 ldrsb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2017 GET_INST_OPCODE(ip) @ extract opcode from rINST 2018 SET_VREG(r2, r9) @ vAA<- r2 2019 GOTO_OPCODE(ip) @ jump to next instruction 2020 2021 2022/* ------------------------------ */ 2023 .balign 64 2024.L_OP_AGET_CHAR: /* 0x49 */ 2025/* File: armv5te/OP_AGET_CHAR.S */ 2026/* File: armv5te/OP_AGET.S */ 2027 /* 2028 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2029 * 2030 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2031 * instructions. We use a pair of FETCH_Bs instead. 2032 * 2033 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2034 */ 2035 /* op vAA, vBB, vCC */ 2036 FETCH_B(r2, 1, 0) @ r2<- BB 2037 mov r9, rINST, lsr #8 @ r9<- AA 2038 FETCH_B(r3, 1, 1) @ r3<- CC 2039 GET_VREG(r0, r2) @ r0<- vBB (array object) 2040 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2041 cmp r0, #0 @ null array object? 2042 beq common_errNullObject @ yes, bail 2043 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2044 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2045 cmp r1, r3 @ compare unsigned index, length 2046 bcs common_errArrayIndex @ index >= length, bail 2047 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2048 ldrh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2049 GET_INST_OPCODE(ip) @ extract opcode from rINST 2050 SET_VREG(r2, r9) @ vAA<- r2 2051 GOTO_OPCODE(ip) @ jump to next instruction 2052 2053 2054/* ------------------------------ */ 2055 .balign 64 2056.L_OP_AGET_SHORT: /* 0x4a */ 2057/* File: armv5te/OP_AGET_SHORT.S */ 2058/* File: armv5te/OP_AGET.S */ 2059 /* 2060 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2061 * 2062 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2063 * instructions. We use a pair of FETCH_Bs instead. 2064 * 2065 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2066 */ 2067 /* op vAA, vBB, vCC */ 2068 FETCH_B(r2, 1, 0) @ r2<- BB 2069 mov r9, rINST, lsr #8 @ r9<- AA 2070 FETCH_B(r3, 1, 1) @ r3<- CC 2071 GET_VREG(r0, r2) @ r0<- vBB (array object) 2072 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2073 cmp r0, #0 @ null array object? 2074 beq common_errNullObject @ yes, bail 2075 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2076 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2077 cmp r1, r3 @ compare unsigned index, length 2078 bcs common_errArrayIndex @ index >= length, bail 2079 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2080 ldrsh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2081 GET_INST_OPCODE(ip) @ extract opcode from rINST 2082 SET_VREG(r2, r9) @ vAA<- r2 2083 GOTO_OPCODE(ip) @ jump to next instruction 2084 2085 2086/* ------------------------------ */ 2087 .balign 64 2088.L_OP_APUT: /* 0x4b */ 2089/* File: armv5te/OP_APUT.S */ 2090 /* 2091 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2092 * 2093 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2094 * instructions. We use a pair of FETCH_Bs instead. 2095 * 2096 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2097 */ 2098 /* op vAA, vBB, vCC */ 2099 FETCH_B(r2, 1, 0) @ r2<- BB 2100 mov r9, rINST, lsr #8 @ r9<- AA 2101 FETCH_B(r3, 1, 1) @ r3<- CC 2102 GET_VREG(r0, r2) @ r0<- vBB (array object) 2103 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2104 cmp r0, #0 @ null array object? 2105 beq common_errNullObject @ yes, bail 2106 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2107 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2108 cmp r1, r3 @ compare unsigned index, length 2109 bcs common_errArrayIndex @ index >= length, bail 2110 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2111 GET_VREG(r2, r9) @ r2<- vAA 2112 GET_INST_OPCODE(ip) @ extract opcode from rINST 2113 str r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2114 GOTO_OPCODE(ip) @ jump to next instruction 2115 2116/* ------------------------------ */ 2117 .balign 64 2118.L_OP_APUT_WIDE: /* 0x4c */ 2119/* File: armv5te/OP_APUT_WIDE.S */ 2120 /* 2121 * Array put, 64 bits. vBB[vCC] <- vAA. 2122 * 2123 * Arrays of long/double are 64-bit aligned, so it's okay to use STRD. 2124 */ 2125 /* aput-wide vAA, vBB, vCC */ 2126 FETCH(r0, 1) @ r0<- CCBB 2127 mov r9, rINST, lsr #8 @ r9<- AA 2128 and r2, r0, #255 @ r2<- BB 2129 mov r3, r0, lsr #8 @ r3<- CC 2130 GET_VREG(r0, r2) @ r0<- vBB (array object) 2131 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2132 cmp r0, #0 @ null array object? 2133 beq common_errNullObject @ yes, bail 2134 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2135 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2136 cmp r1, r3 @ compare unsigned index, length 2137 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2138 bcc .LOP_APUT_WIDE_finish @ okay, continue below 2139 b common_errArrayIndex @ index >= length, bail 2140 @ May want to swap the order of these two branches depending on how the 2141 @ branch prediction (if any) handles conditional forward branches vs. 2142 @ unconditional forward branches. 2143 2144/* ------------------------------ */ 2145 .balign 64 2146.L_OP_APUT_OBJECT: /* 0x4d */ 2147/* File: armv5te/OP_APUT_OBJECT.S */ 2148 /* 2149 * Store an object into an array. vBB[vCC] <- vAA. 2150 */ 2151 /* op vAA, vBB, vCC */ 2152 FETCH(r0, 1) @ r0<- CCBB 2153 mov r9, rINST, lsr #8 @ r9<- AA 2154 and r2, r0, #255 @ r2<- BB 2155 mov r3, r0, lsr #8 @ r3<- CC 2156 GET_VREG(rINST, r2) @ rINST<- vBB (array object) 2157 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2158 cmp rINST, #0 @ null array object? 2159 GET_VREG(r9, r9) @ r9<- vAA 2160 beq common_errNullObject @ yes, bail 2161 ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length 2162 add r10, rINST, r1, lsl #2 @ r10<- arrayObj + index*width 2163 cmp r1, r3 @ compare unsigned index, length 2164 bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on 2165 b common_errArrayIndex @ index >= length, bail 2166 2167 2168/* ------------------------------ */ 2169 .balign 64 2170.L_OP_APUT_BOOLEAN: /* 0x4e */ 2171/* File: armv5te/OP_APUT_BOOLEAN.S */ 2172/* File: armv5te/OP_APUT.S */ 2173 /* 2174 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2175 * 2176 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2177 * instructions. We use a pair of FETCH_Bs instead. 2178 * 2179 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2180 */ 2181 /* op vAA, vBB, vCC */ 2182 FETCH_B(r2, 1, 0) @ r2<- BB 2183 mov r9, rINST, lsr #8 @ r9<- AA 2184 FETCH_B(r3, 1, 1) @ r3<- CC 2185 GET_VREG(r0, r2) @ r0<- vBB (array object) 2186 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2187 cmp r0, #0 @ null array object? 2188 beq common_errNullObject @ yes, bail 2189 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2190 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2191 cmp r1, r3 @ compare unsigned index, length 2192 bcs common_errArrayIndex @ index >= length, bail 2193 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2194 GET_VREG(r2, r9) @ r2<- vAA 2195 GET_INST_OPCODE(ip) @ extract opcode from rINST 2196 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2197 GOTO_OPCODE(ip) @ jump to next instruction 2198 2199 2200/* ------------------------------ */ 2201 .balign 64 2202.L_OP_APUT_BYTE: /* 0x4f */ 2203/* File: armv5te/OP_APUT_BYTE.S */ 2204/* File: armv5te/OP_APUT.S */ 2205 /* 2206 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2207 * 2208 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2209 * instructions. We use a pair of FETCH_Bs instead. 2210 * 2211 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2212 */ 2213 /* op vAA, vBB, vCC */ 2214 FETCH_B(r2, 1, 0) @ r2<- BB 2215 mov r9, rINST, lsr #8 @ r9<- AA 2216 FETCH_B(r3, 1, 1) @ r3<- CC 2217 GET_VREG(r0, r2) @ r0<- vBB (array object) 2218 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2219 cmp r0, #0 @ null array object? 2220 beq common_errNullObject @ yes, bail 2221 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2222 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2223 cmp r1, r3 @ compare unsigned index, length 2224 bcs common_errArrayIndex @ index >= length, bail 2225 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2226 GET_VREG(r2, r9) @ r2<- vAA 2227 GET_INST_OPCODE(ip) @ extract opcode from rINST 2228 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2229 GOTO_OPCODE(ip) @ jump to next instruction 2230 2231 2232/* ------------------------------ */ 2233 .balign 64 2234.L_OP_APUT_CHAR: /* 0x50 */ 2235/* File: armv5te/OP_APUT_CHAR.S */ 2236/* File: armv5te/OP_APUT.S */ 2237 /* 2238 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2239 * 2240 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2241 * instructions. We use a pair of FETCH_Bs instead. 2242 * 2243 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2244 */ 2245 /* op vAA, vBB, vCC */ 2246 FETCH_B(r2, 1, 0) @ r2<- BB 2247 mov r9, rINST, lsr #8 @ r9<- AA 2248 FETCH_B(r3, 1, 1) @ r3<- CC 2249 GET_VREG(r0, r2) @ r0<- vBB (array object) 2250 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2251 cmp r0, #0 @ null array object? 2252 beq common_errNullObject @ yes, bail 2253 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2254 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2255 cmp r1, r3 @ compare unsigned index, length 2256 bcs common_errArrayIndex @ index >= length, bail 2257 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2258 GET_VREG(r2, r9) @ r2<- vAA 2259 GET_INST_OPCODE(ip) @ extract opcode from rINST 2260 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2261 GOTO_OPCODE(ip) @ jump to next instruction 2262 2263 2264/* ------------------------------ */ 2265 .balign 64 2266.L_OP_APUT_SHORT: /* 0x51 */ 2267/* File: armv5te/OP_APUT_SHORT.S */ 2268/* File: armv5te/OP_APUT.S */ 2269 /* 2270 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2271 * 2272 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2273 * instructions. We use a pair of FETCH_Bs instead. 2274 * 2275 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2276 */ 2277 /* op vAA, vBB, vCC */ 2278 FETCH_B(r2, 1, 0) @ r2<- BB 2279 mov r9, rINST, lsr #8 @ r9<- AA 2280 FETCH_B(r3, 1, 1) @ r3<- CC 2281 GET_VREG(r0, r2) @ r0<- vBB (array object) 2282 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2283 cmp r0, #0 @ null array object? 2284 beq common_errNullObject @ yes, bail 2285 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2286 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2287 cmp r1, r3 @ compare unsigned index, length 2288 bcs common_errArrayIndex @ index >= length, bail 2289 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2290 GET_VREG(r2, r9) @ r2<- vAA 2291 GET_INST_OPCODE(ip) @ extract opcode from rINST 2292 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2293 GOTO_OPCODE(ip) @ jump to next instruction 2294 2295 2296/* ------------------------------ */ 2297 .balign 64 2298.L_OP_IGET: /* 0x52 */ 2299/* File: armv5te/OP_IGET.S */ 2300 /* 2301 * General 32-bit instance field get. 2302 * 2303 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2304 */ 2305 /* op vA, vB, field@CCCC */ 2306 mov r0, rINST, lsr #12 @ r0<- B 2307 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2308 FETCH(r1, 1) @ r1<- field ref CCCC 2309 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2310 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2311 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2312 cmp r0, #0 @ is resolved entry null? 2313 bne .LOP_IGET_finish @ no, already resolved 23148: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2315 EXPORT_PC() @ resolve() could throw 2316 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2317 bl dvmResolveInstField @ r0<- resolved InstField ptr 2318 cmp r0, #0 2319 bne .LOP_IGET_finish 2320 b common_exceptionThrown 2321 2322/* ------------------------------ */ 2323 .balign 64 2324.L_OP_IGET_WIDE: /* 0x53 */ 2325/* File: armv5te/OP_IGET_WIDE.S */ 2326 /* 2327 * Wide 32-bit instance field get. 2328 */ 2329 /* iget-wide vA, vB, field@CCCC */ 2330 mov r0, rINST, lsr #12 @ r0<- B 2331 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2332 FETCH(r1, 1) @ r1<- field ref CCCC 2333 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2334 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2335 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2336 cmp r0, #0 @ is resolved entry null? 2337 bne .LOP_IGET_WIDE_finish @ no, already resolved 23388: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2339 EXPORT_PC() @ resolve() could throw 2340 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2341 bl dvmResolveInstField @ r0<- resolved InstField ptr 2342 cmp r0, #0 2343 bne .LOP_IGET_WIDE_finish 2344 b common_exceptionThrown 2345 2346/* ------------------------------ */ 2347 .balign 64 2348.L_OP_IGET_OBJECT: /* 0x54 */ 2349/* File: armv5te/OP_IGET_OBJECT.S */ 2350/* File: armv5te/OP_IGET.S */ 2351 /* 2352 * General 32-bit instance field get. 2353 * 2354 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2355 */ 2356 /* op vA, vB, field@CCCC */ 2357 mov r0, rINST, lsr #12 @ r0<- B 2358 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2359 FETCH(r1, 1) @ r1<- field ref CCCC 2360 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2361 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2362 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2363 cmp r0, #0 @ is resolved entry null? 2364 bne .LOP_IGET_OBJECT_finish @ no, already resolved 23658: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2366 EXPORT_PC() @ resolve() could throw 2367 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2368 bl dvmResolveInstField @ r0<- resolved InstField ptr 2369 cmp r0, #0 2370 bne .LOP_IGET_OBJECT_finish 2371 b common_exceptionThrown 2372 2373 2374/* ------------------------------ */ 2375 .balign 64 2376.L_OP_IGET_BOOLEAN: /* 0x55 */ 2377/* File: armv5te/OP_IGET_BOOLEAN.S */ 2378@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" } 2379/* File: armv5te/OP_IGET.S */ 2380 /* 2381 * General 32-bit instance field get. 2382 * 2383 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2384 */ 2385 /* op vA, vB, field@CCCC */ 2386 mov r0, rINST, lsr #12 @ r0<- B 2387 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2388 FETCH(r1, 1) @ r1<- field ref CCCC 2389 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2390 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2391 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2392 cmp r0, #0 @ is resolved entry null? 2393 bne .LOP_IGET_BOOLEAN_finish @ no, already resolved 23948: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2395 EXPORT_PC() @ resolve() could throw 2396 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2397 bl dvmResolveInstField @ r0<- resolved InstField ptr 2398 cmp r0, #0 2399 bne .LOP_IGET_BOOLEAN_finish 2400 b common_exceptionThrown 2401 2402 2403/* ------------------------------ */ 2404 .balign 64 2405.L_OP_IGET_BYTE: /* 0x56 */ 2406/* File: armv5te/OP_IGET_BYTE.S */ 2407@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" } 2408/* File: armv5te/OP_IGET.S */ 2409 /* 2410 * General 32-bit instance field get. 2411 * 2412 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2413 */ 2414 /* op vA, vB, field@CCCC */ 2415 mov r0, rINST, lsr #12 @ r0<- B 2416 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2417 FETCH(r1, 1) @ r1<- field ref CCCC 2418 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2419 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2420 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2421 cmp r0, #0 @ is resolved entry null? 2422 bne .LOP_IGET_BYTE_finish @ no, already resolved 24238: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2424 EXPORT_PC() @ resolve() could throw 2425 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2426 bl dvmResolveInstField @ r0<- resolved InstField ptr 2427 cmp r0, #0 2428 bne .LOP_IGET_BYTE_finish 2429 b common_exceptionThrown 2430 2431 2432/* ------------------------------ */ 2433 .balign 64 2434.L_OP_IGET_CHAR: /* 0x57 */ 2435/* File: armv5te/OP_IGET_CHAR.S */ 2436@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" } 2437/* File: armv5te/OP_IGET.S */ 2438 /* 2439 * General 32-bit instance field get. 2440 * 2441 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2442 */ 2443 /* op vA, vB, field@CCCC */ 2444 mov r0, rINST, lsr #12 @ r0<- B 2445 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2446 FETCH(r1, 1) @ r1<- field ref CCCC 2447 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2448 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2449 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2450 cmp r0, #0 @ is resolved entry null? 2451 bne .LOP_IGET_CHAR_finish @ no, already resolved 24528: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2453 EXPORT_PC() @ resolve() could throw 2454 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2455 bl dvmResolveInstField @ r0<- resolved InstField ptr 2456 cmp r0, #0 2457 bne .LOP_IGET_CHAR_finish 2458 b common_exceptionThrown 2459 2460 2461/* ------------------------------ */ 2462 .balign 64 2463.L_OP_IGET_SHORT: /* 0x58 */ 2464/* File: armv5te/OP_IGET_SHORT.S */ 2465@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" } 2466/* File: armv5te/OP_IGET.S */ 2467 /* 2468 * General 32-bit instance field get. 2469 * 2470 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2471 */ 2472 /* op vA, vB, field@CCCC */ 2473 mov r0, rINST, lsr #12 @ r0<- B 2474 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2475 FETCH(r1, 1) @ r1<- field ref CCCC 2476 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2477 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2478 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2479 cmp r0, #0 @ is resolved entry null? 2480 bne .LOP_IGET_SHORT_finish @ no, already resolved 24818: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2482 EXPORT_PC() @ resolve() could throw 2483 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2484 bl dvmResolveInstField @ r0<- resolved InstField ptr 2485 cmp r0, #0 2486 bne .LOP_IGET_SHORT_finish 2487 b common_exceptionThrown 2488 2489 2490/* ------------------------------ */ 2491 .balign 64 2492.L_OP_IPUT: /* 0x59 */ 2493/* File: armv5te/OP_IPUT.S */ 2494 /* 2495 * General 32-bit instance field put. 2496 * 2497 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2498 */ 2499 /* op vA, vB, field@CCCC */ 2500 mov r0, rINST, lsr #12 @ r0<- B 2501 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2502 FETCH(r1, 1) @ r1<- field ref CCCC 2503 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2504 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2505 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2506 cmp r0, #0 @ is resolved entry null? 2507 bne .LOP_IPUT_finish @ no, already resolved 25088: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2509 EXPORT_PC() @ resolve() could throw 2510 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2511 bl dvmResolveInstField @ r0<- resolved InstField ptr 2512 cmp r0, #0 @ success? 2513 bne .LOP_IPUT_finish @ yes, finish up 2514 b common_exceptionThrown 2515 2516/* ------------------------------ */ 2517 .balign 64 2518.L_OP_IPUT_WIDE: /* 0x5a */ 2519/* File: armv5te/OP_IPUT_WIDE.S */ 2520 /* iput-wide vA, vB, field@CCCC */ 2521 mov r0, rINST, lsr #12 @ r0<- B 2522 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2523 FETCH(r1, 1) @ r1<- field ref CCCC 2524 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2525 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2526 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2527 cmp r0, #0 @ is resolved entry null? 2528 bne .LOP_IPUT_WIDE_finish @ no, already resolved 25298: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2530 EXPORT_PC() @ resolve() could throw 2531 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2532 bl dvmResolveInstField @ r0<- resolved InstField ptr 2533 cmp r0, #0 @ success? 2534 bne .LOP_IPUT_WIDE_finish @ yes, finish up 2535 b common_exceptionThrown 2536 2537/* ------------------------------ */ 2538 .balign 64 2539.L_OP_IPUT_OBJECT: /* 0x5b */ 2540/* File: armv5te/OP_IPUT_OBJECT.S */ 2541 /* 2542 * 32-bit instance field put. 2543 * 2544 * for: iput-object, iput-object-volatile 2545 */ 2546 /* op vA, vB, field@CCCC */ 2547 mov r0, rINST, lsr #12 @ r0<- B 2548 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2549 FETCH(r1, 1) @ r1<- field ref CCCC 2550 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2551 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2552 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2553 cmp r0, #0 @ is resolved entry null? 2554 bne .LOP_IPUT_OBJECT_finish @ no, already resolved 25558: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2556 EXPORT_PC() @ resolve() could throw 2557 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2558 bl dvmResolveInstField @ r0<- resolved InstField ptr 2559 cmp r0, #0 @ success? 2560 bne .LOP_IPUT_OBJECT_finish @ yes, finish up 2561 b common_exceptionThrown 2562 2563/* ------------------------------ */ 2564 .balign 64 2565.L_OP_IPUT_BOOLEAN: /* 0x5c */ 2566/* File: armv5te/OP_IPUT_BOOLEAN.S */ 2567@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" } 2568/* File: armv5te/OP_IPUT.S */ 2569 /* 2570 * General 32-bit instance field put. 2571 * 2572 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2573 */ 2574 /* op vA, vB, field@CCCC */ 2575 mov r0, rINST, lsr #12 @ r0<- B 2576 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2577 FETCH(r1, 1) @ r1<- field ref CCCC 2578 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2579 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2580 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2581 cmp r0, #0 @ is resolved entry null? 2582 bne .LOP_IPUT_BOOLEAN_finish @ no, already resolved 25838: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2584 EXPORT_PC() @ resolve() could throw 2585 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2586 bl dvmResolveInstField @ r0<- resolved InstField ptr 2587 cmp r0, #0 @ success? 2588 bne .LOP_IPUT_BOOLEAN_finish @ yes, finish up 2589 b common_exceptionThrown 2590 2591 2592/* ------------------------------ */ 2593 .balign 64 2594.L_OP_IPUT_BYTE: /* 0x5d */ 2595/* File: armv5te/OP_IPUT_BYTE.S */ 2596@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" } 2597/* File: armv5te/OP_IPUT.S */ 2598 /* 2599 * General 32-bit instance field put. 2600 * 2601 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2602 */ 2603 /* op vA, vB, field@CCCC */ 2604 mov r0, rINST, lsr #12 @ r0<- B 2605 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2606 FETCH(r1, 1) @ r1<- field ref CCCC 2607 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2608 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2609 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2610 cmp r0, #0 @ is resolved entry null? 2611 bne .LOP_IPUT_BYTE_finish @ no, already resolved 26128: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2613 EXPORT_PC() @ resolve() could throw 2614 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2615 bl dvmResolveInstField @ r0<- resolved InstField ptr 2616 cmp r0, #0 @ success? 2617 bne .LOP_IPUT_BYTE_finish @ yes, finish up 2618 b common_exceptionThrown 2619 2620 2621/* ------------------------------ */ 2622 .balign 64 2623.L_OP_IPUT_CHAR: /* 0x5e */ 2624/* File: armv5te/OP_IPUT_CHAR.S */ 2625@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" } 2626/* File: armv5te/OP_IPUT.S */ 2627 /* 2628 * General 32-bit instance field put. 2629 * 2630 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2631 */ 2632 /* op vA, vB, field@CCCC */ 2633 mov r0, rINST, lsr #12 @ r0<- B 2634 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2635 FETCH(r1, 1) @ r1<- field ref CCCC 2636 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2637 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2638 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2639 cmp r0, #0 @ is resolved entry null? 2640 bne .LOP_IPUT_CHAR_finish @ no, already resolved 26418: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2642 EXPORT_PC() @ resolve() could throw 2643 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2644 bl dvmResolveInstField @ r0<- resolved InstField ptr 2645 cmp r0, #0 @ success? 2646 bne .LOP_IPUT_CHAR_finish @ yes, finish up 2647 b common_exceptionThrown 2648 2649 2650/* ------------------------------ */ 2651 .balign 64 2652.L_OP_IPUT_SHORT: /* 0x5f */ 2653/* File: armv5te/OP_IPUT_SHORT.S */ 2654@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" } 2655/* File: armv5te/OP_IPUT.S */ 2656 /* 2657 * General 32-bit instance field put. 2658 * 2659 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2660 */ 2661 /* op vA, vB, field@CCCC */ 2662 mov r0, rINST, lsr #12 @ r0<- B 2663 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2664 FETCH(r1, 1) @ r1<- field ref CCCC 2665 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2666 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2667 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2668 cmp r0, #0 @ is resolved entry null? 2669 bne .LOP_IPUT_SHORT_finish @ no, already resolved 26708: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2671 EXPORT_PC() @ resolve() could throw 2672 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2673 bl dvmResolveInstField @ r0<- resolved InstField ptr 2674 cmp r0, #0 @ success? 2675 bne .LOP_IPUT_SHORT_finish @ yes, finish up 2676 b common_exceptionThrown 2677 2678 2679/* ------------------------------ */ 2680 .balign 64 2681.L_OP_SGET: /* 0x60 */ 2682/* File: armv5te/OP_SGET.S */ 2683 /* 2684 * General 32-bit SGET handler. 2685 * 2686 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2687 */ 2688 /* op vAA, field@BBBB */ 2689 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2690 FETCH(r1, 1) @ r1<- field ref BBBB 2691 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2692 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2693 cmp r0, #0 @ is resolved entry null? 2694 beq .LOP_SGET_resolve @ yes, do resolve 2695.LOP_SGET_finish: @ field ptr in r0 2696 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2697 @ no-op @ acquiring load 2698 mov r2, rINST, lsr #8 @ r2<- AA 2699 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2700 SET_VREG(r1, r2) @ fp[AA]<- r1 2701 GET_INST_OPCODE(ip) @ extract opcode from rINST 2702 GOTO_OPCODE(ip) @ jump to next instruction 2703 2704/* ------------------------------ */ 2705 .balign 64 2706.L_OP_SGET_WIDE: /* 0x61 */ 2707/* File: armv5te/OP_SGET_WIDE.S */ 2708 /* 2709 * 64-bit SGET handler. 2710 */ 2711 /* sget-wide vAA, field@BBBB */ 2712 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2713 FETCH(r1, 1) @ r1<- field ref BBBB 2714 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2715 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2716 cmp r0, #0 @ is resolved entry null? 2717 beq .LOP_SGET_WIDE_resolve @ yes, do resolve 2718.LOP_SGET_WIDE_finish: 2719 mov r9, rINST, lsr #8 @ r9<- AA 2720 .if 0 2721 add r0, r0, #offStaticField_value @ r0<- pointer to data 2722 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 2723 .else 2724 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 2725 .endif 2726 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2727 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2728 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 2729 GET_INST_OPCODE(ip) @ extract opcode from rINST 2730 GOTO_OPCODE(ip) @ jump to next instruction 2731 2732/* ------------------------------ */ 2733 .balign 64 2734.L_OP_SGET_OBJECT: /* 0x62 */ 2735/* File: armv5te/OP_SGET_OBJECT.S */ 2736/* File: armv5te/OP_SGET.S */ 2737 /* 2738 * General 32-bit SGET handler. 2739 * 2740 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2741 */ 2742 /* op vAA, field@BBBB */ 2743 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2744 FETCH(r1, 1) @ r1<- field ref BBBB 2745 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2746 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2747 cmp r0, #0 @ is resolved entry null? 2748 beq .LOP_SGET_OBJECT_resolve @ yes, do resolve 2749.LOP_SGET_OBJECT_finish: @ field ptr in r0 2750 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2751 @ no-op @ acquiring load 2752 mov r2, rINST, lsr #8 @ r2<- AA 2753 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2754 SET_VREG(r1, r2) @ fp[AA]<- r1 2755 GET_INST_OPCODE(ip) @ extract opcode from rINST 2756 GOTO_OPCODE(ip) @ jump to next instruction 2757 2758 2759/* ------------------------------ */ 2760 .balign 64 2761.L_OP_SGET_BOOLEAN: /* 0x63 */ 2762/* File: armv5te/OP_SGET_BOOLEAN.S */ 2763/* File: armv5te/OP_SGET.S */ 2764 /* 2765 * General 32-bit SGET handler. 2766 * 2767 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2768 */ 2769 /* op vAA, field@BBBB */ 2770 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2771 FETCH(r1, 1) @ r1<- field ref BBBB 2772 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2773 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2774 cmp r0, #0 @ is resolved entry null? 2775 beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve 2776.LOP_SGET_BOOLEAN_finish: @ field ptr in r0 2777 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2778 @ no-op @ acquiring load 2779 mov r2, rINST, lsr #8 @ r2<- AA 2780 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2781 SET_VREG(r1, r2) @ fp[AA]<- r1 2782 GET_INST_OPCODE(ip) @ extract opcode from rINST 2783 GOTO_OPCODE(ip) @ jump to next instruction 2784 2785 2786/* ------------------------------ */ 2787 .balign 64 2788.L_OP_SGET_BYTE: /* 0x64 */ 2789/* File: armv5te/OP_SGET_BYTE.S */ 2790/* File: armv5te/OP_SGET.S */ 2791 /* 2792 * General 32-bit SGET handler. 2793 * 2794 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2795 */ 2796 /* op vAA, field@BBBB */ 2797 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2798 FETCH(r1, 1) @ r1<- field ref BBBB 2799 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2800 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2801 cmp r0, #0 @ is resolved entry null? 2802 beq .LOP_SGET_BYTE_resolve @ yes, do resolve 2803.LOP_SGET_BYTE_finish: @ field ptr in r0 2804 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2805 @ no-op @ acquiring load 2806 mov r2, rINST, lsr #8 @ r2<- AA 2807 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2808 SET_VREG(r1, r2) @ fp[AA]<- r1 2809 GET_INST_OPCODE(ip) @ extract opcode from rINST 2810 GOTO_OPCODE(ip) @ jump to next instruction 2811 2812 2813/* ------------------------------ */ 2814 .balign 64 2815.L_OP_SGET_CHAR: /* 0x65 */ 2816/* File: armv5te/OP_SGET_CHAR.S */ 2817/* File: armv5te/OP_SGET.S */ 2818 /* 2819 * General 32-bit SGET handler. 2820 * 2821 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2822 */ 2823 /* op vAA, field@BBBB */ 2824 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2825 FETCH(r1, 1) @ r1<- field ref BBBB 2826 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2827 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2828 cmp r0, #0 @ is resolved entry null? 2829 beq .LOP_SGET_CHAR_resolve @ yes, do resolve 2830.LOP_SGET_CHAR_finish: @ field ptr in r0 2831 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2832 @ no-op @ acquiring load 2833 mov r2, rINST, lsr #8 @ r2<- AA 2834 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2835 SET_VREG(r1, r2) @ fp[AA]<- r1 2836 GET_INST_OPCODE(ip) @ extract opcode from rINST 2837 GOTO_OPCODE(ip) @ jump to next instruction 2838 2839 2840/* ------------------------------ */ 2841 .balign 64 2842.L_OP_SGET_SHORT: /* 0x66 */ 2843/* File: armv5te/OP_SGET_SHORT.S */ 2844/* File: armv5te/OP_SGET.S */ 2845 /* 2846 * General 32-bit SGET handler. 2847 * 2848 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2849 */ 2850 /* op vAA, field@BBBB */ 2851 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2852 FETCH(r1, 1) @ r1<- field ref BBBB 2853 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2854 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2855 cmp r0, #0 @ is resolved entry null? 2856 beq .LOP_SGET_SHORT_resolve @ yes, do resolve 2857.LOP_SGET_SHORT_finish: @ field ptr in r0 2858 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2859 @ no-op @ acquiring load 2860 mov r2, rINST, lsr #8 @ r2<- AA 2861 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2862 SET_VREG(r1, r2) @ fp[AA]<- r1 2863 GET_INST_OPCODE(ip) @ extract opcode from rINST 2864 GOTO_OPCODE(ip) @ jump to next instruction 2865 2866 2867/* ------------------------------ */ 2868 .balign 64 2869.L_OP_SPUT: /* 0x67 */ 2870/* File: armv5te/OP_SPUT.S */ 2871 /* 2872 * General 32-bit SPUT handler. 2873 * 2874 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2875 */ 2876 /* op vAA, field@BBBB */ 2877 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2878 FETCH(r1, 1) @ r1<- field ref BBBB 2879 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2880 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2881 cmp r0, #0 @ is resolved entry null? 2882 beq .LOP_SPUT_resolve @ yes, do resolve 2883.LOP_SPUT_finish: @ field ptr in r0 2884 mov r2, rINST, lsr #8 @ r2<- AA 2885 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2886 GET_VREG(r1, r2) @ r1<- fp[AA] 2887 GET_INST_OPCODE(ip) @ extract opcode from rINST 2888 @ no-op @ releasing store 2889 str r1, [r0, #offStaticField_value] @ field<- vAA 2890 @ no-op 2891 GOTO_OPCODE(ip) @ jump to next instruction 2892 2893/* ------------------------------ */ 2894 .balign 64 2895.L_OP_SPUT_WIDE: /* 0x68 */ 2896/* File: armv5te/OP_SPUT_WIDE.S */ 2897 /* 2898 * 64-bit SPUT handler. 2899 */ 2900 /* sput-wide vAA, field@BBBB */ 2901 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- DvmDex 2902 FETCH(r1, 1) @ r1<- field ref BBBB 2903 ldr r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2904 mov r9, rINST, lsr #8 @ r9<- AA 2905 ldr r2, [r10, r1, lsl #2] @ r2<- resolved StaticField ptr 2906 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2907 cmp r2, #0 @ is resolved entry null? 2908 beq .LOP_SPUT_WIDE_resolve @ yes, do resolve 2909.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9 2910 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2911 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 2912 GET_INST_OPCODE(r10) @ extract opcode from rINST 2913 .if 0 2914 add r2, r2, #offStaticField_value @ r2<- pointer to data 2915 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 2916 .else 2917 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 2918 .endif 2919 GOTO_OPCODE(r10) @ jump to next instruction 2920 2921/* ------------------------------ */ 2922 .balign 64 2923.L_OP_SPUT_OBJECT: /* 0x69 */ 2924/* File: armv5te/OP_SPUT_OBJECT.S */ 2925 /* 2926 * 32-bit SPUT handler for objects 2927 * 2928 * for: sput-object, sput-object-volatile 2929 */ 2930 /* op vAA, field@BBBB */ 2931 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2932 FETCH(r1, 1) @ r1<- field ref BBBB 2933 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2934 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2935 cmp r0, #0 @ is resolved entry null? 2936 beq .LOP_SPUT_OBJECT_resolve @ yes, do resolve 2937.LOP_SPUT_OBJECT_finish: @ field ptr in r0 2938 mov r2, rINST, lsr #8 @ r2<- AA 2939 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2940 GET_VREG(r1, r2) @ r1<- fp[AA] 2941 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 2942 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 2943 GET_INST_OPCODE(ip) @ extract opcode from rINST 2944 @ no-op @ releasing store 2945 b .LOP_SPUT_OBJECT_end 2946 2947/* ------------------------------ */ 2948 .balign 64 2949.L_OP_SPUT_BOOLEAN: /* 0x6a */ 2950/* File: armv5te/OP_SPUT_BOOLEAN.S */ 2951/* File: armv5te/OP_SPUT.S */ 2952 /* 2953 * General 32-bit SPUT handler. 2954 * 2955 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2956 */ 2957 /* op vAA, field@BBBB */ 2958 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2959 FETCH(r1, 1) @ r1<- field ref BBBB 2960 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2961 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2962 cmp r0, #0 @ is resolved entry null? 2963 beq .LOP_SPUT_BOOLEAN_resolve @ yes, do resolve 2964.LOP_SPUT_BOOLEAN_finish: @ field ptr in r0 2965 mov r2, rINST, lsr #8 @ r2<- AA 2966 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2967 GET_VREG(r1, r2) @ r1<- fp[AA] 2968 GET_INST_OPCODE(ip) @ extract opcode from rINST 2969 @ no-op @ releasing store 2970 str r1, [r0, #offStaticField_value] @ field<- vAA 2971 @ no-op 2972 GOTO_OPCODE(ip) @ jump to next instruction 2973 2974 2975/* ------------------------------ */ 2976 .balign 64 2977.L_OP_SPUT_BYTE: /* 0x6b */ 2978/* File: armv5te/OP_SPUT_BYTE.S */ 2979/* File: armv5te/OP_SPUT.S */ 2980 /* 2981 * General 32-bit SPUT handler. 2982 * 2983 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2984 */ 2985 /* op vAA, field@BBBB */ 2986 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2987 FETCH(r1, 1) @ r1<- field ref BBBB 2988 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 2989 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 2990 cmp r0, #0 @ is resolved entry null? 2991 beq .LOP_SPUT_BYTE_resolve @ yes, do resolve 2992.LOP_SPUT_BYTE_finish: @ field ptr in r0 2993 mov r2, rINST, lsr #8 @ r2<- AA 2994 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2995 GET_VREG(r1, r2) @ r1<- fp[AA] 2996 GET_INST_OPCODE(ip) @ extract opcode from rINST 2997 @ no-op @ releasing store 2998 str r1, [r0, #offStaticField_value] @ field<- vAA 2999 @ no-op 3000 GOTO_OPCODE(ip) @ jump to next instruction 3001 3002 3003/* ------------------------------ */ 3004 .balign 64 3005.L_OP_SPUT_CHAR: /* 0x6c */ 3006/* File: armv5te/OP_SPUT_CHAR.S */ 3007/* File: armv5te/OP_SPUT.S */ 3008 /* 3009 * General 32-bit SPUT handler. 3010 * 3011 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3012 */ 3013 /* op vAA, field@BBBB */ 3014 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3015 FETCH(r1, 1) @ r1<- field ref BBBB 3016 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 3017 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 3018 cmp r0, #0 @ is resolved entry null? 3019 beq .LOP_SPUT_CHAR_resolve @ yes, do resolve 3020.LOP_SPUT_CHAR_finish: @ field ptr in r0 3021 mov r2, rINST, lsr #8 @ r2<- AA 3022 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3023 GET_VREG(r1, r2) @ r1<- fp[AA] 3024 GET_INST_OPCODE(ip) @ extract opcode from rINST 3025 @ no-op @ releasing store 3026 str r1, [r0, #offStaticField_value] @ field<- vAA 3027 @ no-op 3028 GOTO_OPCODE(ip) @ jump to next instruction 3029 3030 3031/* ------------------------------ */ 3032 .balign 64 3033.L_OP_SPUT_SHORT: /* 0x6d */ 3034/* File: armv5te/OP_SPUT_SHORT.S */ 3035/* File: armv5te/OP_SPUT.S */ 3036 /* 3037 * General 32-bit SPUT handler. 3038 * 3039 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3040 */ 3041 /* op vAA, field@BBBB */ 3042 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3043 FETCH(r1, 1) @ r1<- field ref BBBB 3044 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 3045 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 3046 cmp r0, #0 @ is resolved entry null? 3047 beq .LOP_SPUT_SHORT_resolve @ yes, do resolve 3048.LOP_SPUT_SHORT_finish: @ field ptr in r0 3049 mov r2, rINST, lsr #8 @ r2<- AA 3050 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3051 GET_VREG(r1, r2) @ r1<- fp[AA] 3052 GET_INST_OPCODE(ip) @ extract opcode from rINST 3053 @ no-op @ releasing store 3054 str r1, [r0, #offStaticField_value] @ field<- vAA 3055 @ no-op 3056 GOTO_OPCODE(ip) @ jump to next instruction 3057 3058 3059/* ------------------------------ */ 3060 .balign 64 3061.L_OP_INVOKE_VIRTUAL: /* 0x6e */ 3062/* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3063 /* 3064 * Handle a virtual method call. 3065 * 3066 * for: invoke-virtual, invoke-virtual/range 3067 */ 3068 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3069 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3070 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3071 FETCH(r1, 1) @ r1<- BBBB 3072 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3073 FETCH(r10, 2) @ r10<- GFED or CCCC 3074 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3075 .if (!0) 3076 and r10, r10, #15 @ r10<- D (or stays CCCC) 3077 .endif 3078 cmp r0, #0 @ already resolved? 3079 EXPORT_PC() @ must export for invoke 3080 bne .LOP_INVOKE_VIRTUAL_continue @ yes, continue on 3081 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3082 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3083 mov r2, #METHOD_VIRTUAL @ resolver method type 3084 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3085 cmp r0, #0 @ got null? 3086 bne .LOP_INVOKE_VIRTUAL_continue @ no, continue 3087 b common_exceptionThrown @ yes, handle exception 3088 3089/* ------------------------------ */ 3090 .balign 64 3091.L_OP_INVOKE_SUPER: /* 0x6f */ 3092/* File: armv5te/OP_INVOKE_SUPER.S */ 3093 /* 3094 * Handle a "super" method call. 3095 * 3096 * for: invoke-super, invoke-super/range 3097 */ 3098 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3099 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3100 FETCH(r10, 2) @ r10<- GFED or CCCC 3101 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3102 .if (!0) 3103 and r10, r10, #15 @ r10<- D (or stays CCCC) 3104 .endif 3105 FETCH(r1, 1) @ r1<- BBBB 3106 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3107 GET_VREG(r9, r10) @ r9<- "this" ptr 3108 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3109 cmp r9, #0 @ null "this"? 3110 ldr r10, [rSELF, #offThread_method] @ r10<- current method 3111 beq common_errNullObject @ null "this", throw exception 3112 cmp r0, #0 @ already resolved? 3113 ldr r10, [r10, #offMethod_clazz] @ r10<- method->clazz 3114 EXPORT_PC() @ must export for invoke 3115 bne .LOP_INVOKE_SUPER_continue @ resolved, continue on 3116 b .LOP_INVOKE_SUPER_resolve @ do resolve now 3117 3118/* ------------------------------ */ 3119 .balign 64 3120.L_OP_INVOKE_DIRECT: /* 0x70 */ 3121/* File: armv5te/OP_INVOKE_DIRECT.S */ 3122 /* 3123 * Handle a direct method call. 3124 * 3125 * (We could defer the "is 'this' pointer null" test to the common 3126 * method invocation code, and use a flag to indicate that static 3127 * calls don't count. If we do this as part of copying the arguments 3128 * out we could avoiding loading the first arg twice.) 3129 * 3130 * for: invoke-direct, invoke-direct/range 3131 */ 3132 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3133 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3134 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3135 FETCH(r1, 1) @ r1<- BBBB 3136 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3137 FETCH(r10, 2) @ r10<- GFED or CCCC 3138 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3139 .if (!0) 3140 and r10, r10, #15 @ r10<- D (or stays CCCC) 3141 .endif 3142 cmp r0, #0 @ already resolved? 3143 EXPORT_PC() @ must export for invoke 3144 GET_VREG(r9, r10) @ r9<- "this" ptr 3145 beq .LOP_INVOKE_DIRECT_resolve @ not resolved, do it now 3146.LOP_INVOKE_DIRECT_finish: 3147 cmp r9, #0 @ null "this" ref? 3148 bne common_invokeMethodNoRange @ r0=method, r9="this" 3149 b common_errNullObject @ yes, throw exception 3150 3151/* ------------------------------ */ 3152 .balign 64 3153.L_OP_INVOKE_STATIC: /* 0x71 */ 3154/* File: armv5te/OP_INVOKE_STATIC.S */ 3155 /* 3156 * Handle a static method call. 3157 * 3158 * for: invoke-static, invoke-static/range 3159 */ 3160 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3161 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3162 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3163 FETCH(r1, 1) @ r1<- BBBB 3164 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3165 mov r9, #0 @ null "this" in delay slot 3166 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3167#if defined(WITH_JIT) 3168 add r10, r3, r1, lsl #2 @ r10<- &resolved_methodToCall 3169#endif 3170 cmp r0, #0 @ already resolved? 3171 EXPORT_PC() @ must export for invoke 3172 bne common_invokeMethodNoRange @ yes, continue on 3173 b .LOP_INVOKE_STATIC_resolve 3174 3175/* ------------------------------ */ 3176 .balign 64 3177.L_OP_INVOKE_INTERFACE: /* 0x72 */ 3178/* File: armv5te/OP_INVOKE_INTERFACE.S */ 3179 /* 3180 * Handle an interface method call. 3181 * 3182 * for: invoke-interface, invoke-interface/range 3183 */ 3184 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3185 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3186 FETCH(r2, 2) @ r2<- FEDC or CCCC 3187 FETCH(r1, 1) @ r1<- BBBB 3188 .if (!0) 3189 and r2, r2, #15 @ r2<- C (or stays CCCC) 3190 .endif 3191 EXPORT_PC() @ must export for invoke 3192 GET_VREG(r9, r2) @ r9<- first arg ("this") 3193 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- methodClassDex 3194 cmp r9, #0 @ null obj? 3195 ldr r2, [rSELF, #offThread_method] @ r2<- method 3196 beq common_errNullObject @ yes, fail 3197 ldr r0, [r9, #offObject_clazz] @ r0<- thisPtr->clazz 3198 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3199 cmp r0, #0 @ failed? 3200 beq common_exceptionThrown @ yes, handle exception 3201 b common_invokeMethodNoRange @ (r0=method, r9="this") 3202 3203/* ------------------------------ */ 3204 .balign 64 3205.L_OP_UNUSED_73: /* 0x73 */ 3206/* File: armv5te/OP_UNUSED_73.S */ 3207/* File: armv5te/unused.S */ 3208 bl common_abort 3209 3210 3211/* ------------------------------ */ 3212 .balign 64 3213.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 3214/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */ 3215/* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3216 /* 3217 * Handle a virtual method call. 3218 * 3219 * for: invoke-virtual, invoke-virtual/range 3220 */ 3221 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3222 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3223 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3224 FETCH(r1, 1) @ r1<- BBBB 3225 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3226 FETCH(r10, 2) @ r10<- GFED or CCCC 3227 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3228 .if (!1) 3229 and r10, r10, #15 @ r10<- D (or stays CCCC) 3230 .endif 3231 cmp r0, #0 @ already resolved? 3232 EXPORT_PC() @ must export for invoke 3233 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ yes, continue on 3234 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3235 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3236 mov r2, #METHOD_VIRTUAL @ resolver method type 3237 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3238 cmp r0, #0 @ got null? 3239 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ no, continue 3240 b common_exceptionThrown @ yes, handle exception 3241 3242 3243/* ------------------------------ */ 3244 .balign 64 3245.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 3246/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */ 3247/* File: armv5te/OP_INVOKE_SUPER.S */ 3248 /* 3249 * Handle a "super" method call. 3250 * 3251 * for: invoke-super, invoke-super/range 3252 */ 3253 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3254 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3255 FETCH(r10, 2) @ r10<- GFED or CCCC 3256 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3257 .if (!1) 3258 and r10, r10, #15 @ r10<- D (or stays CCCC) 3259 .endif 3260 FETCH(r1, 1) @ r1<- BBBB 3261 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3262 GET_VREG(r9, r10) @ r9<- "this" ptr 3263 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3264 cmp r9, #0 @ null "this"? 3265 ldr r10, [rSELF, #offThread_method] @ r10<- current method 3266 beq common_errNullObject @ null "this", throw exception 3267 cmp r0, #0 @ already resolved? 3268 ldr r10, [r10, #offMethod_clazz] @ r10<- method->clazz 3269 EXPORT_PC() @ must export for invoke 3270 bne .LOP_INVOKE_SUPER_RANGE_continue @ resolved, continue on 3271 b .LOP_INVOKE_SUPER_RANGE_resolve @ do resolve now 3272 3273 3274/* ------------------------------ */ 3275 .balign 64 3276.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 3277/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */ 3278/* File: armv5te/OP_INVOKE_DIRECT.S */ 3279 /* 3280 * Handle a direct method call. 3281 * 3282 * (We could defer the "is 'this' pointer null" test to the common 3283 * method invocation code, and use a flag to indicate that static 3284 * calls don't count. If we do this as part of copying the arguments 3285 * out we could avoiding loading the first arg twice.) 3286 * 3287 * for: invoke-direct, invoke-direct/range 3288 */ 3289 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3290 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3291 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3292 FETCH(r1, 1) @ r1<- BBBB 3293 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3294 FETCH(r10, 2) @ r10<- GFED or CCCC 3295 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3296 .if (!1) 3297 and r10, r10, #15 @ r10<- D (or stays CCCC) 3298 .endif 3299 cmp r0, #0 @ already resolved? 3300 EXPORT_PC() @ must export for invoke 3301 GET_VREG(r9, r10) @ r9<- "this" ptr 3302 beq .LOP_INVOKE_DIRECT_RANGE_resolve @ not resolved, do it now 3303.LOP_INVOKE_DIRECT_RANGE_finish: 3304 cmp r9, #0 @ null "this" ref? 3305 bne common_invokeMethodRange @ r0=method, r9="this" 3306 b common_errNullObject @ yes, throw exception 3307 3308 3309/* ------------------------------ */ 3310 .balign 64 3311.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 3312/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */ 3313/* File: armv5te/OP_INVOKE_STATIC.S */ 3314 /* 3315 * Handle a static method call. 3316 * 3317 * for: invoke-static, invoke-static/range 3318 */ 3319 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3320 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3321 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3322 FETCH(r1, 1) @ r1<- BBBB 3323 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3324 mov r9, #0 @ null "this" in delay slot 3325 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3326#if defined(WITH_JIT) 3327 add r10, r3, r1, lsl #2 @ r10<- &resolved_methodToCall 3328#endif 3329 cmp r0, #0 @ already resolved? 3330 EXPORT_PC() @ must export for invoke 3331 bne common_invokeMethodRange @ yes, continue on 3332 b .LOP_INVOKE_STATIC_RANGE_resolve 3333 3334 3335/* ------------------------------ */ 3336 .balign 64 3337.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 3338/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */ 3339/* File: armv5te/OP_INVOKE_INTERFACE.S */ 3340 /* 3341 * Handle an interface method call. 3342 * 3343 * for: invoke-interface, invoke-interface/range 3344 */ 3345 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3346 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3347 FETCH(r2, 2) @ r2<- FEDC or CCCC 3348 FETCH(r1, 1) @ r1<- BBBB 3349 .if (!1) 3350 and r2, r2, #15 @ r2<- C (or stays CCCC) 3351 .endif 3352 EXPORT_PC() @ must export for invoke 3353 GET_VREG(r9, r2) @ r9<- first arg ("this") 3354 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- methodClassDex 3355 cmp r9, #0 @ null obj? 3356 ldr r2, [rSELF, #offThread_method] @ r2<- method 3357 beq common_errNullObject @ yes, fail 3358 ldr r0, [r9, #offObject_clazz] @ r0<- thisPtr->clazz 3359 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3360 cmp r0, #0 @ failed? 3361 beq common_exceptionThrown @ yes, handle exception 3362 b common_invokeMethodRange @ (r0=method, r9="this") 3363 3364 3365/* ------------------------------ */ 3366 .balign 64 3367.L_OP_UNUSED_79: /* 0x79 */ 3368/* File: armv5te/OP_UNUSED_79.S */ 3369/* File: armv5te/unused.S */ 3370 bl common_abort 3371 3372 3373/* ------------------------------ */ 3374 .balign 64 3375.L_OP_UNUSED_7A: /* 0x7a */ 3376/* File: armv5te/OP_UNUSED_7A.S */ 3377/* File: armv5te/unused.S */ 3378 bl common_abort 3379 3380 3381/* ------------------------------ */ 3382 .balign 64 3383.L_OP_NEG_INT: /* 0x7b */ 3384/* File: armv5te/OP_NEG_INT.S */ 3385/* File: armv5te/unop.S */ 3386 /* 3387 * Generic 32-bit unary operation. Provide an "instr" line that 3388 * specifies an instruction that performs "result = op r0". 3389 * This could be an ARM instruction or a function call. 3390 * 3391 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3392 * int-to-byte, int-to-char, int-to-short 3393 */ 3394 /* unop vA, vB */ 3395 mov r3, rINST, lsr #12 @ r3<- B 3396 mov r9, rINST, lsr #8 @ r9<- A+ 3397 GET_VREG(r0, r3) @ r0<- vB 3398 and r9, r9, #15 3399 @ optional op; may set condition codes 3400 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3401 rsb r0, r0, #0 @ r0<- op, r0-r3 changed 3402 GET_INST_OPCODE(ip) @ extract opcode from rINST 3403 SET_VREG(r0, r9) @ vAA<- r0 3404 GOTO_OPCODE(ip) @ jump to next instruction 3405 /* 9-10 instructions */ 3406 3407 3408/* ------------------------------ */ 3409 .balign 64 3410.L_OP_NOT_INT: /* 0x7c */ 3411/* File: armv5te/OP_NOT_INT.S */ 3412/* File: armv5te/unop.S */ 3413 /* 3414 * Generic 32-bit unary operation. Provide an "instr" line that 3415 * specifies an instruction that performs "result = op r0". 3416 * This could be an ARM instruction or a function call. 3417 * 3418 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3419 * int-to-byte, int-to-char, int-to-short 3420 */ 3421 /* unop vA, vB */ 3422 mov r3, rINST, lsr #12 @ r3<- B 3423 mov r9, rINST, lsr #8 @ r9<- A+ 3424 GET_VREG(r0, r3) @ r0<- vB 3425 and r9, r9, #15 3426 @ optional op; may set condition codes 3427 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3428 mvn r0, r0 @ r0<- op, r0-r3 changed 3429 GET_INST_OPCODE(ip) @ extract opcode from rINST 3430 SET_VREG(r0, r9) @ vAA<- r0 3431 GOTO_OPCODE(ip) @ jump to next instruction 3432 /* 9-10 instructions */ 3433 3434 3435/* ------------------------------ */ 3436 .balign 64 3437.L_OP_NEG_LONG: /* 0x7d */ 3438/* File: armv5te/OP_NEG_LONG.S */ 3439/* File: armv5te/unopWide.S */ 3440 /* 3441 * Generic 64-bit unary operation. Provide an "instr" line that 3442 * specifies an instruction that performs "result = op r0/r1". 3443 * This could be an ARM instruction or a function call. 3444 * 3445 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3446 */ 3447 /* unop vA, vB */ 3448 mov r9, rINST, lsr #8 @ r9<- A+ 3449 mov r3, rINST, lsr #12 @ r3<- B 3450 and r9, r9, #15 3451 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3452 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3453 ldmia r3, {r0-r1} @ r0/r1<- vAA 3454 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3455 rsbs r0, r0, #0 @ optional op; may set condition codes 3456 rsc r1, r1, #0 @ r0/r1<- op, r2-r3 changed 3457 GET_INST_OPCODE(ip) @ extract opcode from rINST 3458 stmia r9, {r0-r1} @ vAA<- r0/r1 3459 GOTO_OPCODE(ip) @ jump to next instruction 3460 /* 12-13 instructions */ 3461 3462 3463/* ------------------------------ */ 3464 .balign 64 3465.L_OP_NOT_LONG: /* 0x7e */ 3466/* File: armv5te/OP_NOT_LONG.S */ 3467/* File: armv5te/unopWide.S */ 3468 /* 3469 * Generic 64-bit unary operation. Provide an "instr" line that 3470 * specifies an instruction that performs "result = op r0/r1". 3471 * This could be an ARM instruction or a function call. 3472 * 3473 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3474 */ 3475 /* unop vA, vB */ 3476 mov r9, rINST, lsr #8 @ r9<- A+ 3477 mov r3, rINST, lsr #12 @ r3<- B 3478 and r9, r9, #15 3479 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3480 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3481 ldmia r3, {r0-r1} @ r0/r1<- vAA 3482 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3483 mvn r0, r0 @ optional op; may set condition codes 3484 mvn r1, r1 @ r0/r1<- op, r2-r3 changed 3485 GET_INST_OPCODE(ip) @ extract opcode from rINST 3486 stmia r9, {r0-r1} @ vAA<- r0/r1 3487 GOTO_OPCODE(ip) @ jump to next instruction 3488 /* 12-13 instructions */ 3489 3490 3491/* ------------------------------ */ 3492 .balign 64 3493.L_OP_NEG_FLOAT: /* 0x7f */ 3494/* File: armv5te/OP_NEG_FLOAT.S */ 3495/* File: armv5te/unop.S */ 3496 /* 3497 * Generic 32-bit unary operation. Provide an "instr" line that 3498 * specifies an instruction that performs "result = op r0". 3499 * This could be an ARM instruction or a function call. 3500 * 3501 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3502 * int-to-byte, int-to-char, int-to-short 3503 */ 3504 /* unop vA, vB */ 3505 mov r3, rINST, lsr #12 @ r3<- B 3506 mov r9, rINST, lsr #8 @ r9<- A+ 3507 GET_VREG(r0, r3) @ r0<- vB 3508 and r9, r9, #15 3509 @ optional op; may set condition codes 3510 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3511 add r0, r0, #0x80000000 @ r0<- op, r0-r3 changed 3512 GET_INST_OPCODE(ip) @ extract opcode from rINST 3513 SET_VREG(r0, r9) @ vAA<- r0 3514 GOTO_OPCODE(ip) @ jump to next instruction 3515 /* 9-10 instructions */ 3516 3517 3518/* ------------------------------ */ 3519 .balign 64 3520.L_OP_NEG_DOUBLE: /* 0x80 */ 3521/* File: armv5te/OP_NEG_DOUBLE.S */ 3522/* File: armv5te/unopWide.S */ 3523 /* 3524 * Generic 64-bit unary operation. Provide an "instr" line that 3525 * specifies an instruction that performs "result = op r0/r1". 3526 * This could be an ARM instruction or a function call. 3527 * 3528 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3529 */ 3530 /* unop vA, vB */ 3531 mov r9, rINST, lsr #8 @ r9<- A+ 3532 mov r3, rINST, lsr #12 @ r3<- B 3533 and r9, r9, #15 3534 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3535 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3536 ldmia r3, {r0-r1} @ r0/r1<- vAA 3537 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3538 @ optional op; may set condition codes 3539 add r1, r1, #0x80000000 @ r0/r1<- op, r2-r3 changed 3540 GET_INST_OPCODE(ip) @ extract opcode from rINST 3541 stmia r9, {r0-r1} @ vAA<- r0/r1 3542 GOTO_OPCODE(ip) @ jump to next instruction 3543 /* 12-13 instructions */ 3544 3545 3546/* ------------------------------ */ 3547 .balign 64 3548.L_OP_INT_TO_LONG: /* 0x81 */ 3549/* File: armv5te/OP_INT_TO_LONG.S */ 3550/* File: armv5te/unopWider.S */ 3551 /* 3552 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3553 * that specifies an instruction that performs "result = op r0", where 3554 * "result" is a 64-bit quantity in r0/r1. 3555 * 3556 * For: int-to-long, int-to-double, float-to-long, float-to-double 3557 */ 3558 /* unop vA, vB */ 3559 mov r9, rINST, lsr #8 @ r9<- A+ 3560 mov r3, rINST, lsr #12 @ r3<- B 3561 and r9, r9, #15 3562 GET_VREG(r0, r3) @ r0<- vB 3563 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3564 @ optional op; may set condition codes 3565 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3566 mov r1, r0, asr #31 @ r0<- op, r0-r3 changed 3567 GET_INST_OPCODE(ip) @ extract opcode from rINST 3568 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3569 GOTO_OPCODE(ip) @ jump to next instruction 3570 /* 10-11 instructions */ 3571 3572 3573/* ------------------------------ */ 3574 .balign 64 3575.L_OP_INT_TO_FLOAT: /* 0x82 */ 3576/* File: arm-vfp/OP_INT_TO_FLOAT.S */ 3577/* File: arm-vfp/funop.S */ 3578 /* 3579 * Generic 32-bit unary floating-point operation. Provide an "instr" 3580 * line that specifies an instruction that performs "s1 = op s0". 3581 * 3582 * for: int-to-float, float-to-int 3583 */ 3584 /* unop vA, vB */ 3585 mov r3, rINST, lsr #12 @ r3<- B 3586 mov r9, rINST, lsr #8 @ r9<- A+ 3587 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3588 flds s0, [r3] @ s0<- vB 3589 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3590 and r9, r9, #15 @ r9<- A 3591 fsitos s1, s0 @ s1<- op 3592 GET_INST_OPCODE(ip) @ extract opcode from rINST 3593 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3594 fsts s1, [r9] @ vA<- s1 3595 GOTO_OPCODE(ip) @ jump to next instruction 3596 3597 3598/* ------------------------------ */ 3599 .balign 64 3600.L_OP_INT_TO_DOUBLE: /* 0x83 */ 3601/* File: arm-vfp/OP_INT_TO_DOUBLE.S */ 3602/* File: arm-vfp/funopWider.S */ 3603 /* 3604 * Generic 32bit-to-64bit floating point unary operation. Provide an 3605 * "instr" line that specifies an instruction that performs "d0 = op s0". 3606 * 3607 * For: int-to-double, float-to-double 3608 */ 3609 /* unop vA, vB */ 3610 mov r3, rINST, lsr #12 @ r3<- B 3611 mov r9, rINST, lsr #8 @ r9<- A+ 3612 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3613 flds s0, [r3] @ s0<- vB 3614 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3615 and r9, r9, #15 @ r9<- A 3616 fsitod d0, s0 @ d0<- op 3617 GET_INST_OPCODE(ip) @ extract opcode from rINST 3618 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3619 fstd d0, [r9] @ vA<- d0 3620 GOTO_OPCODE(ip) @ jump to next instruction 3621 3622 3623/* ------------------------------ */ 3624 .balign 64 3625.L_OP_LONG_TO_INT: /* 0x84 */ 3626/* File: armv5te/OP_LONG_TO_INT.S */ 3627/* we ignore the high word, making this equivalent to a 32-bit reg move */ 3628/* File: armv5te/OP_MOVE.S */ 3629 /* for move, move-object, long-to-int */ 3630 /* op vA, vB */ 3631 mov r1, rINST, lsr #12 @ r1<- B from 15:12 3632 mov r0, rINST, lsr #8 @ r0<- A from 11:8 3633 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3634 GET_VREG(r2, r1) @ r2<- fp[B] 3635 and r0, r0, #15 3636 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 3637 SET_VREG(r2, r0) @ fp[A]<- r2 3638 GOTO_OPCODE(ip) @ execute next instruction 3639 3640 3641/* ------------------------------ */ 3642 .balign 64 3643.L_OP_LONG_TO_FLOAT: /* 0x85 */ 3644/* File: armv5te/OP_LONG_TO_FLOAT.S */ 3645/* File: armv5te/unopNarrower.S */ 3646 /* 3647 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 3648 * that specifies an instruction that performs "result = op r0/r1", where 3649 * "result" is a 32-bit quantity in r0. 3650 * 3651 * For: long-to-float, double-to-int, double-to-float 3652 * 3653 * (This would work for long-to-int, but that instruction is actually 3654 * an exact match for OP_MOVE.) 3655 */ 3656 /* unop vA, vB */ 3657 mov r3, rINST, lsr #12 @ r3<- B 3658 mov r9, rINST, lsr #8 @ r9<- A+ 3659 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3660 and r9, r9, #15 3661 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 3662 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3663 @ optional op; may set condition codes 3664 bl __aeabi_l2f @ r0<- op, r0-r3 changed 3665 GET_INST_OPCODE(ip) @ extract opcode from rINST 3666 SET_VREG(r0, r9) @ vA<- r0 3667 GOTO_OPCODE(ip) @ jump to next instruction 3668 /* 10-11 instructions */ 3669 3670 3671/* ------------------------------ */ 3672 .balign 64 3673.L_OP_LONG_TO_DOUBLE: /* 0x86 */ 3674/* File: armv5te/OP_LONG_TO_DOUBLE.S */ 3675/* File: armv5te/unopWide.S */ 3676 /* 3677 * Generic 64-bit unary operation. Provide an "instr" line that 3678 * specifies an instruction that performs "result = op r0/r1". 3679 * This could be an ARM instruction or a function call. 3680 * 3681 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3682 */ 3683 /* unop vA, vB */ 3684 mov r9, rINST, lsr #8 @ r9<- A+ 3685 mov r3, rINST, lsr #12 @ r3<- B 3686 and r9, r9, #15 3687 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3688 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3689 ldmia r3, {r0-r1} @ r0/r1<- vAA 3690 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3691 @ optional op; may set condition codes 3692 bl __aeabi_l2d @ r0/r1<- op, r2-r3 changed 3693 GET_INST_OPCODE(ip) @ extract opcode from rINST 3694 stmia r9, {r0-r1} @ vAA<- r0/r1 3695 GOTO_OPCODE(ip) @ jump to next instruction 3696 /* 12-13 instructions */ 3697 3698 3699/* ------------------------------ */ 3700 .balign 64 3701.L_OP_FLOAT_TO_INT: /* 0x87 */ 3702/* File: arm-vfp/OP_FLOAT_TO_INT.S */ 3703/* File: arm-vfp/funop.S */ 3704 /* 3705 * Generic 32-bit unary floating-point operation. Provide an "instr" 3706 * line that specifies an instruction that performs "s1 = op s0". 3707 * 3708 * for: int-to-float, float-to-int 3709 */ 3710 /* unop vA, vB */ 3711 mov r3, rINST, lsr #12 @ r3<- B 3712 mov r9, rINST, lsr #8 @ r9<- A+ 3713 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3714 flds s0, [r3] @ s0<- vB 3715 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3716 and r9, r9, #15 @ r9<- A 3717 ftosizs s1, s0 @ s1<- op 3718 GET_INST_OPCODE(ip) @ extract opcode from rINST 3719 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3720 fsts s1, [r9] @ vA<- s1 3721 GOTO_OPCODE(ip) @ jump to next instruction 3722 3723 3724/* ------------------------------ */ 3725 .balign 64 3726.L_OP_FLOAT_TO_LONG: /* 0x88 */ 3727/* File: armv5te/OP_FLOAT_TO_LONG.S */ 3728@include "armv5te/unopWider.S" {"instr":"bl __aeabi_f2lz"} 3729/* File: armv5te/unopWider.S */ 3730 /* 3731 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3732 * that specifies an instruction that performs "result = op r0", where 3733 * "result" is a 64-bit quantity in r0/r1. 3734 * 3735 * For: int-to-long, int-to-double, float-to-long, float-to-double 3736 */ 3737 /* unop vA, vB */ 3738 mov r9, rINST, lsr #8 @ r9<- A+ 3739 mov r3, rINST, lsr #12 @ r3<- B 3740 and r9, r9, #15 3741 GET_VREG(r0, r3) @ r0<- vB 3742 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3743 @ optional op; may set condition codes 3744 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3745 bl f2l_doconv @ r0<- op, r0-r3 changed 3746 GET_INST_OPCODE(ip) @ extract opcode from rINST 3747 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3748 GOTO_OPCODE(ip) @ jump to next instruction 3749 /* 10-11 instructions */ 3750 3751 3752 3753/* ------------------------------ */ 3754 .balign 64 3755.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 3756/* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */ 3757/* File: arm-vfp/funopWider.S */ 3758 /* 3759 * Generic 32bit-to-64bit floating point unary operation. Provide an 3760 * "instr" line that specifies an instruction that performs "d0 = op s0". 3761 * 3762 * For: int-to-double, float-to-double 3763 */ 3764 /* unop vA, vB */ 3765 mov r3, rINST, lsr #12 @ r3<- B 3766 mov r9, rINST, lsr #8 @ r9<- A+ 3767 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3768 flds s0, [r3] @ s0<- vB 3769 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3770 and r9, r9, #15 @ r9<- A 3771 fcvtds d0, s0 @ d0<- op 3772 GET_INST_OPCODE(ip) @ extract opcode from rINST 3773 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3774 fstd d0, [r9] @ vA<- d0 3775 GOTO_OPCODE(ip) @ jump to next instruction 3776 3777 3778/* ------------------------------ */ 3779 .balign 64 3780.L_OP_DOUBLE_TO_INT: /* 0x8a */ 3781/* File: arm-vfp/OP_DOUBLE_TO_INT.S */ 3782/* File: arm-vfp/funopNarrower.S */ 3783 /* 3784 * Generic 64bit-to-32bit unary floating point operation. Provide an 3785 * "instr" line that specifies an instruction that performs "s0 = op d0". 3786 * 3787 * For: double-to-int, double-to-float 3788 */ 3789 /* unop vA, vB */ 3790 mov r3, rINST, lsr #12 @ r3<- B 3791 mov r9, rINST, lsr #8 @ r9<- A+ 3792 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3793 fldd d0, [r3] @ d0<- vB 3794 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3795 and r9, r9, #15 @ r9<- A 3796 ftosizd s0, d0 @ s0<- op 3797 GET_INST_OPCODE(ip) @ extract opcode from rINST 3798 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3799 fsts s0, [r9] @ vA<- s0 3800 GOTO_OPCODE(ip) @ jump to next instruction 3801 3802 3803/* ------------------------------ */ 3804 .balign 64 3805.L_OP_DOUBLE_TO_LONG: /* 0x8b */ 3806/* File: armv5te/OP_DOUBLE_TO_LONG.S */ 3807@include "armv5te/unopWide.S" {"instr":"bl __aeabi_d2lz"} 3808/* File: armv5te/unopWide.S */ 3809 /* 3810 * Generic 64-bit unary operation. Provide an "instr" line that 3811 * specifies an instruction that performs "result = op r0/r1". 3812 * This could be an ARM instruction or a function call. 3813 * 3814 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3815 */ 3816 /* unop vA, vB */ 3817 mov r9, rINST, lsr #8 @ r9<- A+ 3818 mov r3, rINST, lsr #12 @ r3<- B 3819 and r9, r9, #15 3820 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3821 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3822 ldmia r3, {r0-r1} @ r0/r1<- vAA 3823 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3824 @ optional op; may set condition codes 3825 bl d2l_doconv @ r0/r1<- op, r2-r3 changed 3826 GET_INST_OPCODE(ip) @ extract opcode from rINST 3827 stmia r9, {r0-r1} @ vAA<- r0/r1 3828 GOTO_OPCODE(ip) @ jump to next instruction 3829 /* 12-13 instructions */ 3830 3831 3832 3833/* ------------------------------ */ 3834 .balign 64 3835.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 3836/* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */ 3837/* File: arm-vfp/funopNarrower.S */ 3838 /* 3839 * Generic 64bit-to-32bit unary floating point operation. Provide an 3840 * "instr" line that specifies an instruction that performs "s0 = op d0". 3841 * 3842 * For: double-to-int, double-to-float 3843 */ 3844 /* unop vA, vB */ 3845 mov r3, rINST, lsr #12 @ r3<- B 3846 mov r9, rINST, lsr #8 @ r9<- A+ 3847 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3848 fldd d0, [r3] @ d0<- vB 3849 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3850 and r9, r9, #15 @ r9<- A 3851 fcvtsd s0, d0 @ s0<- op 3852 GET_INST_OPCODE(ip) @ extract opcode from rINST 3853 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3854 fsts s0, [r9] @ vA<- s0 3855 GOTO_OPCODE(ip) @ jump to next instruction 3856 3857 3858/* ------------------------------ */ 3859 .balign 64 3860.L_OP_INT_TO_BYTE: /* 0x8d */ 3861/* File: armv5te/OP_INT_TO_BYTE.S */ 3862/* File: armv5te/unop.S */ 3863 /* 3864 * Generic 32-bit unary operation. Provide an "instr" line that 3865 * specifies an instruction that performs "result = op r0". 3866 * This could be an ARM instruction or a function call. 3867 * 3868 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3869 * int-to-byte, int-to-char, int-to-short 3870 */ 3871 /* unop vA, vB */ 3872 mov r3, rINST, lsr #12 @ r3<- B 3873 mov r9, rINST, lsr #8 @ r9<- A+ 3874 GET_VREG(r0, r3) @ r0<- vB 3875 and r9, r9, #15 3876 mov r0, r0, asl #24 @ optional op; may set condition codes 3877 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3878 mov r0, r0, asr #24 @ r0<- op, r0-r3 changed 3879 GET_INST_OPCODE(ip) @ extract opcode from rINST 3880 SET_VREG(r0, r9) @ vAA<- r0 3881 GOTO_OPCODE(ip) @ jump to next instruction 3882 /* 9-10 instructions */ 3883 3884 3885/* ------------------------------ */ 3886 .balign 64 3887.L_OP_INT_TO_CHAR: /* 0x8e */ 3888/* File: armv5te/OP_INT_TO_CHAR.S */ 3889/* File: armv5te/unop.S */ 3890 /* 3891 * Generic 32-bit unary operation. Provide an "instr" line that 3892 * specifies an instruction that performs "result = op r0". 3893 * This could be an ARM instruction or a function call. 3894 * 3895 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3896 * int-to-byte, int-to-char, int-to-short 3897 */ 3898 /* unop vA, vB */ 3899 mov r3, rINST, lsr #12 @ r3<- B 3900 mov r9, rINST, lsr #8 @ r9<- A+ 3901 GET_VREG(r0, r3) @ r0<- vB 3902 and r9, r9, #15 3903 mov r0, r0, asl #16 @ optional op; may set condition codes 3904 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3905 mov r0, r0, lsr #16 @ r0<- op, r0-r3 changed 3906 GET_INST_OPCODE(ip) @ extract opcode from rINST 3907 SET_VREG(r0, r9) @ vAA<- r0 3908 GOTO_OPCODE(ip) @ jump to next instruction 3909 /* 9-10 instructions */ 3910 3911 3912/* ------------------------------ */ 3913 .balign 64 3914.L_OP_INT_TO_SHORT: /* 0x8f */ 3915/* File: armv5te/OP_INT_TO_SHORT.S */ 3916/* File: armv5te/unop.S */ 3917 /* 3918 * Generic 32-bit unary operation. Provide an "instr" line that 3919 * specifies an instruction that performs "result = op r0". 3920 * This could be an ARM instruction or a function call. 3921 * 3922 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3923 * int-to-byte, int-to-char, int-to-short 3924 */ 3925 /* unop vA, vB */ 3926 mov r3, rINST, lsr #12 @ r3<- B 3927 mov r9, rINST, lsr #8 @ r9<- A+ 3928 GET_VREG(r0, r3) @ r0<- vB 3929 and r9, r9, #15 3930 mov r0, r0, asl #16 @ optional op; may set condition codes 3931 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3932 mov r0, r0, asr #16 @ r0<- op, r0-r3 changed 3933 GET_INST_OPCODE(ip) @ extract opcode from rINST 3934 SET_VREG(r0, r9) @ vAA<- r0 3935 GOTO_OPCODE(ip) @ jump to next instruction 3936 /* 9-10 instructions */ 3937 3938 3939/* ------------------------------ */ 3940 .balign 64 3941.L_OP_ADD_INT: /* 0x90 */ 3942/* File: armv5te/OP_ADD_INT.S */ 3943/* File: armv5te/binop.S */ 3944 /* 3945 * Generic 32-bit binary operation. Provide an "instr" line that 3946 * specifies an instruction that performs "result = r0 op r1". 3947 * This could be an ARM instruction or a function call. (If the result 3948 * comes back in a register other than r0, you can override "result".) 3949 * 3950 * If "chkzero" is set to 1, we perform a divide-by-zero check on 3951 * vCC (r1). Useful for integer division and modulus. Note that we 3952 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 3953 * handles it correctly. 3954 * 3955 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 3956 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 3957 * mul-float, div-float, rem-float 3958 */ 3959 /* binop vAA, vBB, vCC */ 3960 FETCH(r0, 1) @ r0<- CCBB 3961 mov r9, rINST, lsr #8 @ r9<- AA 3962 mov r3, r0, lsr #8 @ r3<- CC 3963 and r2, r0, #255 @ r2<- BB 3964 GET_VREG(r1, r3) @ r1<- vCC 3965 GET_VREG(r0, r2) @ r0<- vBB 3966 .if 0 3967 cmp r1, #0 @ is second operand zero? 3968 beq common_errDivideByZero 3969 .endif 3970 3971 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3972 @ optional op; may set condition codes 3973 add r0, r0, r1 @ r0<- op, r0-r3 changed 3974 GET_INST_OPCODE(ip) @ extract opcode from rINST 3975 SET_VREG(r0, r9) @ vAA<- r0 3976 GOTO_OPCODE(ip) @ jump to next instruction 3977 /* 11-14 instructions */ 3978 3979 3980/* ------------------------------ */ 3981 .balign 64 3982.L_OP_SUB_INT: /* 0x91 */ 3983/* File: armv5te/OP_SUB_INT.S */ 3984/* File: armv5te/binop.S */ 3985 /* 3986 * Generic 32-bit binary operation. Provide an "instr" line that 3987 * specifies an instruction that performs "result = r0 op r1". 3988 * This could be an ARM instruction or a function call. (If the result 3989 * comes back in a register other than r0, you can override "result".) 3990 * 3991 * If "chkzero" is set to 1, we perform a divide-by-zero check on 3992 * vCC (r1). Useful for integer division and modulus. Note that we 3993 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 3994 * handles it correctly. 3995 * 3996 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 3997 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 3998 * mul-float, div-float, rem-float 3999 */ 4000 /* binop vAA, vBB, vCC */ 4001 FETCH(r0, 1) @ r0<- CCBB 4002 mov r9, rINST, lsr #8 @ r9<- AA 4003 mov r3, r0, lsr #8 @ r3<- CC 4004 and r2, r0, #255 @ r2<- BB 4005 GET_VREG(r1, r3) @ r1<- vCC 4006 GET_VREG(r0, r2) @ r0<- vBB 4007 .if 0 4008 cmp r1, #0 @ is second operand zero? 4009 beq common_errDivideByZero 4010 .endif 4011 4012 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4013 @ optional op; may set condition codes 4014 sub r0, r0, r1 @ r0<- op, r0-r3 changed 4015 GET_INST_OPCODE(ip) @ extract opcode from rINST 4016 SET_VREG(r0, r9) @ vAA<- r0 4017 GOTO_OPCODE(ip) @ jump to next instruction 4018 /* 11-14 instructions */ 4019 4020 4021/* ------------------------------ */ 4022 .balign 64 4023.L_OP_MUL_INT: /* 0x92 */ 4024/* File: armv5te/OP_MUL_INT.S */ 4025/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 4026/* File: armv5te/binop.S */ 4027 /* 4028 * Generic 32-bit binary operation. Provide an "instr" line that 4029 * specifies an instruction that performs "result = r0 op r1". 4030 * This could be an ARM instruction or a function call. (If the result 4031 * comes back in a register other than r0, you can override "result".) 4032 * 4033 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4034 * vCC (r1). Useful for integer division and modulus. Note that we 4035 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4036 * handles it correctly. 4037 * 4038 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4039 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4040 * mul-float, div-float, rem-float 4041 */ 4042 /* binop vAA, vBB, vCC */ 4043 FETCH(r0, 1) @ r0<- CCBB 4044 mov r9, rINST, lsr #8 @ r9<- AA 4045 mov r3, r0, lsr #8 @ r3<- CC 4046 and r2, r0, #255 @ r2<- BB 4047 GET_VREG(r1, r3) @ r1<- vCC 4048 GET_VREG(r0, r2) @ r0<- vBB 4049 .if 0 4050 cmp r1, #0 @ is second operand zero? 4051 beq common_errDivideByZero 4052 .endif 4053 4054 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4055 @ optional op; may set condition codes 4056 mul r0, r1, r0 @ r0<- op, r0-r3 changed 4057 GET_INST_OPCODE(ip) @ extract opcode from rINST 4058 SET_VREG(r0, r9) @ vAA<- r0 4059 GOTO_OPCODE(ip) @ jump to next instruction 4060 /* 11-14 instructions */ 4061 4062 4063/* ------------------------------ */ 4064 .balign 64 4065.L_OP_DIV_INT: /* 0x93 */ 4066/* File: armv5te/OP_DIV_INT.S */ 4067/* File: armv5te/binop.S */ 4068 /* 4069 * Generic 32-bit binary operation. Provide an "instr" line that 4070 * specifies an instruction that performs "result = r0 op r1". 4071 * This could be an ARM instruction or a function call. (If the result 4072 * comes back in a register other than r0, you can override "result".) 4073 * 4074 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4075 * vCC (r1). Useful for integer division and modulus. Note that we 4076 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4077 * handles it correctly. 4078 * 4079 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4080 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4081 * mul-float, div-float, rem-float 4082 */ 4083 /* binop vAA, vBB, vCC */ 4084 FETCH(r0, 1) @ r0<- CCBB 4085 mov r9, rINST, lsr #8 @ r9<- AA 4086 mov r3, r0, lsr #8 @ r3<- CC 4087 and r2, r0, #255 @ r2<- BB 4088 GET_VREG(r1, r3) @ r1<- vCC 4089 GET_VREG(r0, r2) @ r0<- vBB 4090 .if 1 4091 cmp r1, #0 @ is second operand zero? 4092 beq common_errDivideByZero 4093 .endif 4094 4095 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4096 @ optional op; may set condition codes 4097 bl __aeabi_idiv @ r0<- op, r0-r3 changed 4098 GET_INST_OPCODE(ip) @ extract opcode from rINST 4099 SET_VREG(r0, r9) @ vAA<- r0 4100 GOTO_OPCODE(ip) @ jump to next instruction 4101 /* 11-14 instructions */ 4102 4103 4104/* ------------------------------ */ 4105 .balign 64 4106.L_OP_REM_INT: /* 0x94 */ 4107/* File: armv5te/OP_REM_INT.S */ 4108/* idivmod returns quotient in r0 and remainder in r1 */ 4109/* File: armv5te/binop.S */ 4110 /* 4111 * Generic 32-bit binary operation. Provide an "instr" line that 4112 * specifies an instruction that performs "result = r0 op r1". 4113 * This could be an ARM instruction or a function call. (If the result 4114 * comes back in a register other than r0, you can override "result".) 4115 * 4116 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4117 * vCC (r1). Useful for integer division and modulus. Note that we 4118 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4119 * handles it correctly. 4120 * 4121 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4122 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4123 * mul-float, div-float, rem-float 4124 */ 4125 /* binop vAA, vBB, vCC */ 4126 FETCH(r0, 1) @ r0<- CCBB 4127 mov r9, rINST, lsr #8 @ r9<- AA 4128 mov r3, r0, lsr #8 @ r3<- CC 4129 and r2, r0, #255 @ r2<- BB 4130 GET_VREG(r1, r3) @ r1<- vCC 4131 GET_VREG(r0, r2) @ r0<- vBB 4132 .if 1 4133 cmp r1, #0 @ is second operand zero? 4134 beq common_errDivideByZero 4135 .endif 4136 4137 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4138 @ optional op; may set condition codes 4139 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 4140 GET_INST_OPCODE(ip) @ extract opcode from rINST 4141 SET_VREG(r1, r9) @ vAA<- r1 4142 GOTO_OPCODE(ip) @ jump to next instruction 4143 /* 11-14 instructions */ 4144 4145 4146/* ------------------------------ */ 4147 .balign 64 4148.L_OP_AND_INT: /* 0x95 */ 4149/* File: armv5te/OP_AND_INT.S */ 4150/* File: armv5te/binop.S */ 4151 /* 4152 * Generic 32-bit binary operation. Provide an "instr" line that 4153 * specifies an instruction that performs "result = r0 op r1". 4154 * This could be an ARM instruction or a function call. (If the result 4155 * comes back in a register other than r0, you can override "result".) 4156 * 4157 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4158 * vCC (r1). Useful for integer division and modulus. Note that we 4159 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4160 * handles it correctly. 4161 * 4162 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4163 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4164 * mul-float, div-float, rem-float 4165 */ 4166 /* binop vAA, vBB, vCC */ 4167 FETCH(r0, 1) @ r0<- CCBB 4168 mov r9, rINST, lsr #8 @ r9<- AA 4169 mov r3, r0, lsr #8 @ r3<- CC 4170 and r2, r0, #255 @ r2<- BB 4171 GET_VREG(r1, r3) @ r1<- vCC 4172 GET_VREG(r0, r2) @ r0<- vBB 4173 .if 0 4174 cmp r1, #0 @ is second operand zero? 4175 beq common_errDivideByZero 4176 .endif 4177 4178 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4179 @ optional op; may set condition codes 4180 and r0, r0, r1 @ r0<- op, r0-r3 changed 4181 GET_INST_OPCODE(ip) @ extract opcode from rINST 4182 SET_VREG(r0, r9) @ vAA<- r0 4183 GOTO_OPCODE(ip) @ jump to next instruction 4184 /* 11-14 instructions */ 4185 4186 4187/* ------------------------------ */ 4188 .balign 64 4189.L_OP_OR_INT: /* 0x96 */ 4190/* File: armv5te/OP_OR_INT.S */ 4191/* File: armv5te/binop.S */ 4192 /* 4193 * Generic 32-bit binary operation. Provide an "instr" line that 4194 * specifies an instruction that performs "result = r0 op r1". 4195 * This could be an ARM instruction or a function call. (If the result 4196 * comes back in a register other than r0, you can override "result".) 4197 * 4198 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4199 * vCC (r1). Useful for integer division and modulus. Note that we 4200 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4201 * handles it correctly. 4202 * 4203 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4204 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4205 * mul-float, div-float, rem-float 4206 */ 4207 /* binop vAA, vBB, vCC */ 4208 FETCH(r0, 1) @ r0<- CCBB 4209 mov r9, rINST, lsr #8 @ r9<- AA 4210 mov r3, r0, lsr #8 @ r3<- CC 4211 and r2, r0, #255 @ r2<- BB 4212 GET_VREG(r1, r3) @ r1<- vCC 4213 GET_VREG(r0, r2) @ r0<- vBB 4214 .if 0 4215 cmp r1, #0 @ is second operand zero? 4216 beq common_errDivideByZero 4217 .endif 4218 4219 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4220 @ optional op; may set condition codes 4221 orr r0, r0, r1 @ r0<- op, r0-r3 changed 4222 GET_INST_OPCODE(ip) @ extract opcode from rINST 4223 SET_VREG(r0, r9) @ vAA<- r0 4224 GOTO_OPCODE(ip) @ jump to next instruction 4225 /* 11-14 instructions */ 4226 4227 4228/* ------------------------------ */ 4229 .balign 64 4230.L_OP_XOR_INT: /* 0x97 */ 4231/* File: armv5te/OP_XOR_INT.S */ 4232/* File: armv5te/binop.S */ 4233 /* 4234 * Generic 32-bit binary operation. Provide an "instr" line that 4235 * specifies an instruction that performs "result = r0 op r1". 4236 * This could be an ARM instruction or a function call. (If the result 4237 * comes back in a register other than r0, you can override "result".) 4238 * 4239 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4240 * vCC (r1). Useful for integer division and modulus. Note that we 4241 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4242 * handles it correctly. 4243 * 4244 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4245 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4246 * mul-float, div-float, rem-float 4247 */ 4248 /* binop vAA, vBB, vCC */ 4249 FETCH(r0, 1) @ r0<- CCBB 4250 mov r9, rINST, lsr #8 @ r9<- AA 4251 mov r3, r0, lsr #8 @ r3<- CC 4252 and r2, r0, #255 @ r2<- BB 4253 GET_VREG(r1, r3) @ r1<- vCC 4254 GET_VREG(r0, r2) @ r0<- vBB 4255 .if 0 4256 cmp r1, #0 @ is second operand zero? 4257 beq common_errDivideByZero 4258 .endif 4259 4260 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4261 @ optional op; may set condition codes 4262 eor r0, r0, r1 @ r0<- op, r0-r3 changed 4263 GET_INST_OPCODE(ip) @ extract opcode from rINST 4264 SET_VREG(r0, r9) @ vAA<- r0 4265 GOTO_OPCODE(ip) @ jump to next instruction 4266 /* 11-14 instructions */ 4267 4268 4269/* ------------------------------ */ 4270 .balign 64 4271.L_OP_SHL_INT: /* 0x98 */ 4272/* File: armv5te/OP_SHL_INT.S */ 4273/* File: armv5te/binop.S */ 4274 /* 4275 * Generic 32-bit binary operation. Provide an "instr" line that 4276 * specifies an instruction that performs "result = r0 op r1". 4277 * This could be an ARM instruction or a function call. (If the result 4278 * comes back in a register other than r0, you can override "result".) 4279 * 4280 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4281 * vCC (r1). Useful for integer division and modulus. Note that we 4282 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4283 * handles it correctly. 4284 * 4285 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4286 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4287 * mul-float, div-float, rem-float 4288 */ 4289 /* binop vAA, vBB, vCC */ 4290 FETCH(r0, 1) @ r0<- CCBB 4291 mov r9, rINST, lsr #8 @ r9<- AA 4292 mov r3, r0, lsr #8 @ r3<- CC 4293 and r2, r0, #255 @ r2<- BB 4294 GET_VREG(r1, r3) @ r1<- vCC 4295 GET_VREG(r0, r2) @ r0<- vBB 4296 .if 0 4297 cmp r1, #0 @ is second operand zero? 4298 beq common_errDivideByZero 4299 .endif 4300 4301 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4302 and r1, r1, #31 @ optional op; may set condition codes 4303 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 4304 GET_INST_OPCODE(ip) @ extract opcode from rINST 4305 SET_VREG(r0, r9) @ vAA<- r0 4306 GOTO_OPCODE(ip) @ jump to next instruction 4307 /* 11-14 instructions */ 4308 4309 4310/* ------------------------------ */ 4311 .balign 64 4312.L_OP_SHR_INT: /* 0x99 */ 4313/* File: armv5te/OP_SHR_INT.S */ 4314/* File: armv5te/binop.S */ 4315 /* 4316 * Generic 32-bit binary operation. Provide an "instr" line that 4317 * specifies an instruction that performs "result = r0 op r1". 4318 * This could be an ARM instruction or a function call. (If the result 4319 * comes back in a register other than r0, you can override "result".) 4320 * 4321 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4322 * vCC (r1). Useful for integer division and modulus. Note that we 4323 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4324 * handles it correctly. 4325 * 4326 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4327 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4328 * mul-float, div-float, rem-float 4329 */ 4330 /* binop vAA, vBB, vCC */ 4331 FETCH(r0, 1) @ r0<- CCBB 4332 mov r9, rINST, lsr #8 @ r9<- AA 4333 mov r3, r0, lsr #8 @ r3<- CC 4334 and r2, r0, #255 @ r2<- BB 4335 GET_VREG(r1, r3) @ r1<- vCC 4336 GET_VREG(r0, r2) @ r0<- vBB 4337 .if 0 4338 cmp r1, #0 @ is second operand zero? 4339 beq common_errDivideByZero 4340 .endif 4341 4342 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4343 and r1, r1, #31 @ optional op; may set condition codes 4344 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 4345 GET_INST_OPCODE(ip) @ extract opcode from rINST 4346 SET_VREG(r0, r9) @ vAA<- r0 4347 GOTO_OPCODE(ip) @ jump to next instruction 4348 /* 11-14 instructions */ 4349 4350 4351/* ------------------------------ */ 4352 .balign 64 4353.L_OP_USHR_INT: /* 0x9a */ 4354/* File: armv5te/OP_USHR_INT.S */ 4355/* File: armv5te/binop.S */ 4356 /* 4357 * Generic 32-bit binary operation. Provide an "instr" line that 4358 * specifies an instruction that performs "result = r0 op r1". 4359 * This could be an ARM instruction or a function call. (If the result 4360 * comes back in a register other than r0, you can override "result".) 4361 * 4362 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4363 * vCC (r1). Useful for integer division and modulus. Note that we 4364 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4365 * handles it correctly. 4366 * 4367 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4368 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4369 * mul-float, div-float, rem-float 4370 */ 4371 /* binop vAA, vBB, vCC */ 4372 FETCH(r0, 1) @ r0<- CCBB 4373 mov r9, rINST, lsr #8 @ r9<- AA 4374 mov r3, r0, lsr #8 @ r3<- CC 4375 and r2, r0, #255 @ r2<- BB 4376 GET_VREG(r1, r3) @ r1<- vCC 4377 GET_VREG(r0, r2) @ r0<- vBB 4378 .if 0 4379 cmp r1, #0 @ is second operand zero? 4380 beq common_errDivideByZero 4381 .endif 4382 4383 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4384 and r1, r1, #31 @ optional op; may set condition codes 4385 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 4386 GET_INST_OPCODE(ip) @ extract opcode from rINST 4387 SET_VREG(r0, r9) @ vAA<- r0 4388 GOTO_OPCODE(ip) @ jump to next instruction 4389 /* 11-14 instructions */ 4390 4391 4392/* ------------------------------ */ 4393 .balign 64 4394.L_OP_ADD_LONG: /* 0x9b */ 4395/* File: armv5te/OP_ADD_LONG.S */ 4396/* File: armv5te/binopWide.S */ 4397 /* 4398 * Generic 64-bit binary operation. Provide an "instr" line that 4399 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4400 * This could be an ARM instruction or a function call. (If the result 4401 * comes back in a register other than r0, you can override "result".) 4402 * 4403 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4404 * vCC (r1). Useful for integer division and modulus. 4405 * 4406 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4407 * xor-long, add-double, sub-double, mul-double, div-double, 4408 * rem-double 4409 * 4410 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4411 */ 4412 /* binop vAA, vBB, vCC */ 4413 FETCH(r0, 1) @ r0<- CCBB 4414 mov r9, rINST, lsr #8 @ r9<- AA 4415 and r2, r0, #255 @ r2<- BB 4416 mov r3, r0, lsr #8 @ r3<- CC 4417 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4418 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4419 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4420 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4421 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4422 .if 0 4423 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4424 beq common_errDivideByZero 4425 .endif 4426 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4427 4428 adds r0, r0, r2 @ optional op; may set condition codes 4429 adc r1, r1, r3 @ result<- op, r0-r3 changed 4430 GET_INST_OPCODE(ip) @ extract opcode from rINST 4431 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4432 GOTO_OPCODE(ip) @ jump to next instruction 4433 /* 14-17 instructions */ 4434 4435 4436/* ------------------------------ */ 4437 .balign 64 4438.L_OP_SUB_LONG: /* 0x9c */ 4439/* File: armv5te/OP_SUB_LONG.S */ 4440/* File: armv5te/binopWide.S */ 4441 /* 4442 * Generic 64-bit binary operation. Provide an "instr" line that 4443 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4444 * This could be an ARM instruction or a function call. (If the result 4445 * comes back in a register other than r0, you can override "result".) 4446 * 4447 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4448 * vCC (r1). Useful for integer division and modulus. 4449 * 4450 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4451 * xor-long, add-double, sub-double, mul-double, div-double, 4452 * rem-double 4453 * 4454 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4455 */ 4456 /* binop vAA, vBB, vCC */ 4457 FETCH(r0, 1) @ r0<- CCBB 4458 mov r9, rINST, lsr #8 @ r9<- AA 4459 and r2, r0, #255 @ r2<- BB 4460 mov r3, r0, lsr #8 @ r3<- CC 4461 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4462 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4463 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4464 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4465 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4466 .if 0 4467 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4468 beq common_errDivideByZero 4469 .endif 4470 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4471 4472 subs r0, r0, r2 @ optional op; may set condition codes 4473 sbc r1, r1, r3 @ result<- op, r0-r3 changed 4474 GET_INST_OPCODE(ip) @ extract opcode from rINST 4475 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4476 GOTO_OPCODE(ip) @ jump to next instruction 4477 /* 14-17 instructions */ 4478 4479 4480/* ------------------------------ */ 4481 .balign 64 4482.L_OP_MUL_LONG: /* 0x9d */ 4483/* File: armv5te/OP_MUL_LONG.S */ 4484 /* 4485 * Signed 64-bit integer multiply. 4486 * 4487 * Consider WXxYZ (r1r0 x r3r2) with a long multiply: 4488 * WX 4489 * x YZ 4490 * -------- 4491 * ZW ZX 4492 * YW YX 4493 * 4494 * The low word of the result holds ZX, the high word holds 4495 * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because 4496 * it doesn't fit in the low 64 bits. 4497 * 4498 * Unlike most ARM math operations, multiply instructions have 4499 * restrictions on using the same register more than once (Rd and Rm 4500 * cannot be the same). 4501 */ 4502 /* mul-long vAA, vBB, vCC */ 4503 FETCH(r0, 1) @ r0<- CCBB 4504 and r2, r0, #255 @ r2<- BB 4505 mov r3, r0, lsr #8 @ r3<- CC 4506 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4507 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4508 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4509 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4510 mul ip, r2, r1 @ ip<- ZxW 4511 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 4512 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 4513 mov r0, rINST, lsr #8 @ r0<- AA 4514 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 4515 add r0, rFP, r0, lsl #2 @ r0<- &fp[AA] 4516 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4517 b .LOP_MUL_LONG_finish 4518 4519/* ------------------------------ */ 4520 .balign 64 4521.L_OP_DIV_LONG: /* 0x9e */ 4522/* File: armv5te/OP_DIV_LONG.S */ 4523/* File: armv5te/binopWide.S */ 4524 /* 4525 * Generic 64-bit binary operation. Provide an "instr" line that 4526 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4527 * This could be an ARM instruction or a function call. (If the result 4528 * comes back in a register other than r0, you can override "result".) 4529 * 4530 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4531 * vCC (r1). Useful for integer division and modulus. 4532 * 4533 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4534 * xor-long, add-double, sub-double, mul-double, div-double, 4535 * rem-double 4536 * 4537 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4538 */ 4539 /* binop vAA, vBB, vCC */ 4540 FETCH(r0, 1) @ r0<- CCBB 4541 mov r9, rINST, lsr #8 @ r9<- AA 4542 and r2, r0, #255 @ r2<- BB 4543 mov r3, r0, lsr #8 @ r3<- CC 4544 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4545 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4546 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4547 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4548 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4549 .if 1 4550 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4551 beq common_errDivideByZero 4552 .endif 4553 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4554 4555 @ optional op; may set condition codes 4556 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4557 GET_INST_OPCODE(ip) @ extract opcode from rINST 4558 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4559 GOTO_OPCODE(ip) @ jump to next instruction 4560 /* 14-17 instructions */ 4561 4562 4563/* ------------------------------ */ 4564 .balign 64 4565.L_OP_REM_LONG: /* 0x9f */ 4566/* File: armv5te/OP_REM_LONG.S */ 4567/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 4568/* File: armv5te/binopWide.S */ 4569 /* 4570 * Generic 64-bit binary operation. Provide an "instr" line that 4571 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4572 * This could be an ARM instruction or a function call. (If the result 4573 * comes back in a register other than r0, you can override "result".) 4574 * 4575 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4576 * vCC (r1). Useful for integer division and modulus. 4577 * 4578 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4579 * xor-long, add-double, sub-double, mul-double, div-double, 4580 * rem-double 4581 * 4582 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4583 */ 4584 /* binop vAA, vBB, vCC */ 4585 FETCH(r0, 1) @ r0<- CCBB 4586 mov r9, rINST, lsr #8 @ r9<- AA 4587 and r2, r0, #255 @ r2<- BB 4588 mov r3, r0, lsr #8 @ r3<- CC 4589 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4590 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4591 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4592 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4593 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4594 .if 1 4595 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4596 beq common_errDivideByZero 4597 .endif 4598 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4599 4600 @ optional op; may set condition codes 4601 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4602 GET_INST_OPCODE(ip) @ extract opcode from rINST 4603 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 4604 GOTO_OPCODE(ip) @ jump to next instruction 4605 /* 14-17 instructions */ 4606 4607 4608/* ------------------------------ */ 4609 .balign 64 4610.L_OP_AND_LONG: /* 0xa0 */ 4611/* File: armv5te/OP_AND_LONG.S */ 4612/* File: armv5te/binopWide.S */ 4613 /* 4614 * Generic 64-bit binary operation. Provide an "instr" line that 4615 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4616 * This could be an ARM instruction or a function call. (If the result 4617 * comes back in a register other than r0, you can override "result".) 4618 * 4619 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4620 * vCC (r1). Useful for integer division and modulus. 4621 * 4622 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4623 * xor-long, add-double, sub-double, mul-double, div-double, 4624 * rem-double 4625 * 4626 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4627 */ 4628 /* binop vAA, vBB, vCC */ 4629 FETCH(r0, 1) @ r0<- CCBB 4630 mov r9, rINST, lsr #8 @ r9<- AA 4631 and r2, r0, #255 @ r2<- BB 4632 mov r3, r0, lsr #8 @ r3<- CC 4633 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4634 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4635 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4636 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4637 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4638 .if 0 4639 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4640 beq common_errDivideByZero 4641 .endif 4642 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4643 4644 and r0, r0, r2 @ optional op; may set condition codes 4645 and r1, r1, r3 @ result<- op, r0-r3 changed 4646 GET_INST_OPCODE(ip) @ extract opcode from rINST 4647 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4648 GOTO_OPCODE(ip) @ jump to next instruction 4649 /* 14-17 instructions */ 4650 4651 4652/* ------------------------------ */ 4653 .balign 64 4654.L_OP_OR_LONG: /* 0xa1 */ 4655/* File: armv5te/OP_OR_LONG.S */ 4656/* File: armv5te/binopWide.S */ 4657 /* 4658 * Generic 64-bit binary operation. Provide an "instr" line that 4659 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4660 * This could be an ARM instruction or a function call. (If the result 4661 * comes back in a register other than r0, you can override "result".) 4662 * 4663 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4664 * vCC (r1). Useful for integer division and modulus. 4665 * 4666 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4667 * xor-long, add-double, sub-double, mul-double, div-double, 4668 * rem-double 4669 * 4670 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4671 */ 4672 /* binop vAA, vBB, vCC */ 4673 FETCH(r0, 1) @ r0<- CCBB 4674 mov r9, rINST, lsr #8 @ r9<- AA 4675 and r2, r0, #255 @ r2<- BB 4676 mov r3, r0, lsr #8 @ r3<- CC 4677 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4678 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4679 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4680 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4681 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4682 .if 0 4683 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4684 beq common_errDivideByZero 4685 .endif 4686 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4687 4688 orr r0, r0, r2 @ optional op; may set condition codes 4689 orr r1, r1, r3 @ result<- op, r0-r3 changed 4690 GET_INST_OPCODE(ip) @ extract opcode from rINST 4691 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4692 GOTO_OPCODE(ip) @ jump to next instruction 4693 /* 14-17 instructions */ 4694 4695 4696/* ------------------------------ */ 4697 .balign 64 4698.L_OP_XOR_LONG: /* 0xa2 */ 4699/* File: armv5te/OP_XOR_LONG.S */ 4700/* File: armv5te/binopWide.S */ 4701 /* 4702 * Generic 64-bit binary operation. Provide an "instr" line that 4703 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4704 * This could be an ARM instruction or a function call. (If the result 4705 * comes back in a register other than r0, you can override "result".) 4706 * 4707 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4708 * vCC (r1). Useful for integer division and modulus. 4709 * 4710 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4711 * xor-long, add-double, sub-double, mul-double, div-double, 4712 * rem-double 4713 * 4714 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4715 */ 4716 /* binop vAA, vBB, vCC */ 4717 FETCH(r0, 1) @ r0<- CCBB 4718 mov r9, rINST, lsr #8 @ r9<- AA 4719 and r2, r0, #255 @ r2<- BB 4720 mov r3, r0, lsr #8 @ r3<- CC 4721 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4722 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4723 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4724 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4725 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4726 .if 0 4727 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4728 beq common_errDivideByZero 4729 .endif 4730 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4731 4732 eor r0, r0, r2 @ optional op; may set condition codes 4733 eor r1, r1, r3 @ result<- op, r0-r3 changed 4734 GET_INST_OPCODE(ip) @ extract opcode from rINST 4735 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4736 GOTO_OPCODE(ip) @ jump to next instruction 4737 /* 14-17 instructions */ 4738 4739 4740/* ------------------------------ */ 4741 .balign 64 4742.L_OP_SHL_LONG: /* 0xa3 */ 4743/* File: armv5te/OP_SHL_LONG.S */ 4744 /* 4745 * Long integer shift. This is different from the generic 32/64-bit 4746 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4747 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4748 * 6 bits of the shift distance. 4749 */ 4750 /* shl-long vAA, vBB, vCC */ 4751 FETCH(r0, 1) @ r0<- CCBB 4752 mov r9, rINST, lsr #8 @ r9<- AA 4753 and r3, r0, #255 @ r3<- BB 4754 mov r0, r0, lsr #8 @ r0<- CC 4755 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4756 GET_VREG(r2, r0) @ r2<- vCC 4757 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4758 and r2, r2, #63 @ r2<- r2 & 0x3f 4759 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4760 4761 mov r1, r1, asl r2 @ r1<- r1 << r2 4762 rsb r3, r2, #32 @ r3<- 32 - r2 4763 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 4764 subs ip, r2, #32 @ ip<- r2 - 32 4765 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 4766 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4767 b .LOP_SHL_LONG_finish 4768 4769/* ------------------------------ */ 4770 .balign 64 4771.L_OP_SHR_LONG: /* 0xa4 */ 4772/* File: armv5te/OP_SHR_LONG.S */ 4773 /* 4774 * Long integer shift. This is different from the generic 32/64-bit 4775 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4776 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4777 * 6 bits of the shift distance. 4778 */ 4779 /* shr-long vAA, vBB, vCC */ 4780 FETCH(r0, 1) @ r0<- CCBB 4781 mov r9, rINST, lsr #8 @ r9<- AA 4782 and r3, r0, #255 @ r3<- BB 4783 mov r0, r0, lsr #8 @ r0<- CC 4784 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4785 GET_VREG(r2, r0) @ r2<- vCC 4786 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4787 and r2, r2, #63 @ r0<- r0 & 0x3f 4788 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4789 4790 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4791 rsb r3, r2, #32 @ r3<- 32 - r2 4792 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4793 subs ip, r2, #32 @ ip<- r2 - 32 4794 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 4795 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4796 b .LOP_SHR_LONG_finish 4797 4798/* ------------------------------ */ 4799 .balign 64 4800.L_OP_USHR_LONG: /* 0xa5 */ 4801/* File: armv5te/OP_USHR_LONG.S */ 4802 /* 4803 * Long integer shift. This is different from the generic 32/64-bit 4804 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4805 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4806 * 6 bits of the shift distance. 4807 */ 4808 /* ushr-long vAA, vBB, vCC */ 4809 FETCH(r0, 1) @ r0<- CCBB 4810 mov r9, rINST, lsr #8 @ r9<- AA 4811 and r3, r0, #255 @ r3<- BB 4812 mov r0, r0, lsr #8 @ r0<- CC 4813 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4814 GET_VREG(r2, r0) @ r2<- vCC 4815 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4816 and r2, r2, #63 @ r0<- r0 & 0x3f 4817 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4818 4819 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4820 rsb r3, r2, #32 @ r3<- 32 - r2 4821 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4822 subs ip, r2, #32 @ ip<- r2 - 32 4823 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 4824 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4825 b .LOP_USHR_LONG_finish 4826 4827/* ------------------------------ */ 4828 .balign 64 4829.L_OP_ADD_FLOAT: /* 0xa6 */ 4830/* File: arm-vfp/OP_ADD_FLOAT.S */ 4831/* File: arm-vfp/fbinop.S */ 4832 /* 4833 * Generic 32-bit floating-point operation. Provide an "instr" line that 4834 * specifies an instruction that performs "s2 = s0 op s1". Because we 4835 * use the "softfp" ABI, this must be an instruction, not a function call. 4836 * 4837 * For: add-float, sub-float, mul-float, div-float 4838 */ 4839 /* floatop vAA, vBB, vCC */ 4840 FETCH(r0, 1) @ r0<- CCBB 4841 mov r9, rINST, lsr #8 @ r9<- AA 4842 mov r3, r0, lsr #8 @ r3<- CC 4843 and r2, r0, #255 @ r2<- BB 4844 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4845 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4846 flds s1, [r3] @ s1<- vCC 4847 flds s0, [r2] @ s0<- vBB 4848 4849 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4850 fadds s2, s0, s1 @ s2<- op 4851 GET_INST_OPCODE(ip) @ extract opcode from rINST 4852 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4853 fsts s2, [r9] @ vAA<- s2 4854 GOTO_OPCODE(ip) @ jump to next instruction 4855 4856 4857/* ------------------------------ */ 4858 .balign 64 4859.L_OP_SUB_FLOAT: /* 0xa7 */ 4860/* File: arm-vfp/OP_SUB_FLOAT.S */ 4861/* File: arm-vfp/fbinop.S */ 4862 /* 4863 * Generic 32-bit floating-point operation. Provide an "instr" line that 4864 * specifies an instruction that performs "s2 = s0 op s1". Because we 4865 * use the "softfp" ABI, this must be an instruction, not a function call. 4866 * 4867 * For: add-float, sub-float, mul-float, div-float 4868 */ 4869 /* floatop vAA, vBB, vCC */ 4870 FETCH(r0, 1) @ r0<- CCBB 4871 mov r9, rINST, lsr #8 @ r9<- AA 4872 mov r3, r0, lsr #8 @ r3<- CC 4873 and r2, r0, #255 @ r2<- BB 4874 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4875 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4876 flds s1, [r3] @ s1<- vCC 4877 flds s0, [r2] @ s0<- vBB 4878 4879 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4880 fsubs s2, s0, s1 @ s2<- op 4881 GET_INST_OPCODE(ip) @ extract opcode from rINST 4882 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4883 fsts s2, [r9] @ vAA<- s2 4884 GOTO_OPCODE(ip) @ jump to next instruction 4885 4886 4887/* ------------------------------ */ 4888 .balign 64 4889.L_OP_MUL_FLOAT: /* 0xa8 */ 4890/* File: arm-vfp/OP_MUL_FLOAT.S */ 4891/* File: arm-vfp/fbinop.S */ 4892 /* 4893 * Generic 32-bit floating-point operation. Provide an "instr" line that 4894 * specifies an instruction that performs "s2 = s0 op s1". Because we 4895 * use the "softfp" ABI, this must be an instruction, not a function call. 4896 * 4897 * For: add-float, sub-float, mul-float, div-float 4898 */ 4899 /* floatop vAA, vBB, vCC */ 4900 FETCH(r0, 1) @ r0<- CCBB 4901 mov r9, rINST, lsr #8 @ r9<- AA 4902 mov r3, r0, lsr #8 @ r3<- CC 4903 and r2, r0, #255 @ r2<- BB 4904 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4905 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4906 flds s1, [r3] @ s1<- vCC 4907 flds s0, [r2] @ s0<- vBB 4908 4909 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4910 fmuls s2, s0, s1 @ s2<- op 4911 GET_INST_OPCODE(ip) @ extract opcode from rINST 4912 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4913 fsts s2, [r9] @ vAA<- s2 4914 GOTO_OPCODE(ip) @ jump to next instruction 4915 4916 4917/* ------------------------------ */ 4918 .balign 64 4919.L_OP_DIV_FLOAT: /* 0xa9 */ 4920/* File: arm-vfp/OP_DIV_FLOAT.S */ 4921/* File: arm-vfp/fbinop.S */ 4922 /* 4923 * Generic 32-bit floating-point operation. Provide an "instr" line that 4924 * specifies an instruction that performs "s2 = s0 op s1". Because we 4925 * use the "softfp" ABI, this must be an instruction, not a function call. 4926 * 4927 * For: add-float, sub-float, mul-float, div-float 4928 */ 4929 /* floatop vAA, vBB, vCC */ 4930 FETCH(r0, 1) @ r0<- CCBB 4931 mov r9, rINST, lsr #8 @ r9<- AA 4932 mov r3, r0, lsr #8 @ r3<- CC 4933 and r2, r0, #255 @ r2<- BB 4934 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4935 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4936 flds s1, [r3] @ s1<- vCC 4937 flds s0, [r2] @ s0<- vBB 4938 4939 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4940 fdivs s2, s0, s1 @ s2<- op 4941 GET_INST_OPCODE(ip) @ extract opcode from rINST 4942 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4943 fsts s2, [r9] @ vAA<- s2 4944 GOTO_OPCODE(ip) @ jump to next instruction 4945 4946 4947/* ------------------------------ */ 4948 .balign 64 4949.L_OP_REM_FLOAT: /* 0xaa */ 4950/* File: armv5te/OP_REM_FLOAT.S */ 4951/* EABI doesn't define a float remainder function, but libm does */ 4952/* File: armv5te/binop.S */ 4953 /* 4954 * Generic 32-bit binary operation. Provide an "instr" line that 4955 * specifies an instruction that performs "result = r0 op r1". 4956 * This could be an ARM instruction or a function call. (If the result 4957 * comes back in a register other than r0, you can override "result".) 4958 * 4959 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4960 * vCC (r1). Useful for integer division and modulus. Note that we 4961 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4962 * handles it correctly. 4963 * 4964 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4965 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4966 * mul-float, div-float, rem-float 4967 */ 4968 /* binop vAA, vBB, vCC */ 4969 FETCH(r0, 1) @ r0<- CCBB 4970 mov r9, rINST, lsr #8 @ r9<- AA 4971 mov r3, r0, lsr #8 @ r3<- CC 4972 and r2, r0, #255 @ r2<- BB 4973 GET_VREG(r1, r3) @ r1<- vCC 4974 GET_VREG(r0, r2) @ r0<- vBB 4975 .if 0 4976 cmp r1, #0 @ is second operand zero? 4977 beq common_errDivideByZero 4978 .endif 4979 4980 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4981 @ optional op; may set condition codes 4982 bl fmodf @ r0<- op, r0-r3 changed 4983 GET_INST_OPCODE(ip) @ extract opcode from rINST 4984 SET_VREG(r0, r9) @ vAA<- r0 4985 GOTO_OPCODE(ip) @ jump to next instruction 4986 /* 11-14 instructions */ 4987 4988 4989/* ------------------------------ */ 4990 .balign 64 4991.L_OP_ADD_DOUBLE: /* 0xab */ 4992/* File: arm-vfp/OP_ADD_DOUBLE.S */ 4993/* File: arm-vfp/fbinopWide.S */ 4994 /* 4995 * Generic 64-bit double-precision floating point binary operation. 4996 * Provide an "instr" line that specifies an instruction that performs 4997 * "d2 = d0 op d1". 4998 * 4999 * for: add-double, sub-double, mul-double, div-double 5000 */ 5001 /* doubleop vAA, vBB, vCC */ 5002 FETCH(r0, 1) @ r0<- CCBB 5003 mov r9, rINST, lsr #8 @ r9<- AA 5004 mov r3, r0, lsr #8 @ r3<- CC 5005 and r2, r0, #255 @ r2<- BB 5006 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5007 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5008 fldd d1, [r3] @ d1<- vCC 5009 fldd d0, [r2] @ d0<- vBB 5010 5011 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5012 faddd d2, d0, d1 @ s2<- op 5013 GET_INST_OPCODE(ip) @ extract opcode from rINST 5014 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5015 fstd d2, [r9] @ vAA<- d2 5016 GOTO_OPCODE(ip) @ jump to next instruction 5017 5018 5019/* ------------------------------ */ 5020 .balign 64 5021.L_OP_SUB_DOUBLE: /* 0xac */ 5022/* File: arm-vfp/OP_SUB_DOUBLE.S */ 5023/* File: arm-vfp/fbinopWide.S */ 5024 /* 5025 * Generic 64-bit double-precision floating point binary operation. 5026 * Provide an "instr" line that specifies an instruction that performs 5027 * "d2 = d0 op d1". 5028 * 5029 * for: add-double, sub-double, mul-double, div-double 5030 */ 5031 /* doubleop vAA, vBB, vCC */ 5032 FETCH(r0, 1) @ r0<- CCBB 5033 mov r9, rINST, lsr #8 @ r9<- AA 5034 mov r3, r0, lsr #8 @ r3<- CC 5035 and r2, r0, #255 @ r2<- BB 5036 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5037 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5038 fldd d1, [r3] @ d1<- vCC 5039 fldd d0, [r2] @ d0<- vBB 5040 5041 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5042 fsubd d2, d0, d1 @ s2<- op 5043 GET_INST_OPCODE(ip) @ extract opcode from rINST 5044 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5045 fstd d2, [r9] @ vAA<- d2 5046 GOTO_OPCODE(ip) @ jump to next instruction 5047 5048 5049/* ------------------------------ */ 5050 .balign 64 5051.L_OP_MUL_DOUBLE: /* 0xad */ 5052/* File: arm-vfp/OP_MUL_DOUBLE.S */ 5053/* File: arm-vfp/fbinopWide.S */ 5054 /* 5055 * Generic 64-bit double-precision floating point binary operation. 5056 * Provide an "instr" line that specifies an instruction that performs 5057 * "d2 = d0 op d1". 5058 * 5059 * for: add-double, sub-double, mul-double, div-double 5060 */ 5061 /* doubleop vAA, vBB, vCC */ 5062 FETCH(r0, 1) @ r0<- CCBB 5063 mov r9, rINST, lsr #8 @ r9<- AA 5064 mov r3, r0, lsr #8 @ r3<- CC 5065 and r2, r0, #255 @ r2<- BB 5066 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5067 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5068 fldd d1, [r3] @ d1<- vCC 5069 fldd d0, [r2] @ d0<- vBB 5070 5071 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5072 fmuld d2, d0, d1 @ s2<- op 5073 GET_INST_OPCODE(ip) @ extract opcode from rINST 5074 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5075 fstd d2, [r9] @ vAA<- d2 5076 GOTO_OPCODE(ip) @ jump to next instruction 5077 5078 5079/* ------------------------------ */ 5080 .balign 64 5081.L_OP_DIV_DOUBLE: /* 0xae */ 5082/* File: arm-vfp/OP_DIV_DOUBLE.S */ 5083/* File: arm-vfp/fbinopWide.S */ 5084 /* 5085 * Generic 64-bit double-precision floating point binary operation. 5086 * Provide an "instr" line that specifies an instruction that performs 5087 * "d2 = d0 op d1". 5088 * 5089 * for: add-double, sub-double, mul-double, div-double 5090 */ 5091 /* doubleop vAA, vBB, vCC */ 5092 FETCH(r0, 1) @ r0<- CCBB 5093 mov r9, rINST, lsr #8 @ r9<- AA 5094 mov r3, r0, lsr #8 @ r3<- CC 5095 and r2, r0, #255 @ r2<- BB 5096 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5097 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5098 fldd d1, [r3] @ d1<- vCC 5099 fldd d0, [r2] @ d0<- vBB 5100 5101 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5102 fdivd d2, d0, d1 @ s2<- op 5103 GET_INST_OPCODE(ip) @ extract opcode from rINST 5104 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5105 fstd d2, [r9] @ vAA<- d2 5106 GOTO_OPCODE(ip) @ jump to next instruction 5107 5108 5109/* ------------------------------ */ 5110 .balign 64 5111.L_OP_REM_DOUBLE: /* 0xaf */ 5112/* File: armv5te/OP_REM_DOUBLE.S */ 5113/* EABI doesn't define a double remainder function, but libm does */ 5114/* File: armv5te/binopWide.S */ 5115 /* 5116 * Generic 64-bit binary operation. Provide an "instr" line that 5117 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5118 * This could be an ARM instruction or a function call. (If the result 5119 * comes back in a register other than r0, you can override "result".) 5120 * 5121 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5122 * vCC (r1). Useful for integer division and modulus. 5123 * 5124 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5125 * xor-long, add-double, sub-double, mul-double, div-double, 5126 * rem-double 5127 * 5128 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5129 */ 5130 /* binop vAA, vBB, vCC */ 5131 FETCH(r0, 1) @ r0<- CCBB 5132 mov r9, rINST, lsr #8 @ r9<- AA 5133 and r2, r0, #255 @ r2<- BB 5134 mov r3, r0, lsr #8 @ r3<- CC 5135 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5136 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5137 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5138 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5139 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5140 .if 0 5141 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5142 beq common_errDivideByZero 5143 .endif 5144 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5145 5146 @ optional op; may set condition codes 5147 bl fmod @ result<- op, r0-r3 changed 5148 GET_INST_OPCODE(ip) @ extract opcode from rINST 5149 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5150 GOTO_OPCODE(ip) @ jump to next instruction 5151 /* 14-17 instructions */ 5152 5153 5154/* ------------------------------ */ 5155 .balign 64 5156.L_OP_ADD_INT_2ADDR: /* 0xb0 */ 5157/* File: armv5te/OP_ADD_INT_2ADDR.S */ 5158/* File: armv5te/binop2addr.S */ 5159 /* 5160 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5161 * that specifies an instruction that performs "result = r0 op r1". 5162 * This could be an ARM instruction or a function call. (If the result 5163 * comes back in a register other than r0, you can override "result".) 5164 * 5165 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5166 * vCC (r1). Useful for integer division and modulus. 5167 * 5168 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5169 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5170 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5171 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5172 */ 5173 /* binop/2addr vA, vB */ 5174 mov r9, rINST, lsr #8 @ r9<- A+ 5175 mov r3, rINST, lsr #12 @ r3<- B 5176 and r9, r9, #15 5177 GET_VREG(r1, r3) @ r1<- vB 5178 GET_VREG(r0, r9) @ r0<- vA 5179 .if 0 5180 cmp r1, #0 @ is second operand zero? 5181 beq common_errDivideByZero 5182 .endif 5183 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5184 5185 @ optional op; may set condition codes 5186 add r0, r0, r1 @ r0<- op, r0-r3 changed 5187 GET_INST_OPCODE(ip) @ extract opcode from rINST 5188 SET_VREG(r0, r9) @ vAA<- r0 5189 GOTO_OPCODE(ip) @ jump to next instruction 5190 /* 10-13 instructions */ 5191 5192 5193/* ------------------------------ */ 5194 .balign 64 5195.L_OP_SUB_INT_2ADDR: /* 0xb1 */ 5196/* File: armv5te/OP_SUB_INT_2ADDR.S */ 5197/* File: armv5te/binop2addr.S */ 5198 /* 5199 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5200 * that specifies an instruction that performs "result = r0 op r1". 5201 * This could be an ARM instruction or a function call. (If the result 5202 * comes back in a register other than r0, you can override "result".) 5203 * 5204 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5205 * vCC (r1). Useful for integer division and modulus. 5206 * 5207 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5208 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5209 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5210 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5211 */ 5212 /* binop/2addr vA, vB */ 5213 mov r9, rINST, lsr #8 @ r9<- A+ 5214 mov r3, rINST, lsr #12 @ r3<- B 5215 and r9, r9, #15 5216 GET_VREG(r1, r3) @ r1<- vB 5217 GET_VREG(r0, r9) @ r0<- vA 5218 .if 0 5219 cmp r1, #0 @ is second operand zero? 5220 beq common_errDivideByZero 5221 .endif 5222 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5223 5224 @ optional op; may set condition codes 5225 sub r0, r0, r1 @ r0<- op, r0-r3 changed 5226 GET_INST_OPCODE(ip) @ extract opcode from rINST 5227 SET_VREG(r0, r9) @ vAA<- r0 5228 GOTO_OPCODE(ip) @ jump to next instruction 5229 /* 10-13 instructions */ 5230 5231 5232/* ------------------------------ */ 5233 .balign 64 5234.L_OP_MUL_INT_2ADDR: /* 0xb2 */ 5235/* File: armv5te/OP_MUL_INT_2ADDR.S */ 5236/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 5237/* File: armv5te/binop2addr.S */ 5238 /* 5239 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5240 * that specifies an instruction that performs "result = r0 op r1". 5241 * This could be an ARM instruction or a function call. (If the result 5242 * comes back in a register other than r0, you can override "result".) 5243 * 5244 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5245 * vCC (r1). Useful for integer division and modulus. 5246 * 5247 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5248 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5249 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5250 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5251 */ 5252 /* binop/2addr vA, vB */ 5253 mov r9, rINST, lsr #8 @ r9<- A+ 5254 mov r3, rINST, lsr #12 @ r3<- B 5255 and r9, r9, #15 5256 GET_VREG(r1, r3) @ r1<- vB 5257 GET_VREG(r0, r9) @ r0<- vA 5258 .if 0 5259 cmp r1, #0 @ is second operand zero? 5260 beq common_errDivideByZero 5261 .endif 5262 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5263 5264 @ optional op; may set condition codes 5265 mul r0, r1, r0 @ r0<- op, r0-r3 changed 5266 GET_INST_OPCODE(ip) @ extract opcode from rINST 5267 SET_VREG(r0, r9) @ vAA<- r0 5268 GOTO_OPCODE(ip) @ jump to next instruction 5269 /* 10-13 instructions */ 5270 5271 5272/* ------------------------------ */ 5273 .balign 64 5274.L_OP_DIV_INT_2ADDR: /* 0xb3 */ 5275/* File: armv5te/OP_DIV_INT_2ADDR.S */ 5276/* File: armv5te/binop2addr.S */ 5277 /* 5278 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5279 * that specifies an instruction that performs "result = r0 op r1". 5280 * This could be an ARM instruction or a function call. (If the result 5281 * comes back in a register other than r0, you can override "result".) 5282 * 5283 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5284 * vCC (r1). Useful for integer division and modulus. 5285 * 5286 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5287 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5288 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5289 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5290 */ 5291 /* binop/2addr vA, vB */ 5292 mov r9, rINST, lsr #8 @ r9<- A+ 5293 mov r3, rINST, lsr #12 @ r3<- B 5294 and r9, r9, #15 5295 GET_VREG(r1, r3) @ r1<- vB 5296 GET_VREG(r0, r9) @ r0<- vA 5297 .if 1 5298 cmp r1, #0 @ is second operand zero? 5299 beq common_errDivideByZero 5300 .endif 5301 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5302 5303 @ optional op; may set condition codes 5304 bl __aeabi_idiv @ r0<- op, r0-r3 changed 5305 GET_INST_OPCODE(ip) @ extract opcode from rINST 5306 SET_VREG(r0, r9) @ vAA<- r0 5307 GOTO_OPCODE(ip) @ jump to next instruction 5308 /* 10-13 instructions */ 5309 5310 5311/* ------------------------------ */ 5312 .balign 64 5313.L_OP_REM_INT_2ADDR: /* 0xb4 */ 5314/* File: armv5te/OP_REM_INT_2ADDR.S */ 5315/* idivmod returns quotient in r0 and remainder in r1 */ 5316/* File: armv5te/binop2addr.S */ 5317 /* 5318 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5319 * that specifies an instruction that performs "result = r0 op r1". 5320 * This could be an ARM instruction or a function call. (If the result 5321 * comes back in a register other than r0, you can override "result".) 5322 * 5323 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5324 * vCC (r1). Useful for integer division and modulus. 5325 * 5326 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5327 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5328 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5329 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5330 */ 5331 /* binop/2addr vA, vB */ 5332 mov r9, rINST, lsr #8 @ r9<- A+ 5333 mov r3, rINST, lsr #12 @ r3<- B 5334 and r9, r9, #15 5335 GET_VREG(r1, r3) @ r1<- vB 5336 GET_VREG(r0, r9) @ r0<- vA 5337 .if 1 5338 cmp r1, #0 @ is second operand zero? 5339 beq common_errDivideByZero 5340 .endif 5341 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5342 5343 @ optional op; may set condition codes 5344 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 5345 GET_INST_OPCODE(ip) @ extract opcode from rINST 5346 SET_VREG(r1, r9) @ vAA<- r1 5347 GOTO_OPCODE(ip) @ jump to next instruction 5348 /* 10-13 instructions */ 5349 5350 5351/* ------------------------------ */ 5352 .balign 64 5353.L_OP_AND_INT_2ADDR: /* 0xb5 */ 5354/* File: armv5te/OP_AND_INT_2ADDR.S */ 5355/* File: armv5te/binop2addr.S */ 5356 /* 5357 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5358 * that specifies an instruction that performs "result = r0 op r1". 5359 * This could be an ARM instruction or a function call. (If the result 5360 * comes back in a register other than r0, you can override "result".) 5361 * 5362 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5363 * vCC (r1). Useful for integer division and modulus. 5364 * 5365 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5366 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5367 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5368 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5369 */ 5370 /* binop/2addr vA, vB */ 5371 mov r9, rINST, lsr #8 @ r9<- A+ 5372 mov r3, rINST, lsr #12 @ r3<- B 5373 and r9, r9, #15 5374 GET_VREG(r1, r3) @ r1<- vB 5375 GET_VREG(r0, r9) @ r0<- vA 5376 .if 0 5377 cmp r1, #0 @ is second operand zero? 5378 beq common_errDivideByZero 5379 .endif 5380 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5381 5382 @ optional op; may set condition codes 5383 and r0, r0, r1 @ r0<- op, r0-r3 changed 5384 GET_INST_OPCODE(ip) @ extract opcode from rINST 5385 SET_VREG(r0, r9) @ vAA<- r0 5386 GOTO_OPCODE(ip) @ jump to next instruction 5387 /* 10-13 instructions */ 5388 5389 5390/* ------------------------------ */ 5391 .balign 64 5392.L_OP_OR_INT_2ADDR: /* 0xb6 */ 5393/* File: armv5te/OP_OR_INT_2ADDR.S */ 5394/* File: armv5te/binop2addr.S */ 5395 /* 5396 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5397 * that specifies an instruction that performs "result = r0 op r1". 5398 * This could be an ARM instruction or a function call. (If the result 5399 * comes back in a register other than r0, you can override "result".) 5400 * 5401 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5402 * vCC (r1). Useful for integer division and modulus. 5403 * 5404 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5405 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5406 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5407 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5408 */ 5409 /* binop/2addr vA, vB */ 5410 mov r9, rINST, lsr #8 @ r9<- A+ 5411 mov r3, rINST, lsr #12 @ r3<- B 5412 and r9, r9, #15 5413 GET_VREG(r1, r3) @ r1<- vB 5414 GET_VREG(r0, r9) @ r0<- vA 5415 .if 0 5416 cmp r1, #0 @ is second operand zero? 5417 beq common_errDivideByZero 5418 .endif 5419 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5420 5421 @ optional op; may set condition codes 5422 orr r0, r0, r1 @ r0<- op, r0-r3 changed 5423 GET_INST_OPCODE(ip) @ extract opcode from rINST 5424 SET_VREG(r0, r9) @ vAA<- r0 5425 GOTO_OPCODE(ip) @ jump to next instruction 5426 /* 10-13 instructions */ 5427 5428 5429/* ------------------------------ */ 5430 .balign 64 5431.L_OP_XOR_INT_2ADDR: /* 0xb7 */ 5432/* File: armv5te/OP_XOR_INT_2ADDR.S */ 5433/* File: armv5te/binop2addr.S */ 5434 /* 5435 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5436 * that specifies an instruction that performs "result = r0 op r1". 5437 * This could be an ARM instruction or a function call. (If the result 5438 * comes back in a register other than r0, you can override "result".) 5439 * 5440 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5441 * vCC (r1). Useful for integer division and modulus. 5442 * 5443 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5444 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5445 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5446 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5447 */ 5448 /* binop/2addr vA, vB */ 5449 mov r9, rINST, lsr #8 @ r9<- A+ 5450 mov r3, rINST, lsr #12 @ r3<- B 5451 and r9, r9, #15 5452 GET_VREG(r1, r3) @ r1<- vB 5453 GET_VREG(r0, r9) @ r0<- vA 5454 .if 0 5455 cmp r1, #0 @ is second operand zero? 5456 beq common_errDivideByZero 5457 .endif 5458 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5459 5460 @ optional op; may set condition codes 5461 eor r0, r0, r1 @ r0<- op, r0-r3 changed 5462 GET_INST_OPCODE(ip) @ extract opcode from rINST 5463 SET_VREG(r0, r9) @ vAA<- r0 5464 GOTO_OPCODE(ip) @ jump to next instruction 5465 /* 10-13 instructions */ 5466 5467 5468/* ------------------------------ */ 5469 .balign 64 5470.L_OP_SHL_INT_2ADDR: /* 0xb8 */ 5471/* File: armv5te/OP_SHL_INT_2ADDR.S */ 5472/* File: armv5te/binop2addr.S */ 5473 /* 5474 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5475 * that specifies an instruction that performs "result = r0 op r1". 5476 * This could be an ARM instruction or a function call. (If the result 5477 * comes back in a register other than r0, you can override "result".) 5478 * 5479 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5480 * vCC (r1). Useful for integer division and modulus. 5481 * 5482 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5483 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5484 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5485 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5486 */ 5487 /* binop/2addr vA, vB */ 5488 mov r9, rINST, lsr #8 @ r9<- A+ 5489 mov r3, rINST, lsr #12 @ r3<- B 5490 and r9, r9, #15 5491 GET_VREG(r1, r3) @ r1<- vB 5492 GET_VREG(r0, r9) @ r0<- vA 5493 .if 0 5494 cmp r1, #0 @ is second operand zero? 5495 beq common_errDivideByZero 5496 .endif 5497 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5498 5499 and r1, r1, #31 @ optional op; may set condition codes 5500 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 5501 GET_INST_OPCODE(ip) @ extract opcode from rINST 5502 SET_VREG(r0, r9) @ vAA<- r0 5503 GOTO_OPCODE(ip) @ jump to next instruction 5504 /* 10-13 instructions */ 5505 5506 5507/* ------------------------------ */ 5508 .balign 64 5509.L_OP_SHR_INT_2ADDR: /* 0xb9 */ 5510/* File: armv5te/OP_SHR_INT_2ADDR.S */ 5511/* File: armv5te/binop2addr.S */ 5512 /* 5513 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5514 * that specifies an instruction that performs "result = r0 op r1". 5515 * This could be an ARM instruction or a function call. (If the result 5516 * comes back in a register other than r0, you can override "result".) 5517 * 5518 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5519 * vCC (r1). Useful for integer division and modulus. 5520 * 5521 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5522 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5523 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5524 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5525 */ 5526 /* binop/2addr vA, vB */ 5527 mov r9, rINST, lsr #8 @ r9<- A+ 5528 mov r3, rINST, lsr #12 @ r3<- B 5529 and r9, r9, #15 5530 GET_VREG(r1, r3) @ r1<- vB 5531 GET_VREG(r0, r9) @ r0<- vA 5532 .if 0 5533 cmp r1, #0 @ is second operand zero? 5534 beq common_errDivideByZero 5535 .endif 5536 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5537 5538 and r1, r1, #31 @ optional op; may set condition codes 5539 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 5540 GET_INST_OPCODE(ip) @ extract opcode from rINST 5541 SET_VREG(r0, r9) @ vAA<- r0 5542 GOTO_OPCODE(ip) @ jump to next instruction 5543 /* 10-13 instructions */ 5544 5545 5546/* ------------------------------ */ 5547 .balign 64 5548.L_OP_USHR_INT_2ADDR: /* 0xba */ 5549/* File: armv5te/OP_USHR_INT_2ADDR.S */ 5550/* File: armv5te/binop2addr.S */ 5551 /* 5552 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5553 * that specifies an instruction that performs "result = r0 op r1". 5554 * This could be an ARM instruction or a function call. (If the result 5555 * comes back in a register other than r0, you can override "result".) 5556 * 5557 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5558 * vCC (r1). Useful for integer division and modulus. 5559 * 5560 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5561 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5562 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5563 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5564 */ 5565 /* binop/2addr vA, vB */ 5566 mov r9, rINST, lsr #8 @ r9<- A+ 5567 mov r3, rINST, lsr #12 @ r3<- B 5568 and r9, r9, #15 5569 GET_VREG(r1, r3) @ r1<- vB 5570 GET_VREG(r0, r9) @ r0<- vA 5571 .if 0 5572 cmp r1, #0 @ is second operand zero? 5573 beq common_errDivideByZero 5574 .endif 5575 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5576 5577 and r1, r1, #31 @ optional op; may set condition codes 5578 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 5579 GET_INST_OPCODE(ip) @ extract opcode from rINST 5580 SET_VREG(r0, r9) @ vAA<- r0 5581 GOTO_OPCODE(ip) @ jump to next instruction 5582 /* 10-13 instructions */ 5583 5584 5585/* ------------------------------ */ 5586 .balign 64 5587.L_OP_ADD_LONG_2ADDR: /* 0xbb */ 5588/* File: armv5te/OP_ADD_LONG_2ADDR.S */ 5589/* File: armv5te/binopWide2addr.S */ 5590 /* 5591 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5592 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5593 * This could be an ARM instruction or a function call. (If the result 5594 * comes back in a register other than r0, you can override "result".) 5595 * 5596 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5597 * vCC (r1). Useful for integer division and modulus. 5598 * 5599 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5600 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5601 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5602 * rem-double/2addr 5603 */ 5604 /* binop/2addr vA, vB */ 5605 mov r9, rINST, lsr #8 @ r9<- A+ 5606 mov r1, rINST, lsr #12 @ r1<- B 5607 and r9, r9, #15 5608 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5609 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5610 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5611 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5612 .if 0 5613 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5614 beq common_errDivideByZero 5615 .endif 5616 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5617 5618 adds r0, r0, r2 @ optional op; may set condition codes 5619 adc r1, r1, r3 @ result<- op, r0-r3 changed 5620 GET_INST_OPCODE(ip) @ extract opcode from rINST 5621 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5622 GOTO_OPCODE(ip) @ jump to next instruction 5623 /* 12-15 instructions */ 5624 5625 5626/* ------------------------------ */ 5627 .balign 64 5628.L_OP_SUB_LONG_2ADDR: /* 0xbc */ 5629/* File: armv5te/OP_SUB_LONG_2ADDR.S */ 5630/* File: armv5te/binopWide2addr.S */ 5631 /* 5632 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5633 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5634 * This could be an ARM instruction or a function call. (If the result 5635 * comes back in a register other than r0, you can override "result".) 5636 * 5637 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5638 * vCC (r1). Useful for integer division and modulus. 5639 * 5640 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5641 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5642 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5643 * rem-double/2addr 5644 */ 5645 /* binop/2addr vA, vB */ 5646 mov r9, rINST, lsr #8 @ r9<- A+ 5647 mov r1, rINST, lsr #12 @ r1<- B 5648 and r9, r9, #15 5649 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5650 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5651 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5652 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5653 .if 0 5654 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5655 beq common_errDivideByZero 5656 .endif 5657 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5658 5659 subs r0, r0, r2 @ optional op; may set condition codes 5660 sbc r1, r1, r3 @ result<- op, r0-r3 changed 5661 GET_INST_OPCODE(ip) @ extract opcode from rINST 5662 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5663 GOTO_OPCODE(ip) @ jump to next instruction 5664 /* 12-15 instructions */ 5665 5666 5667/* ------------------------------ */ 5668 .balign 64 5669.L_OP_MUL_LONG_2ADDR: /* 0xbd */ 5670/* File: armv5te/OP_MUL_LONG_2ADDR.S */ 5671 /* 5672 * Signed 64-bit integer multiply, "/2addr" version. 5673 * 5674 * See OP_MUL_LONG for an explanation. 5675 * 5676 * We get a little tight on registers, so to avoid looking up &fp[A] 5677 * again we stuff it into rINST. 5678 */ 5679 /* mul-long/2addr vA, vB */ 5680 mov r9, rINST, lsr #8 @ r9<- A+ 5681 mov r1, rINST, lsr #12 @ r1<- B 5682 and r9, r9, #15 5683 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5684 add rINST, rFP, r9, lsl #2 @ rINST<- &fp[A] 5685 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5686 ldmia rINST, {r0-r1} @ r0/r1<- vAA/vAA+1 5687 mul ip, r2, r1 @ ip<- ZxW 5688 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 5689 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 5690 mov r0, rINST @ r0<- &fp[A] (free up rINST) 5691 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5692 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 5693 GET_INST_OPCODE(ip) @ extract opcode from rINST 5694 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 5695 GOTO_OPCODE(ip) @ jump to next instruction 5696 5697/* ------------------------------ */ 5698 .balign 64 5699.L_OP_DIV_LONG_2ADDR: /* 0xbe */ 5700/* File: armv5te/OP_DIV_LONG_2ADDR.S */ 5701/* File: armv5te/binopWide2addr.S */ 5702 /* 5703 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5704 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5705 * This could be an ARM instruction or a function call. (If the result 5706 * comes back in a register other than r0, you can override "result".) 5707 * 5708 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5709 * vCC (r1). Useful for integer division and modulus. 5710 * 5711 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5712 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5713 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5714 * rem-double/2addr 5715 */ 5716 /* binop/2addr vA, vB */ 5717 mov r9, rINST, lsr #8 @ r9<- A+ 5718 mov r1, rINST, lsr #12 @ r1<- B 5719 and r9, r9, #15 5720 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5721 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5722 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5723 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5724 .if 1 5725 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5726 beq common_errDivideByZero 5727 .endif 5728 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5729 5730 @ optional op; may set condition codes 5731 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5732 GET_INST_OPCODE(ip) @ extract opcode from rINST 5733 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5734 GOTO_OPCODE(ip) @ jump to next instruction 5735 /* 12-15 instructions */ 5736 5737 5738/* ------------------------------ */ 5739 .balign 64 5740.L_OP_REM_LONG_2ADDR: /* 0xbf */ 5741/* File: armv5te/OP_REM_LONG_2ADDR.S */ 5742/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 5743/* File: armv5te/binopWide2addr.S */ 5744 /* 5745 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5746 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5747 * This could be an ARM instruction or a function call. (If the result 5748 * comes back in a register other than r0, you can override "result".) 5749 * 5750 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5751 * vCC (r1). Useful for integer division and modulus. 5752 * 5753 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5754 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5755 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5756 * rem-double/2addr 5757 */ 5758 /* binop/2addr vA, vB */ 5759 mov r9, rINST, lsr #8 @ r9<- A+ 5760 mov r1, rINST, lsr #12 @ r1<- B 5761 and r9, r9, #15 5762 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5763 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5764 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5765 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5766 .if 1 5767 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5768 beq common_errDivideByZero 5769 .endif 5770 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5771 5772 @ optional op; may set condition codes 5773 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5774 GET_INST_OPCODE(ip) @ extract opcode from rINST 5775 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 5776 GOTO_OPCODE(ip) @ jump to next instruction 5777 /* 12-15 instructions */ 5778 5779 5780/* ------------------------------ */ 5781 .balign 64 5782.L_OP_AND_LONG_2ADDR: /* 0xc0 */ 5783/* File: armv5te/OP_AND_LONG_2ADDR.S */ 5784/* File: armv5te/binopWide2addr.S */ 5785 /* 5786 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5787 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5788 * This could be an ARM instruction or a function call. (If the result 5789 * comes back in a register other than r0, you can override "result".) 5790 * 5791 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5792 * vCC (r1). Useful for integer division and modulus. 5793 * 5794 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5795 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5796 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5797 * rem-double/2addr 5798 */ 5799 /* binop/2addr vA, vB */ 5800 mov r9, rINST, lsr #8 @ r9<- A+ 5801 mov r1, rINST, lsr #12 @ r1<- B 5802 and r9, r9, #15 5803 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5804 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5805 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5806 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5807 .if 0 5808 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5809 beq common_errDivideByZero 5810 .endif 5811 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5812 5813 and r0, r0, r2 @ optional op; may set condition codes 5814 and r1, r1, r3 @ result<- op, r0-r3 changed 5815 GET_INST_OPCODE(ip) @ extract opcode from rINST 5816 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5817 GOTO_OPCODE(ip) @ jump to next instruction 5818 /* 12-15 instructions */ 5819 5820 5821/* ------------------------------ */ 5822 .balign 64 5823.L_OP_OR_LONG_2ADDR: /* 0xc1 */ 5824/* File: armv5te/OP_OR_LONG_2ADDR.S */ 5825/* File: armv5te/binopWide2addr.S */ 5826 /* 5827 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5828 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5829 * This could be an ARM instruction or a function call. (If the result 5830 * comes back in a register other than r0, you can override "result".) 5831 * 5832 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5833 * vCC (r1). Useful for integer division and modulus. 5834 * 5835 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5836 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5837 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5838 * rem-double/2addr 5839 */ 5840 /* binop/2addr vA, vB */ 5841 mov r9, rINST, lsr #8 @ r9<- A+ 5842 mov r1, rINST, lsr #12 @ r1<- B 5843 and r9, r9, #15 5844 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5845 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5846 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5847 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5848 .if 0 5849 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5850 beq common_errDivideByZero 5851 .endif 5852 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5853 5854 orr r0, r0, r2 @ optional op; may set condition codes 5855 orr r1, r1, r3 @ result<- op, r0-r3 changed 5856 GET_INST_OPCODE(ip) @ extract opcode from rINST 5857 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5858 GOTO_OPCODE(ip) @ jump to next instruction 5859 /* 12-15 instructions */ 5860 5861 5862/* ------------------------------ */ 5863 .balign 64 5864.L_OP_XOR_LONG_2ADDR: /* 0xc2 */ 5865/* File: armv5te/OP_XOR_LONG_2ADDR.S */ 5866/* File: armv5te/binopWide2addr.S */ 5867 /* 5868 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5869 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5870 * This could be an ARM instruction or a function call. (If the result 5871 * comes back in a register other than r0, you can override "result".) 5872 * 5873 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5874 * vCC (r1). Useful for integer division and modulus. 5875 * 5876 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5877 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5878 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5879 * rem-double/2addr 5880 */ 5881 /* binop/2addr vA, vB */ 5882 mov r9, rINST, lsr #8 @ r9<- A+ 5883 mov r1, rINST, lsr #12 @ r1<- B 5884 and r9, r9, #15 5885 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5886 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5887 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5888 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5889 .if 0 5890 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5891 beq common_errDivideByZero 5892 .endif 5893 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5894 5895 eor r0, r0, r2 @ optional op; may set condition codes 5896 eor r1, r1, r3 @ result<- op, r0-r3 changed 5897 GET_INST_OPCODE(ip) @ extract opcode from rINST 5898 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5899 GOTO_OPCODE(ip) @ jump to next instruction 5900 /* 12-15 instructions */ 5901 5902 5903/* ------------------------------ */ 5904 .balign 64 5905.L_OP_SHL_LONG_2ADDR: /* 0xc3 */ 5906/* File: armv5te/OP_SHL_LONG_2ADDR.S */ 5907 /* 5908 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5909 * 32-bit shift distance. 5910 */ 5911 /* shl-long/2addr vA, vB */ 5912 mov r9, rINST, lsr #8 @ r9<- A+ 5913 mov r3, rINST, lsr #12 @ r3<- B 5914 and r9, r9, #15 5915 GET_VREG(r2, r3) @ r2<- vB 5916 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5917 and r2, r2, #63 @ r2<- r2 & 0x3f 5918 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5919 5920 mov r1, r1, asl r2 @ r1<- r1 << r2 5921 rsb r3, r2, #32 @ r3<- 32 - r2 5922 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 5923 subs ip, r2, #32 @ ip<- r2 - 32 5924 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5925 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 5926 mov r0, r0, asl r2 @ r0<- r0 << r2 5927 b .LOP_SHL_LONG_2ADDR_finish 5928 5929/* ------------------------------ */ 5930 .balign 64 5931.L_OP_SHR_LONG_2ADDR: /* 0xc4 */ 5932/* File: armv5te/OP_SHR_LONG_2ADDR.S */ 5933 /* 5934 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5935 * 32-bit shift distance. 5936 */ 5937 /* shr-long/2addr vA, vB */ 5938 mov r9, rINST, lsr #8 @ r9<- A+ 5939 mov r3, rINST, lsr #12 @ r3<- B 5940 and r9, r9, #15 5941 GET_VREG(r2, r3) @ r2<- vB 5942 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5943 and r2, r2, #63 @ r2<- r2 & 0x3f 5944 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5945 5946 mov r0, r0, lsr r2 @ r0<- r2 >> r2 5947 rsb r3, r2, #32 @ r3<- 32 - r2 5948 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 5949 subs ip, r2, #32 @ ip<- r2 - 32 5950 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5951 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 5952 mov r1, r1, asr r2 @ r1<- r1 >> r2 5953 b .LOP_SHR_LONG_2ADDR_finish 5954 5955/* ------------------------------ */ 5956 .balign 64 5957.L_OP_USHR_LONG_2ADDR: /* 0xc5 */ 5958/* File: armv5te/OP_USHR_LONG_2ADDR.S */ 5959 /* 5960 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5961 * 32-bit shift distance. 5962 */ 5963 /* ushr-long/2addr vA, vB */ 5964 mov r9, rINST, lsr #8 @ r9<- A+ 5965 mov r3, rINST, lsr #12 @ r3<- B 5966 and r9, r9, #15 5967 GET_VREG(r2, r3) @ r2<- vB 5968 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5969 and r2, r2, #63 @ r2<- r2 & 0x3f 5970 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5971 5972 mov r0, r0, lsr r2 @ r0<- r2 >> r2 5973 rsb r3, r2, #32 @ r3<- 32 - r2 5974 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 5975 subs ip, r2, #32 @ ip<- r2 - 32 5976 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5977 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 5978 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 5979 b .LOP_USHR_LONG_2ADDR_finish 5980 5981/* ------------------------------ */ 5982 .balign 64 5983.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 5984/* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */ 5985/* File: arm-vfp/fbinop2addr.S */ 5986 /* 5987 * Generic 32-bit floating point "/2addr" binary operation. Provide 5988 * an "instr" line that specifies an instruction that performs 5989 * "s2 = s0 op s1". 5990 * 5991 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 5992 */ 5993 /* binop/2addr vA, vB */ 5994 mov r3, rINST, lsr #12 @ r3<- B 5995 mov r9, rINST, lsr #8 @ r9<- A+ 5996 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 5997 and r9, r9, #15 @ r9<- A 5998 flds s1, [r3] @ s1<- vB 5999 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6000 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6001 flds s0, [r9] @ s0<- vA 6002 6003 fadds s2, s0, s1 @ s2<- op 6004 GET_INST_OPCODE(ip) @ extract opcode from rINST 6005 fsts s2, [r9] @ vAA<- s2 6006 GOTO_OPCODE(ip) @ jump to next instruction 6007 6008 6009/* ------------------------------ */ 6010 .balign 64 6011.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 6012/* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */ 6013/* File: arm-vfp/fbinop2addr.S */ 6014 /* 6015 * Generic 32-bit floating point "/2addr" binary operation. Provide 6016 * an "instr" line that specifies an instruction that performs 6017 * "s2 = s0 op s1". 6018 * 6019 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6020 */ 6021 /* binop/2addr vA, vB */ 6022 mov r3, rINST, lsr #12 @ r3<- B 6023 mov r9, rINST, lsr #8 @ r9<- A+ 6024 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6025 and r9, r9, #15 @ r9<- A 6026 flds s1, [r3] @ s1<- vB 6027 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6028 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6029 flds s0, [r9] @ s0<- vA 6030 6031 fsubs s2, s0, s1 @ s2<- op 6032 GET_INST_OPCODE(ip) @ extract opcode from rINST 6033 fsts s2, [r9] @ vAA<- s2 6034 GOTO_OPCODE(ip) @ jump to next instruction 6035 6036 6037/* ------------------------------ */ 6038 .balign 64 6039.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 6040/* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */ 6041/* File: arm-vfp/fbinop2addr.S */ 6042 /* 6043 * Generic 32-bit floating point "/2addr" binary operation. Provide 6044 * an "instr" line that specifies an instruction that performs 6045 * "s2 = s0 op s1". 6046 * 6047 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6048 */ 6049 /* binop/2addr vA, vB */ 6050 mov r3, rINST, lsr #12 @ r3<- B 6051 mov r9, rINST, lsr #8 @ r9<- A+ 6052 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6053 and r9, r9, #15 @ r9<- A 6054 flds s1, [r3] @ s1<- vB 6055 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6056 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6057 flds s0, [r9] @ s0<- vA 6058 6059 fmuls s2, s0, s1 @ s2<- op 6060 GET_INST_OPCODE(ip) @ extract opcode from rINST 6061 fsts s2, [r9] @ vAA<- s2 6062 GOTO_OPCODE(ip) @ jump to next instruction 6063 6064 6065/* ------------------------------ */ 6066 .balign 64 6067.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 6068/* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */ 6069/* File: arm-vfp/fbinop2addr.S */ 6070 /* 6071 * Generic 32-bit floating point "/2addr" binary operation. Provide 6072 * an "instr" line that specifies an instruction that performs 6073 * "s2 = s0 op s1". 6074 * 6075 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6076 */ 6077 /* binop/2addr vA, vB */ 6078 mov r3, rINST, lsr #12 @ r3<- B 6079 mov r9, rINST, lsr #8 @ r9<- A+ 6080 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6081 and r9, r9, #15 @ r9<- A 6082 flds s1, [r3] @ s1<- vB 6083 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6084 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6085 flds s0, [r9] @ s0<- vA 6086 6087 fdivs s2, s0, s1 @ s2<- op 6088 GET_INST_OPCODE(ip) @ extract opcode from rINST 6089 fsts s2, [r9] @ vAA<- s2 6090 GOTO_OPCODE(ip) @ jump to next instruction 6091 6092 6093/* ------------------------------ */ 6094 .balign 64 6095.L_OP_REM_FLOAT_2ADDR: /* 0xca */ 6096/* File: armv5te/OP_REM_FLOAT_2ADDR.S */ 6097/* EABI doesn't define a float remainder function, but libm does */ 6098/* File: armv5te/binop2addr.S */ 6099 /* 6100 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6101 * that specifies an instruction that performs "result = r0 op r1". 6102 * This could be an ARM instruction or a function call. (If the result 6103 * comes back in a register other than r0, you can override "result".) 6104 * 6105 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6106 * vCC (r1). Useful for integer division and modulus. 6107 * 6108 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6109 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6110 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6111 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6112 */ 6113 /* binop/2addr vA, vB */ 6114 mov r9, rINST, lsr #8 @ r9<- A+ 6115 mov r3, rINST, lsr #12 @ r3<- B 6116 and r9, r9, #15 6117 GET_VREG(r1, r3) @ r1<- vB 6118 GET_VREG(r0, r9) @ r0<- vA 6119 .if 0 6120 cmp r1, #0 @ is second operand zero? 6121 beq common_errDivideByZero 6122 .endif 6123 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6124 6125 @ optional op; may set condition codes 6126 bl fmodf @ r0<- op, r0-r3 changed 6127 GET_INST_OPCODE(ip) @ extract opcode from rINST 6128 SET_VREG(r0, r9) @ vAA<- r0 6129 GOTO_OPCODE(ip) @ jump to next instruction 6130 /* 10-13 instructions */ 6131 6132 6133/* ------------------------------ */ 6134 .balign 64 6135.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 6136/* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */ 6137/* File: arm-vfp/fbinopWide2addr.S */ 6138 /* 6139 * Generic 64-bit floating point "/2addr" binary operation. Provide 6140 * an "instr" line that specifies an instruction that performs 6141 * "d2 = d0 op d1". 6142 * 6143 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6144 * div-double/2addr 6145 */ 6146 /* binop/2addr vA, vB */ 6147 mov r3, rINST, lsr #12 @ r3<- B 6148 mov r9, rINST, lsr #8 @ r9<- A+ 6149 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6150 and r9, r9, #15 @ r9<- A 6151 fldd d1, [r3] @ d1<- vB 6152 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6153 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6154 fldd d0, [r9] @ d0<- vA 6155 6156 faddd d2, d0, d1 @ d2<- op 6157 GET_INST_OPCODE(ip) @ extract opcode from rINST 6158 fstd d2, [r9] @ vAA<- d2 6159 GOTO_OPCODE(ip) @ jump to next instruction 6160 6161 6162/* ------------------------------ */ 6163 .balign 64 6164.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 6165/* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */ 6166/* File: arm-vfp/fbinopWide2addr.S */ 6167 /* 6168 * Generic 64-bit floating point "/2addr" binary operation. Provide 6169 * an "instr" line that specifies an instruction that performs 6170 * "d2 = d0 op d1". 6171 * 6172 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6173 * div-double/2addr 6174 */ 6175 /* binop/2addr vA, vB */ 6176 mov r3, rINST, lsr #12 @ r3<- B 6177 mov r9, rINST, lsr #8 @ r9<- A+ 6178 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6179 and r9, r9, #15 @ r9<- A 6180 fldd d1, [r3] @ d1<- vB 6181 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6182 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6183 fldd d0, [r9] @ d0<- vA 6184 6185 fsubd d2, d0, d1 @ d2<- op 6186 GET_INST_OPCODE(ip) @ extract opcode from rINST 6187 fstd d2, [r9] @ vAA<- d2 6188 GOTO_OPCODE(ip) @ jump to next instruction 6189 6190 6191/* ------------------------------ */ 6192 .balign 64 6193.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 6194/* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */ 6195/* File: arm-vfp/fbinopWide2addr.S */ 6196 /* 6197 * Generic 64-bit floating point "/2addr" binary operation. Provide 6198 * an "instr" line that specifies an instruction that performs 6199 * "d2 = d0 op d1". 6200 * 6201 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6202 * div-double/2addr 6203 */ 6204 /* binop/2addr vA, vB */ 6205 mov r3, rINST, lsr #12 @ r3<- B 6206 mov r9, rINST, lsr #8 @ r9<- A+ 6207 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6208 and r9, r9, #15 @ r9<- A 6209 fldd d1, [r3] @ d1<- vB 6210 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6211 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6212 fldd d0, [r9] @ d0<- vA 6213 6214 fmuld d2, d0, d1 @ d2<- op 6215 GET_INST_OPCODE(ip) @ extract opcode from rINST 6216 fstd d2, [r9] @ vAA<- d2 6217 GOTO_OPCODE(ip) @ jump to next instruction 6218 6219 6220/* ------------------------------ */ 6221 .balign 64 6222.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 6223/* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */ 6224/* File: arm-vfp/fbinopWide2addr.S */ 6225 /* 6226 * Generic 64-bit floating point "/2addr" binary operation. Provide 6227 * an "instr" line that specifies an instruction that performs 6228 * "d2 = d0 op d1". 6229 * 6230 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6231 * div-double/2addr 6232 */ 6233 /* binop/2addr vA, vB */ 6234 mov r3, rINST, lsr #12 @ r3<- B 6235 mov r9, rINST, lsr #8 @ r9<- A+ 6236 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6237 and r9, r9, #15 @ r9<- A 6238 fldd d1, [r3] @ d1<- vB 6239 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6240 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6241 fldd d0, [r9] @ d0<- vA 6242 6243 fdivd d2, d0, d1 @ d2<- op 6244 GET_INST_OPCODE(ip) @ extract opcode from rINST 6245 fstd d2, [r9] @ vAA<- d2 6246 GOTO_OPCODE(ip) @ jump to next instruction 6247 6248 6249/* ------------------------------ */ 6250 .balign 64 6251.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 6252/* File: armv5te/OP_REM_DOUBLE_2ADDR.S */ 6253/* EABI doesn't define a double remainder function, but libm does */ 6254/* File: armv5te/binopWide2addr.S */ 6255 /* 6256 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6257 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 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-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6265 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6266 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6267 * rem-double/2addr 6268 */ 6269 /* binop/2addr vA, vB */ 6270 mov r9, rINST, lsr #8 @ r9<- A+ 6271 mov r1, rINST, lsr #12 @ r1<- B 6272 and r9, r9, #15 6273 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6274 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6275 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6276 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6277 .if 0 6278 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6279 beq common_errDivideByZero 6280 .endif 6281 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6282 6283 @ optional op; may set condition codes 6284 bl fmod @ result<- op, r0-r3 changed 6285 GET_INST_OPCODE(ip) @ extract opcode from rINST 6286 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6287 GOTO_OPCODE(ip) @ jump to next instruction 6288 /* 12-15 instructions */ 6289 6290 6291/* ------------------------------ */ 6292 .balign 64 6293.L_OP_ADD_INT_LIT16: /* 0xd0 */ 6294/* File: armv5te/OP_ADD_INT_LIT16.S */ 6295/* File: armv5te/binopLit16.S */ 6296 /* 6297 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6298 * that specifies an instruction that performs "result = r0 op r1". 6299 * This could be an ARM instruction or a function call. (If the result 6300 * comes back in a register other than r0, you can override "result".) 6301 * 6302 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6303 * vCC (r1). Useful for integer division and modulus. 6304 * 6305 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6306 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6307 */ 6308 /* binop/lit16 vA, vB, #+CCCC */ 6309 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6310 mov r2, rINST, lsr #12 @ r2<- B 6311 mov r9, rINST, lsr #8 @ r9<- A+ 6312 GET_VREG(r0, r2) @ r0<- vB 6313 and r9, r9, #15 6314 .if 0 6315 cmp r1, #0 @ is second operand zero? 6316 beq common_errDivideByZero 6317 .endif 6318 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6319 6320 add r0, r0, r1 @ r0<- op, r0-r3 changed 6321 GET_INST_OPCODE(ip) @ extract opcode from rINST 6322 SET_VREG(r0, r9) @ vAA<- r0 6323 GOTO_OPCODE(ip) @ jump to next instruction 6324 /* 10-13 instructions */ 6325 6326 6327/* ------------------------------ */ 6328 .balign 64 6329.L_OP_RSUB_INT: /* 0xd1 */ 6330/* File: armv5te/OP_RSUB_INT.S */ 6331/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */ 6332/* File: armv5te/binopLit16.S */ 6333 /* 6334 * Generic 32-bit "lit16" 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/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6343 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6344 */ 6345 /* binop/lit16 vA, vB, #+CCCC */ 6346 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6347 mov r2, rINST, lsr #12 @ r2<- B 6348 mov r9, rINST, lsr #8 @ r9<- A+ 6349 GET_VREG(r0, r2) @ r0<- vB 6350 and r9, r9, #15 6351 .if 0 6352 cmp r1, #0 @ is second operand zero? 6353 beq common_errDivideByZero 6354 .endif 6355 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6356 6357 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6358 GET_INST_OPCODE(ip) @ extract opcode from rINST 6359 SET_VREG(r0, r9) @ vAA<- r0 6360 GOTO_OPCODE(ip) @ jump to next instruction 6361 /* 10-13 instructions */ 6362 6363 6364/* ------------------------------ */ 6365 .balign 64 6366.L_OP_MUL_INT_LIT16: /* 0xd2 */ 6367/* File: armv5te/OP_MUL_INT_LIT16.S */ 6368/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6369/* File: armv5te/binopLit16.S */ 6370 /* 6371 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6372 * that specifies an instruction that performs "result = r0 op r1". 6373 * This could be an ARM instruction or a function call. (If the result 6374 * comes back in a register other than r0, you can override "result".) 6375 * 6376 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6377 * vCC (r1). Useful for integer division and modulus. 6378 * 6379 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6380 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6381 */ 6382 /* binop/lit16 vA, vB, #+CCCC */ 6383 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6384 mov r2, rINST, lsr #12 @ r2<- B 6385 mov r9, rINST, lsr #8 @ r9<- A+ 6386 GET_VREG(r0, r2) @ r0<- vB 6387 and r9, r9, #15 6388 .if 0 6389 cmp r1, #0 @ is second operand zero? 6390 beq common_errDivideByZero 6391 .endif 6392 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6393 6394 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6395 GET_INST_OPCODE(ip) @ extract opcode from rINST 6396 SET_VREG(r0, r9) @ vAA<- r0 6397 GOTO_OPCODE(ip) @ jump to next instruction 6398 /* 10-13 instructions */ 6399 6400 6401/* ------------------------------ */ 6402 .balign 64 6403.L_OP_DIV_INT_LIT16: /* 0xd3 */ 6404/* File: armv5te/OP_DIV_INT_LIT16.S */ 6405/* File: armv5te/binopLit16.S */ 6406 /* 6407 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6408 * that specifies an instruction that performs "result = r0 op r1". 6409 * This could be an ARM instruction or a function call. (If the result 6410 * comes back in a register other than r0, you can override "result".) 6411 * 6412 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6413 * vCC (r1). Useful for integer division and modulus. 6414 * 6415 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6416 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6417 */ 6418 /* binop/lit16 vA, vB, #+CCCC */ 6419 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6420 mov r2, rINST, lsr #12 @ r2<- B 6421 mov r9, rINST, lsr #8 @ r9<- A+ 6422 GET_VREG(r0, r2) @ r0<- vB 6423 and r9, r9, #15 6424 .if 1 6425 cmp r1, #0 @ is second operand zero? 6426 beq common_errDivideByZero 6427 .endif 6428 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6429 6430 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6431 GET_INST_OPCODE(ip) @ extract opcode from rINST 6432 SET_VREG(r0, r9) @ vAA<- r0 6433 GOTO_OPCODE(ip) @ jump to next instruction 6434 /* 10-13 instructions */ 6435 6436 6437/* ------------------------------ */ 6438 .balign 64 6439.L_OP_REM_INT_LIT16: /* 0xd4 */ 6440/* File: armv5te/OP_REM_INT_LIT16.S */ 6441/* idivmod returns quotient in r0 and remainder in r1 */ 6442/* File: armv5te/binopLit16.S */ 6443 /* 6444 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6445 * that specifies an instruction that performs "result = r0 op r1". 6446 * This could be an ARM instruction or a function call. (If the result 6447 * comes back in a register other than r0, you can override "result".) 6448 * 6449 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6450 * vCC (r1). Useful for integer division and modulus. 6451 * 6452 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6453 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6454 */ 6455 /* binop/lit16 vA, vB, #+CCCC */ 6456 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6457 mov r2, rINST, lsr #12 @ r2<- B 6458 mov r9, rINST, lsr #8 @ r9<- A+ 6459 GET_VREG(r0, r2) @ r0<- vB 6460 and r9, r9, #15 6461 .if 1 6462 cmp r1, #0 @ is second operand zero? 6463 beq common_errDivideByZero 6464 .endif 6465 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6466 6467 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6468 GET_INST_OPCODE(ip) @ extract opcode from rINST 6469 SET_VREG(r1, r9) @ vAA<- r1 6470 GOTO_OPCODE(ip) @ jump to next instruction 6471 /* 10-13 instructions */ 6472 6473 6474/* ------------------------------ */ 6475 .balign 64 6476.L_OP_AND_INT_LIT16: /* 0xd5 */ 6477/* File: armv5te/OP_AND_INT_LIT16.S */ 6478/* File: armv5te/binopLit16.S */ 6479 /* 6480 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6481 * that specifies an instruction that performs "result = r0 op r1". 6482 * This could be an ARM instruction or a function call. (If the result 6483 * comes back in a register other than r0, you can override "result".) 6484 * 6485 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6486 * vCC (r1). Useful for integer division and modulus. 6487 * 6488 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6489 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6490 */ 6491 /* binop/lit16 vA, vB, #+CCCC */ 6492 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6493 mov r2, rINST, lsr #12 @ r2<- B 6494 mov r9, rINST, lsr #8 @ r9<- A+ 6495 GET_VREG(r0, r2) @ r0<- vB 6496 and r9, r9, #15 6497 .if 0 6498 cmp r1, #0 @ is second operand zero? 6499 beq common_errDivideByZero 6500 .endif 6501 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6502 6503 and r0, r0, r1 @ r0<- op, r0-r3 changed 6504 GET_INST_OPCODE(ip) @ extract opcode from rINST 6505 SET_VREG(r0, r9) @ vAA<- r0 6506 GOTO_OPCODE(ip) @ jump to next instruction 6507 /* 10-13 instructions */ 6508 6509 6510/* ------------------------------ */ 6511 .balign 64 6512.L_OP_OR_INT_LIT16: /* 0xd6 */ 6513/* File: armv5te/OP_OR_INT_LIT16.S */ 6514/* File: armv5te/binopLit16.S */ 6515 /* 6516 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6517 * that specifies an instruction that performs "result = r0 op r1". 6518 * This could be an ARM instruction or a function call. (If the result 6519 * comes back in a register other than r0, you can override "result".) 6520 * 6521 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6522 * vCC (r1). Useful for integer division and modulus. 6523 * 6524 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6525 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6526 */ 6527 /* binop/lit16 vA, vB, #+CCCC */ 6528 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6529 mov r2, rINST, lsr #12 @ r2<- B 6530 mov r9, rINST, lsr #8 @ r9<- A+ 6531 GET_VREG(r0, r2) @ r0<- vB 6532 and r9, r9, #15 6533 .if 0 6534 cmp r1, #0 @ is second operand zero? 6535 beq common_errDivideByZero 6536 .endif 6537 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6538 6539 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6540 GET_INST_OPCODE(ip) @ extract opcode from rINST 6541 SET_VREG(r0, r9) @ vAA<- r0 6542 GOTO_OPCODE(ip) @ jump to next instruction 6543 /* 10-13 instructions */ 6544 6545 6546/* ------------------------------ */ 6547 .balign 64 6548.L_OP_XOR_INT_LIT16: /* 0xd7 */ 6549/* File: armv5te/OP_XOR_INT_LIT16.S */ 6550/* File: armv5te/binopLit16.S */ 6551 /* 6552 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6553 * that specifies an instruction that performs "result = r0 op r1". 6554 * This could be an ARM instruction or a function call. (If the result 6555 * comes back in a register other than r0, you can override "result".) 6556 * 6557 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6558 * vCC (r1). Useful for integer division and modulus. 6559 * 6560 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6561 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6562 */ 6563 /* binop/lit16 vA, vB, #+CCCC */ 6564 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6565 mov r2, rINST, lsr #12 @ r2<- B 6566 mov r9, rINST, lsr #8 @ r9<- A+ 6567 GET_VREG(r0, r2) @ r0<- vB 6568 and r9, r9, #15 6569 .if 0 6570 cmp r1, #0 @ is second operand zero? 6571 beq common_errDivideByZero 6572 .endif 6573 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6574 6575 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6576 GET_INST_OPCODE(ip) @ extract opcode from rINST 6577 SET_VREG(r0, r9) @ vAA<- r0 6578 GOTO_OPCODE(ip) @ jump to next instruction 6579 /* 10-13 instructions */ 6580 6581 6582/* ------------------------------ */ 6583 .balign 64 6584.L_OP_ADD_INT_LIT8: /* 0xd8 */ 6585/* File: armv5te/OP_ADD_INT_LIT8.S */ 6586/* File: armv5te/binopLit8.S */ 6587 /* 6588 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6589 * that specifies an instruction that performs "result = r0 op r1". 6590 * This could be an ARM instruction or a function call. (If the result 6591 * comes back in a register other than r0, you can override "result".) 6592 * 6593 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6594 * vCC (r1). Useful for integer division and modulus. 6595 * 6596 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6597 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6598 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6599 */ 6600 /* binop/lit8 vAA, vBB, #+CC */ 6601 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6602 mov r9, rINST, lsr #8 @ r9<- AA 6603 and r2, r3, #255 @ r2<- BB 6604 GET_VREG(r0, r2) @ r0<- vBB 6605 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6606 .if 0 6607 @cmp r1, #0 @ is second operand zero? 6608 beq common_errDivideByZero 6609 .endif 6610 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6611 6612 @ optional op; may set condition codes 6613 add r0, r0, r1 @ r0<- op, r0-r3 changed 6614 GET_INST_OPCODE(ip) @ extract opcode from rINST 6615 SET_VREG(r0, r9) @ vAA<- r0 6616 GOTO_OPCODE(ip) @ jump to next instruction 6617 /* 10-12 instructions */ 6618 6619 6620/* ------------------------------ */ 6621 .balign 64 6622.L_OP_RSUB_INT_LIT8: /* 0xd9 */ 6623/* File: armv5te/OP_RSUB_INT_LIT8.S */ 6624/* File: armv5te/binopLit8.S */ 6625 /* 6626 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6627 * that specifies an instruction that performs "result = r0 op r1". 6628 * This could be an ARM instruction or a function call. (If the result 6629 * comes back in a register other than r0, you can override "result".) 6630 * 6631 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6632 * vCC (r1). Useful for integer division and modulus. 6633 * 6634 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6635 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6636 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6637 */ 6638 /* binop/lit8 vAA, vBB, #+CC */ 6639 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6640 mov r9, rINST, lsr #8 @ r9<- AA 6641 and r2, r3, #255 @ r2<- BB 6642 GET_VREG(r0, r2) @ r0<- vBB 6643 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6644 .if 0 6645 @cmp r1, #0 @ is second operand zero? 6646 beq common_errDivideByZero 6647 .endif 6648 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6649 6650 @ optional op; may set condition codes 6651 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6652 GET_INST_OPCODE(ip) @ extract opcode from rINST 6653 SET_VREG(r0, r9) @ vAA<- r0 6654 GOTO_OPCODE(ip) @ jump to next instruction 6655 /* 10-12 instructions */ 6656 6657 6658/* ------------------------------ */ 6659 .balign 64 6660.L_OP_MUL_INT_LIT8: /* 0xda */ 6661/* File: armv5te/OP_MUL_INT_LIT8.S */ 6662/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6663/* File: armv5te/binopLit8.S */ 6664 /* 6665 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6666 * that specifies an instruction that performs "result = r0 op r1". 6667 * This could be an ARM instruction or a function call. (If the result 6668 * comes back in a register other than r0, you can override "result".) 6669 * 6670 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6671 * vCC (r1). Useful for integer division and modulus. 6672 * 6673 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6674 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6675 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6676 */ 6677 /* binop/lit8 vAA, vBB, #+CC */ 6678 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6679 mov r9, rINST, lsr #8 @ r9<- AA 6680 and r2, r3, #255 @ r2<- BB 6681 GET_VREG(r0, r2) @ r0<- vBB 6682 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6683 .if 0 6684 @cmp r1, #0 @ is second operand zero? 6685 beq common_errDivideByZero 6686 .endif 6687 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6688 6689 @ optional op; may set condition codes 6690 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6691 GET_INST_OPCODE(ip) @ extract opcode from rINST 6692 SET_VREG(r0, r9) @ vAA<- r0 6693 GOTO_OPCODE(ip) @ jump to next instruction 6694 /* 10-12 instructions */ 6695 6696 6697/* ------------------------------ */ 6698 .balign 64 6699.L_OP_DIV_INT_LIT8: /* 0xdb */ 6700/* File: armv5te/OP_DIV_INT_LIT8.S */ 6701/* File: armv5te/binopLit8.S */ 6702 /* 6703 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6704 * that specifies an instruction that performs "result = r0 op r1". 6705 * This could be an ARM instruction or a function call. (If the result 6706 * comes back in a register other than r0, you can override "result".) 6707 * 6708 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6709 * vCC (r1). Useful for integer division and modulus. 6710 * 6711 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6712 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6713 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6714 */ 6715 /* binop/lit8 vAA, vBB, #+CC */ 6716 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6717 mov r9, rINST, lsr #8 @ r9<- AA 6718 and r2, r3, #255 @ r2<- BB 6719 GET_VREG(r0, r2) @ r0<- vBB 6720 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6721 .if 1 6722 @cmp r1, #0 @ is second operand zero? 6723 beq common_errDivideByZero 6724 .endif 6725 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6726 6727 @ optional op; may set condition codes 6728 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6729 GET_INST_OPCODE(ip) @ extract opcode from rINST 6730 SET_VREG(r0, r9) @ vAA<- r0 6731 GOTO_OPCODE(ip) @ jump to next instruction 6732 /* 10-12 instructions */ 6733 6734 6735/* ------------------------------ */ 6736 .balign 64 6737.L_OP_REM_INT_LIT8: /* 0xdc */ 6738/* File: armv5te/OP_REM_INT_LIT8.S */ 6739/* idivmod returns quotient in r0 and remainder in r1 */ 6740/* File: armv5te/binopLit8.S */ 6741 /* 6742 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6743 * that specifies an instruction that performs "result = r0 op r1". 6744 * This could be an ARM instruction or a function call. (If the result 6745 * comes back in a register other than r0, you can override "result".) 6746 * 6747 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6748 * vCC (r1). Useful for integer division and modulus. 6749 * 6750 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6751 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6752 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6753 */ 6754 /* binop/lit8 vAA, vBB, #+CC */ 6755 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6756 mov r9, rINST, lsr #8 @ r9<- AA 6757 and r2, r3, #255 @ r2<- BB 6758 GET_VREG(r0, r2) @ r0<- vBB 6759 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6760 .if 1 6761 @cmp r1, #0 @ is second operand zero? 6762 beq common_errDivideByZero 6763 .endif 6764 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6765 6766 @ optional op; may set condition codes 6767 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6768 GET_INST_OPCODE(ip) @ extract opcode from rINST 6769 SET_VREG(r1, r9) @ vAA<- r1 6770 GOTO_OPCODE(ip) @ jump to next instruction 6771 /* 10-12 instructions */ 6772 6773 6774/* ------------------------------ */ 6775 .balign 64 6776.L_OP_AND_INT_LIT8: /* 0xdd */ 6777/* File: armv5te/OP_AND_INT_LIT8.S */ 6778/* File: armv5te/binopLit8.S */ 6779 /* 6780 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6781 * that specifies an instruction that performs "result = r0 op r1". 6782 * This could be an ARM instruction or a function call. (If the result 6783 * comes back in a register other than r0, you can override "result".) 6784 * 6785 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6786 * vCC (r1). Useful for integer division and modulus. 6787 * 6788 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6789 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6790 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6791 */ 6792 /* binop/lit8 vAA, vBB, #+CC */ 6793 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6794 mov r9, rINST, lsr #8 @ r9<- AA 6795 and r2, r3, #255 @ r2<- BB 6796 GET_VREG(r0, r2) @ r0<- vBB 6797 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6798 .if 0 6799 @cmp r1, #0 @ is second operand zero? 6800 beq common_errDivideByZero 6801 .endif 6802 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6803 6804 @ optional op; may set condition codes 6805 and r0, r0, r1 @ r0<- op, r0-r3 changed 6806 GET_INST_OPCODE(ip) @ extract opcode from rINST 6807 SET_VREG(r0, r9) @ vAA<- r0 6808 GOTO_OPCODE(ip) @ jump to next instruction 6809 /* 10-12 instructions */ 6810 6811 6812/* ------------------------------ */ 6813 .balign 64 6814.L_OP_OR_INT_LIT8: /* 0xde */ 6815/* File: armv5te/OP_OR_INT_LIT8.S */ 6816/* File: armv5te/binopLit8.S */ 6817 /* 6818 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6819 * that specifies an instruction that performs "result = r0 op r1". 6820 * This could be an ARM instruction or a function call. (If the result 6821 * comes back in a register other than r0, you can override "result".) 6822 * 6823 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6824 * vCC (r1). Useful for integer division and modulus. 6825 * 6826 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6827 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6828 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6829 */ 6830 /* binop/lit8 vAA, vBB, #+CC */ 6831 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6832 mov r9, rINST, lsr #8 @ r9<- AA 6833 and r2, r3, #255 @ r2<- BB 6834 GET_VREG(r0, r2) @ r0<- vBB 6835 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6836 .if 0 6837 @cmp r1, #0 @ is second operand zero? 6838 beq common_errDivideByZero 6839 .endif 6840 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6841 6842 @ optional op; may set condition codes 6843 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6844 GET_INST_OPCODE(ip) @ extract opcode from rINST 6845 SET_VREG(r0, r9) @ vAA<- r0 6846 GOTO_OPCODE(ip) @ jump to next instruction 6847 /* 10-12 instructions */ 6848 6849 6850/* ------------------------------ */ 6851 .balign 64 6852.L_OP_XOR_INT_LIT8: /* 0xdf */ 6853/* File: armv5te/OP_XOR_INT_LIT8.S */ 6854/* File: armv5te/binopLit8.S */ 6855 /* 6856 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6857 * that specifies an instruction that performs "result = r0 op r1". 6858 * This could be an ARM instruction or a function call. (If the result 6859 * comes back in a register other than r0, you can override "result".) 6860 * 6861 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6862 * vCC (r1). Useful for integer division and modulus. 6863 * 6864 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6865 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6866 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6867 */ 6868 /* binop/lit8 vAA, vBB, #+CC */ 6869 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6870 mov r9, rINST, lsr #8 @ r9<- AA 6871 and r2, r3, #255 @ r2<- BB 6872 GET_VREG(r0, r2) @ r0<- vBB 6873 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6874 .if 0 6875 @cmp r1, #0 @ is second operand zero? 6876 beq common_errDivideByZero 6877 .endif 6878 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6879 6880 @ optional op; may set condition codes 6881 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6882 GET_INST_OPCODE(ip) @ extract opcode from rINST 6883 SET_VREG(r0, r9) @ vAA<- r0 6884 GOTO_OPCODE(ip) @ jump to next instruction 6885 /* 10-12 instructions */ 6886 6887 6888/* ------------------------------ */ 6889 .balign 64 6890.L_OP_SHL_INT_LIT8: /* 0xe0 */ 6891/* File: armv5te/OP_SHL_INT_LIT8.S */ 6892/* File: armv5te/binopLit8.S */ 6893 /* 6894 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6895 * that specifies an instruction that performs "result = r0 op r1". 6896 * This could be an ARM instruction or a function call. (If the result 6897 * comes back in a register other than r0, you can override "result".) 6898 * 6899 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6900 * vCC (r1). Useful for integer division and modulus. 6901 * 6902 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6903 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6904 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6905 */ 6906 /* binop/lit8 vAA, vBB, #+CC */ 6907 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6908 mov r9, rINST, lsr #8 @ r9<- AA 6909 and r2, r3, #255 @ r2<- BB 6910 GET_VREG(r0, r2) @ r0<- vBB 6911 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6912 .if 0 6913 @cmp r1, #0 @ is second operand zero? 6914 beq common_errDivideByZero 6915 .endif 6916 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6917 6918 and r1, r1, #31 @ optional op; may set condition codes 6919 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 6920 GET_INST_OPCODE(ip) @ extract opcode from rINST 6921 SET_VREG(r0, r9) @ vAA<- r0 6922 GOTO_OPCODE(ip) @ jump to next instruction 6923 /* 10-12 instructions */ 6924 6925 6926/* ------------------------------ */ 6927 .balign 64 6928.L_OP_SHR_INT_LIT8: /* 0xe1 */ 6929/* File: armv5te/OP_SHR_INT_LIT8.S */ 6930/* File: armv5te/binopLit8.S */ 6931 /* 6932 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6933 * that specifies an instruction that performs "result = r0 op r1". 6934 * This could be an ARM instruction or a function call. (If the result 6935 * comes back in a register other than r0, you can override "result".) 6936 * 6937 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6938 * vCC (r1). Useful for integer division and modulus. 6939 * 6940 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6941 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6942 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6943 */ 6944 /* binop/lit8 vAA, vBB, #+CC */ 6945 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6946 mov r9, rINST, lsr #8 @ r9<- AA 6947 and r2, r3, #255 @ r2<- BB 6948 GET_VREG(r0, r2) @ r0<- vBB 6949 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6950 .if 0 6951 @cmp r1, #0 @ is second operand zero? 6952 beq common_errDivideByZero 6953 .endif 6954 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6955 6956 and r1, r1, #31 @ optional op; may set condition codes 6957 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 6958 GET_INST_OPCODE(ip) @ extract opcode from rINST 6959 SET_VREG(r0, r9) @ vAA<- r0 6960 GOTO_OPCODE(ip) @ jump to next instruction 6961 /* 10-12 instructions */ 6962 6963 6964/* ------------------------------ */ 6965 .balign 64 6966.L_OP_USHR_INT_LIT8: /* 0xe2 */ 6967/* File: armv5te/OP_USHR_INT_LIT8.S */ 6968/* File: armv5te/binopLit8.S */ 6969 /* 6970 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6971 * that specifies an instruction that performs "result = r0 op r1". 6972 * This could be an ARM instruction or a function call. (If the result 6973 * comes back in a register other than r0, you can override "result".) 6974 * 6975 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6976 * vCC (r1). Useful for integer division and modulus. 6977 * 6978 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6979 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6980 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6981 */ 6982 /* binop/lit8 vAA, vBB, #+CC */ 6983 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6984 mov r9, rINST, lsr #8 @ r9<- AA 6985 and r2, r3, #255 @ r2<- BB 6986 GET_VREG(r0, r2) @ r0<- vBB 6987 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6988 .if 0 6989 @cmp r1, #0 @ is second operand zero? 6990 beq common_errDivideByZero 6991 .endif 6992 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6993 6994 and r1, r1, #31 @ optional op; may set condition codes 6995 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 6996 GET_INST_OPCODE(ip) @ extract opcode from rINST 6997 SET_VREG(r0, r9) @ vAA<- r0 6998 GOTO_OPCODE(ip) @ jump to next instruction 6999 /* 10-12 instructions */ 7000 7001 7002/* ------------------------------ */ 7003 .balign 64 7004.L_OP_IGET_VOLATILE: /* 0xe3 */ 7005/* File: armv5te/OP_IGET_VOLATILE.S */ 7006/* File: armv5te/OP_IGET.S */ 7007 /* 7008 * General 32-bit instance field get. 7009 * 7010 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7011 */ 7012 /* op vA, vB, field@CCCC */ 7013 mov r0, rINST, lsr #12 @ r0<- B 7014 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7015 FETCH(r1, 1) @ r1<- field ref CCCC 7016 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7017 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7018 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7019 cmp r0, #0 @ is resolved entry null? 7020 bne .LOP_IGET_VOLATILE_finish @ no, already resolved 70218: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7022 EXPORT_PC() @ resolve() could throw 7023 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7024 bl dvmResolveInstField @ r0<- resolved InstField ptr 7025 cmp r0, #0 7026 bne .LOP_IGET_VOLATILE_finish 7027 b common_exceptionThrown 7028 7029 7030/* ------------------------------ */ 7031 .balign 64 7032.L_OP_IPUT_VOLATILE: /* 0xe4 */ 7033/* File: armv5te/OP_IPUT_VOLATILE.S */ 7034/* File: armv5te/OP_IPUT.S */ 7035 /* 7036 * General 32-bit instance field put. 7037 * 7038 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 7039 */ 7040 /* op vA, vB, field@CCCC */ 7041 mov r0, rINST, lsr #12 @ r0<- B 7042 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7043 FETCH(r1, 1) @ r1<- field ref CCCC 7044 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7045 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7046 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7047 cmp r0, #0 @ is resolved entry null? 7048 bne .LOP_IPUT_VOLATILE_finish @ no, already resolved 70498: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7050 EXPORT_PC() @ resolve() could throw 7051 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7052 bl dvmResolveInstField @ r0<- resolved InstField ptr 7053 cmp r0, #0 @ success? 7054 bne .LOP_IPUT_VOLATILE_finish @ yes, finish up 7055 b common_exceptionThrown 7056 7057 7058/* ------------------------------ */ 7059 .balign 64 7060.L_OP_SGET_VOLATILE: /* 0xe5 */ 7061/* File: armv5te/OP_SGET_VOLATILE.S */ 7062/* File: armv5te/OP_SGET.S */ 7063 /* 7064 * General 32-bit SGET handler. 7065 * 7066 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7067 */ 7068 /* op vAA, field@BBBB */ 7069 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7070 FETCH(r1, 1) @ r1<- field ref BBBB 7071 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7072 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7073 cmp r0, #0 @ is resolved entry null? 7074 beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve 7075.LOP_SGET_VOLATILE_finish: @ field ptr in r0 7076 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7077 SMP_DMB @ acquiring load 7078 mov r2, rINST, lsr #8 @ r2<- AA 7079 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7080 SET_VREG(r1, r2) @ fp[AA]<- r1 7081 GET_INST_OPCODE(ip) @ extract opcode from rINST 7082 GOTO_OPCODE(ip) @ jump to next instruction 7083 7084 7085/* ------------------------------ */ 7086 .balign 64 7087.L_OP_SPUT_VOLATILE: /* 0xe6 */ 7088/* File: armv5te/OP_SPUT_VOLATILE.S */ 7089/* File: armv5te/OP_SPUT.S */ 7090 /* 7091 * General 32-bit SPUT handler. 7092 * 7093 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 7094 */ 7095 /* op vAA, field@BBBB */ 7096 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7097 FETCH(r1, 1) @ r1<- field ref BBBB 7098 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7099 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7100 cmp r0, #0 @ is resolved entry null? 7101 beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve 7102.LOP_SPUT_VOLATILE_finish: @ field ptr in r0 7103 mov r2, rINST, lsr #8 @ r2<- AA 7104 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7105 GET_VREG(r1, r2) @ r1<- fp[AA] 7106 GET_INST_OPCODE(ip) @ extract opcode from rINST 7107 SMP_DMB_ST @ releasing store 7108 str r1, [r0, #offStaticField_value] @ field<- vAA 7109 SMP_DMB 7110 GOTO_OPCODE(ip) @ jump to next instruction 7111 7112 7113/* ------------------------------ */ 7114 .balign 64 7115.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 7116/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */ 7117/* File: armv5te/OP_IGET.S */ 7118 /* 7119 * General 32-bit instance field get. 7120 * 7121 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7122 */ 7123 /* op vA, vB, field@CCCC */ 7124 mov r0, rINST, lsr #12 @ r0<- B 7125 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7126 FETCH(r1, 1) @ r1<- field ref CCCC 7127 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7128 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7129 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7130 cmp r0, #0 @ is resolved entry null? 7131 bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved 71328: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7133 EXPORT_PC() @ resolve() could throw 7134 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7135 bl dvmResolveInstField @ r0<- resolved InstField ptr 7136 cmp r0, #0 7137 bne .LOP_IGET_OBJECT_VOLATILE_finish 7138 b common_exceptionThrown 7139 7140 7141/* ------------------------------ */ 7142 .balign 64 7143.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 7144/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */ 7145/* File: armv5te/OP_IGET_WIDE.S */ 7146 /* 7147 * Wide 32-bit instance field get. 7148 */ 7149 /* iget-wide vA, vB, field@CCCC */ 7150 mov r0, rINST, lsr #12 @ r0<- B 7151 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7152 FETCH(r1, 1) @ r1<- field ref CCCC 7153 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7154 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7155 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7156 cmp r0, #0 @ is resolved entry null? 7157 bne .LOP_IGET_WIDE_VOLATILE_finish @ no, already resolved 71588: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7159 EXPORT_PC() @ resolve() could throw 7160 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7161 bl dvmResolveInstField @ r0<- resolved InstField ptr 7162 cmp r0, #0 7163 bne .LOP_IGET_WIDE_VOLATILE_finish 7164 b common_exceptionThrown 7165 7166 7167/* ------------------------------ */ 7168 .balign 64 7169.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 7170/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */ 7171/* File: armv5te/OP_IPUT_WIDE.S */ 7172 /* iput-wide vA, vB, field@CCCC */ 7173 mov r0, rINST, lsr #12 @ r0<- B 7174 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7175 FETCH(r1, 1) @ r1<- field ref CCCC 7176 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7177 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7178 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7179 cmp r0, #0 @ is resolved entry null? 7180 bne .LOP_IPUT_WIDE_VOLATILE_finish @ no, already resolved 71818: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7182 EXPORT_PC() @ resolve() could throw 7183 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7184 bl dvmResolveInstField @ r0<- resolved InstField ptr 7185 cmp r0, #0 @ success? 7186 bne .LOP_IPUT_WIDE_VOLATILE_finish @ yes, finish up 7187 b common_exceptionThrown 7188 7189 7190/* ------------------------------ */ 7191 .balign 64 7192.L_OP_SGET_WIDE_VOLATILE: /* 0xea */ 7193/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */ 7194/* File: armv5te/OP_SGET_WIDE.S */ 7195 /* 7196 * 64-bit SGET handler. 7197 */ 7198 /* sget-wide vAA, field@BBBB */ 7199 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7200 FETCH(r1, 1) @ r1<- field ref BBBB 7201 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7202 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7203 cmp r0, #0 @ is resolved entry null? 7204 beq .LOP_SGET_WIDE_VOLATILE_resolve @ yes, do resolve 7205.LOP_SGET_WIDE_VOLATILE_finish: 7206 mov r9, rINST, lsr #8 @ r9<- AA 7207 .if 1 7208 add r0, r0, #offStaticField_value @ r0<- pointer to data 7209 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 7210 .else 7211 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 7212 .endif 7213 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7214 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7215 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 7216 GET_INST_OPCODE(ip) @ extract opcode from rINST 7217 GOTO_OPCODE(ip) @ jump to next instruction 7218 7219 7220/* ------------------------------ */ 7221 .balign 64 7222.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 7223/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */ 7224/* File: armv5te/OP_SPUT_WIDE.S */ 7225 /* 7226 * 64-bit SPUT handler. 7227 */ 7228 /* sput-wide vAA, field@BBBB */ 7229 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- DvmDex 7230 FETCH(r1, 1) @ r1<- field ref BBBB 7231 ldr r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7232 mov r9, rINST, lsr #8 @ r9<- AA 7233 ldr r2, [r10, r1, lsl #2] @ r2<- resolved StaticField ptr 7234 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7235 cmp r2, #0 @ is resolved entry null? 7236 beq .LOP_SPUT_WIDE_VOLATILE_resolve @ yes, do resolve 7237.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9 7238 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7239 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 7240 GET_INST_OPCODE(r10) @ extract opcode from rINST 7241 .if 1 7242 add r2, r2, #offStaticField_value @ r2<- pointer to data 7243 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 7244 .else 7245 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 7246 .endif 7247 GOTO_OPCODE(r10) @ jump to next instruction 7248 7249 7250/* ------------------------------ */ 7251 .balign 64 7252.L_OP_BREAKPOINT: /* 0xec */ 7253/* File: armv5te/OP_BREAKPOINT.S */ 7254 /* 7255 * Breakpoint handler. 7256 * 7257 * Restart this instruction with the original opcode. By 7258 * the time we get here, the breakpoint will have already been 7259 * handled. 7260 */ 7261 mov r0, rPC 7262 bl dvmGetOriginalOpcode @ (rPC) 7263 FETCH(rINST, 0) @ reload OP_BREAKPOINT + rest of inst 7264 ldr r1, [rSELF, #offThread_mainHandlerTable] 7265 and rINST, #0xff00 7266 orr rINST, rINST, r0 7267 GOTO_OPCODE_BASE(r1, r0) 7268 7269/* ------------------------------ */ 7270 .balign 64 7271.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 7272/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */ 7273 /* 7274 * Handle a throw-verification-error instruction. This throws an 7275 * exception for an error discovered during verification. The 7276 * exception is indicated by AA, with some detail provided by BBBB. 7277 */ 7278 /* op AA, ref@BBBB */ 7279 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7280 FETCH(r2, 1) @ r2<- BBBB 7281 EXPORT_PC() @ export the PC 7282 mov r1, rINST, lsr #8 @ r1<- AA 7283 bl dvmThrowVerificationError @ always throws 7284 b common_exceptionThrown @ handle exception 7285 7286/* ------------------------------ */ 7287 .balign 64 7288.L_OP_EXECUTE_INLINE: /* 0xee */ 7289/* File: armv5te/OP_EXECUTE_INLINE.S */ 7290 /* 7291 * Execute a "native inline" instruction. 7292 * 7293 * We need to call an InlineOp4Func: 7294 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7295 * 7296 * The first four args are in r0-r3, pointer to return value storage 7297 * is on the stack. The function's return value is a flag that tells 7298 * us if an exception was thrown. 7299 * 7300 * TUNING: could maintain two tables, pointer in Thread and 7301 * swap if profiler/debuggger active. 7302 */ 7303 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 7304 ldrh r2, [rSELF, #offThread_subMode] 7305 FETCH(r10, 1) @ r10<- BBBB 7306 EXPORT_PC() @ can throw 7307 ands r2, #kSubModeDebugProfile @ Any going on? 7308 bne .LOP_EXECUTE_INLINE_debugmode @ yes - take slow path 7309.LOP_EXECUTE_INLINE_resume: 7310 add r1, rSELF, #offThread_retval @ r1<- &self->retval 7311 sub sp, sp, #8 @ make room for arg, +64 bit align 7312 mov r0, rINST, lsr #12 @ r0<- B 7313 str r1, [sp] @ push &self->retval 7314 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 7315 add sp, sp, #8 @ pop stack 7316 cmp r0, #0 @ test boolean result of inline 7317 beq common_exceptionThrown @ returned false, handle exception 7318 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7319 GET_INST_OPCODE(ip) @ extract opcode from rINST 7320 GOTO_OPCODE(ip) @ jump to next instruction 7321 7322/* ------------------------------ */ 7323 .balign 64 7324.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 7325/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */ 7326 /* 7327 * Execute a "native inline" instruction, using "/range" semantics. 7328 * Same idea as execute-inline, but we get the args differently. 7329 * 7330 * We need to call an InlineOp4Func: 7331 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7332 * 7333 * The first four args are in r0-r3, pointer to return value storage 7334 * is on the stack. The function's return value is a flag that tells 7335 * us if an exception was thrown. 7336 */ 7337 /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */ 7338 ldrh r2, [rSELF, #offThread_subMode] 7339 FETCH(r10, 1) @ r10<- BBBB 7340 EXPORT_PC() @ can throw 7341 ands r2, #kSubModeDebugProfile @ Any going on? 7342 bne .LOP_EXECUTE_INLINE_RANGE_debugmode @ yes - take slow path 7343.LOP_EXECUTE_INLINE_RANGE_resume: 7344 add r1, rSELF, #offThread_retval @ r1<- &self->retval 7345 sub sp, sp, #8 @ make room for arg, +64 bit align 7346 mov r0, rINST, lsr #8 @ r0<- AA 7347 str r1, [sp] @ push &self->retval 7348 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 7349 add sp, sp, #8 @ pop stack 7350 cmp r0, #0 @ test boolean result of inline 7351 beq common_exceptionThrown @ returned false, handle exception 7352 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7353 GET_INST_OPCODE(ip) @ extract opcode from rINST 7354 GOTO_OPCODE(ip) @ jump to next instruction 7355 7356/* ------------------------------ */ 7357 .balign 64 7358.L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */ 7359/* File: armv5te/OP_INVOKE_OBJECT_INIT_RANGE.S */ 7360 /* 7361 * Invoke Object.<init> on an object. In practice we know that 7362 * Object's nullary constructor doesn't do anything, so we just 7363 * skip it unless a debugger is active. 7364 */ 7365 FETCH(r1, 2) @ r1<- CCCC 7366 GET_VREG(r0, r1) @ r0<- "this" ptr 7367 cmp r0, #0 @ check for NULL 7368 beq common_errNullObject @ export PC and throw NPE 7369 ldr r1, [r0, #offObject_clazz] @ r1<- obj->clazz 7370 ldr r2, [r1, #offClassObject_accessFlags] @ r2<- clazz->accessFlags 7371 tst r2, #CLASS_ISFINALIZABLE @ is this class finalizable? 7372 bne .LOP_INVOKE_OBJECT_INIT_RANGE_setFinal @ yes, go 7373.LOP_INVOKE_OBJECT_INIT_RANGE_finish: 7374 ldrh r1, [rSELF, #offThread_subMode] 7375 ands r1, #kSubModeDebuggerActive @ debugger active? 7376 bne .LOP_INVOKE_OBJECT_INIT_RANGE_debugger @ Yes - skip optimization 7377 FETCH_ADVANCE_INST(2+1) @ advance to next instr, load rINST 7378 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 7379 GOTO_OPCODE(ip) @ execute it 7380 7381/* ------------------------------ */ 7382 .balign 64 7383.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 7384/* File: armv5te/OP_RETURN_VOID_BARRIER.S */ 7385 SMP_DMB_ST 7386 b common_returnFromMethod 7387 7388/* ------------------------------ */ 7389 .balign 64 7390.L_OP_IGET_QUICK: /* 0xf2 */ 7391/* File: armv5te/OP_IGET_QUICK.S */ 7392 /* For: iget-quick, iget-object-quick */ 7393 /* op vA, vB, offset@CCCC */ 7394 mov r2, rINST, lsr #12 @ r2<- B 7395 GET_VREG(r3, r2) @ r3<- object we're operating on 7396 FETCH(r1, 1) @ r1<- field byte offset 7397 cmp r3, #0 @ check object for null 7398 mov r2, rINST, lsr #8 @ r2<- A(+) 7399 beq common_errNullObject @ object was null 7400 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7401 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7402 and r2, r2, #15 7403 GET_INST_OPCODE(ip) @ extract opcode from rINST 7404 SET_VREG(r0, r2) @ fp[A]<- r0 7405 GOTO_OPCODE(ip) @ jump to next instruction 7406 7407/* ------------------------------ */ 7408 .balign 64 7409.L_OP_IGET_WIDE_QUICK: /* 0xf3 */ 7410/* File: armv5te/OP_IGET_WIDE_QUICK.S */ 7411 /* iget-wide-quick vA, vB, offset@CCCC */ 7412 mov r2, rINST, lsr #12 @ r2<- B 7413 GET_VREG(r3, r2) @ r3<- object we're operating on 7414 FETCH(ip, 1) @ ip<- field byte offset 7415 cmp r3, #0 @ check object for null 7416 mov r2, rINST, lsr #8 @ r2<- A(+) 7417 beq common_errNullObject @ object was null 7418 ldrd r0, [r3, ip] @ r0<- obj.field (64 bits, aligned) 7419 and r2, r2, #15 7420 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7421 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 7422 GET_INST_OPCODE(ip) @ extract opcode from rINST 7423 stmia r3, {r0-r1} @ fp[A]<- r0/r1 7424 GOTO_OPCODE(ip) @ jump to next instruction 7425 7426/* ------------------------------ */ 7427 .balign 64 7428.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 7429/* File: armv5te/OP_IGET_OBJECT_QUICK.S */ 7430/* File: armv5te/OP_IGET_QUICK.S */ 7431 /* For: iget-quick, iget-object-quick */ 7432 /* op vA, vB, offset@CCCC */ 7433 mov r2, rINST, lsr #12 @ r2<- B 7434 GET_VREG(r3, r2) @ r3<- object we're operating on 7435 FETCH(r1, 1) @ r1<- field byte offset 7436 cmp r3, #0 @ check object for null 7437 mov r2, rINST, lsr #8 @ r2<- A(+) 7438 beq common_errNullObject @ object was null 7439 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7440 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7441 and r2, r2, #15 7442 GET_INST_OPCODE(ip) @ extract opcode from rINST 7443 SET_VREG(r0, r2) @ fp[A]<- r0 7444 GOTO_OPCODE(ip) @ jump to next instruction 7445 7446 7447/* ------------------------------ */ 7448 .balign 64 7449.L_OP_IPUT_QUICK: /* 0xf5 */ 7450/* File: armv5te/OP_IPUT_QUICK.S */ 7451 /* For: iput-quick */ 7452 /* op vA, vB, offset@CCCC */ 7453 mov r2, rINST, lsr #12 @ r2<- B 7454 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7455 FETCH(r1, 1) @ r1<- field byte offset 7456 cmp r3, #0 @ check object for null 7457 mov r2, rINST, lsr #8 @ r2<- A(+) 7458 beq common_errNullObject @ object was null 7459 and r2, r2, #15 7460 GET_VREG(r0, r2) @ r0<- fp[A] 7461 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7462 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7463 GET_INST_OPCODE(ip) @ extract opcode from rINST 7464 GOTO_OPCODE(ip) @ jump to next instruction 7465 7466/* ------------------------------ */ 7467 .balign 64 7468.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 7469/* File: armv5te/OP_IPUT_WIDE_QUICK.S */ 7470 /* iput-wide-quick vA, vB, offset@CCCC */ 7471 mov r0, rINST, lsr #8 @ r0<- A(+) 7472 mov r1, rINST, lsr #12 @ r1<- B 7473 and r0, r0, #15 7474 GET_VREG(r2, r1) @ r2<- fp[B], the object pointer 7475 add r3, rFP, r0, lsl #2 @ r3<- &fp[A] 7476 cmp r2, #0 @ check object for null 7477 ldmia r3, {r0-r1} @ r0/r1<- fp[A] 7478 beq common_errNullObject @ object was null 7479 FETCH(r3, 1) @ r3<- field byte offset 7480 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7481 strd r0, [r2, r3] @ obj.field (64 bits, aligned)<- r0/r1 7482 GET_INST_OPCODE(ip) @ extract opcode from rINST 7483 GOTO_OPCODE(ip) @ jump to next instruction 7484 7485/* ------------------------------ */ 7486 .balign 64 7487.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 7488/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */ 7489 /* For: iput-object-quick */ 7490 /* op vA, vB, offset@CCCC */ 7491 mov r2, rINST, lsr #12 @ r2<- B 7492 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7493 FETCH(r1, 1) @ r1<- field byte offset 7494 cmp r3, #0 @ check object for null 7495 mov r2, rINST, lsr #8 @ r2<- A(+) 7496 beq common_errNullObject @ object was null 7497 and r2, r2, #15 7498 GET_VREG(r0, r2) @ r0<- fp[A] 7499 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 7500 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7501 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7502 cmp r0, #0 7503 strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head 7504 GET_INST_OPCODE(ip) @ extract opcode from rINST 7505 GOTO_OPCODE(ip) @ jump to next instruction 7506 7507/* ------------------------------ */ 7508 .balign 64 7509.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 7510/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7511 /* 7512 * Handle an optimized virtual method call. 7513 * 7514 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7515 */ 7516 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7517 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7518 FETCH(r3, 2) @ r3<- FEDC or CCCC 7519 FETCH(r1, 1) @ r1<- BBBB 7520 .if (!0) 7521 and r3, r3, #15 @ r3<- C (or stays CCCC) 7522 .endif 7523 GET_VREG(r9, r3) @ r9<- vC ("this" ptr) 7524 cmp r9, #0 @ is "this" null? 7525 beq common_errNullObject @ null "this", throw exception 7526 ldr r2, [r9, #offObject_clazz] @ r2<- thisPtr->clazz 7527 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7528 EXPORT_PC() @ invoke must export 7529 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7530 bl common_invokeMethodNoRange @ (r0=method, r9="this") 7531 7532/* ------------------------------ */ 7533 .balign 64 7534.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 7535/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */ 7536/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7537 /* 7538 * Handle an optimized virtual method call. 7539 * 7540 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7541 */ 7542 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7543 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7544 FETCH(r3, 2) @ r3<- FEDC or CCCC 7545 FETCH(r1, 1) @ r1<- BBBB 7546 .if (!1) 7547 and r3, r3, #15 @ r3<- C (or stays CCCC) 7548 .endif 7549 GET_VREG(r9, r3) @ r9<- vC ("this" ptr) 7550 cmp r9, #0 @ is "this" null? 7551 beq common_errNullObject @ null "this", throw exception 7552 ldr r2, [r9, #offObject_clazz] @ r2<- thisPtr->clazz 7553 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7554 EXPORT_PC() @ invoke must export 7555 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7556 bl common_invokeMethodRange @ (r0=method, r9="this") 7557 7558 7559/* ------------------------------ */ 7560 .balign 64 7561.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 7562/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7563 /* 7564 * Handle an optimized "super" method call. 7565 * 7566 * for: [opt] invoke-super-quick, invoke-super-quick/range 7567 */ 7568 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7569 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7570 FETCH(r10, 2) @ r10<- GFED or CCCC 7571 ldr r2, [rSELF, #offThread_method] @ r2<- current method 7572 .if (!0) 7573 and r10, r10, #15 @ r10<- D (or stays CCCC) 7574 .endif 7575 FETCH(r1, 1) @ r1<- BBBB 7576 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7577 EXPORT_PC() @ must export for invoke 7578 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7579 GET_VREG(r9, r10) @ r9<- "this" 7580 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7581 cmp r9, #0 @ null "this" ref? 7582 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7583 beq common_errNullObject @ "this" is null, throw exception 7584 bl common_invokeMethodNoRange @ (r0=method, r9="this") 7585 7586/* ------------------------------ */ 7587 .balign 64 7588.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 7589/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */ 7590/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7591 /* 7592 * Handle an optimized "super" method call. 7593 * 7594 * for: [opt] invoke-super-quick, invoke-super-quick/range 7595 */ 7596 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7597 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7598 FETCH(r10, 2) @ r10<- GFED or CCCC 7599 ldr r2, [rSELF, #offThread_method] @ r2<- current method 7600 .if (!1) 7601 and r10, r10, #15 @ r10<- D (or stays CCCC) 7602 .endif 7603 FETCH(r1, 1) @ r1<- BBBB 7604 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7605 EXPORT_PC() @ must export for invoke 7606 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7607 GET_VREG(r9, r10) @ r9<- "this" 7608 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7609 cmp r9, #0 @ null "this" ref? 7610 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7611 beq common_errNullObject @ "this" is null, throw exception 7612 bl common_invokeMethodRange @ (r0=method, r9="this") 7613 7614 7615/* ------------------------------ */ 7616 .balign 64 7617.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 7618/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */ 7619/* File: armv5te/OP_IPUT_OBJECT.S */ 7620 /* 7621 * 32-bit instance field put. 7622 * 7623 * for: iput-object, iput-object-volatile 7624 */ 7625 /* op vA, vB, field@CCCC */ 7626 mov r0, rINST, lsr #12 @ r0<- B 7627 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7628 FETCH(r1, 1) @ r1<- field ref CCCC 7629 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7630 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7631 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7632 cmp r0, #0 @ is resolved entry null? 7633 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved 76348: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7635 EXPORT_PC() @ resolve() could throw 7636 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7637 bl dvmResolveInstField @ r0<- resolved InstField ptr 7638 cmp r0, #0 @ success? 7639 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up 7640 b common_exceptionThrown 7641 7642 7643/* ------------------------------ */ 7644 .balign 64 7645.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 7646/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */ 7647/* File: armv5te/OP_SGET.S */ 7648 /* 7649 * General 32-bit SGET handler. 7650 * 7651 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7652 */ 7653 /* op vAA, field@BBBB */ 7654 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7655 FETCH(r1, 1) @ r1<- field ref BBBB 7656 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7657 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7658 cmp r0, #0 @ is resolved entry null? 7659 beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve 7660.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0 7661 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7662 SMP_DMB @ acquiring load 7663 mov r2, rINST, lsr #8 @ r2<- AA 7664 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7665 SET_VREG(r1, r2) @ fp[AA]<- r1 7666 GET_INST_OPCODE(ip) @ extract opcode from rINST 7667 GOTO_OPCODE(ip) @ jump to next instruction 7668 7669 7670/* ------------------------------ */ 7671 .balign 64 7672.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 7673/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */ 7674/* File: armv5te/OP_SPUT_OBJECT.S */ 7675 /* 7676 * 32-bit SPUT handler for objects 7677 * 7678 * for: sput-object, sput-object-volatile 7679 */ 7680 /* op vAA, field@BBBB */ 7681 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7682 FETCH(r1, 1) @ r1<- field ref BBBB 7683 ldr r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields 7684 ldr r0, [r10, r1, lsl #2] @ r0<- resolved StaticField ptr 7685 cmp r0, #0 @ is resolved entry null? 7686 beq .LOP_SPUT_OBJECT_VOLATILE_resolve @ yes, do resolve 7687.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0 7688 mov r2, rINST, lsr #8 @ r2<- AA 7689 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7690 GET_VREG(r1, r2) @ r1<- fp[AA] 7691 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 7692 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 7693 GET_INST_OPCODE(ip) @ extract opcode from rINST 7694 SMP_DMB_ST @ releasing store 7695 b .LOP_SPUT_OBJECT_VOLATILE_end 7696 7697 7698/* ------------------------------ */ 7699 .balign 64 7700.L_OP_UNUSED_FF: /* 0xff */ 7701/* File: armv5te/OP_UNUSED_FF.S */ 7702/* File: armv5te/unused.S */ 7703 bl common_abort 7704 7705 7706 .balign 64 7707 .size dvmAsmInstructionStart, .-dvmAsmInstructionStart 7708 .global dvmAsmInstructionEnd 7709dvmAsmInstructionEnd: 7710 7711/* 7712 * =========================================================================== 7713 * Sister implementations 7714 * =========================================================================== 7715 */ 7716 .global dvmAsmSisterStart 7717 .type dvmAsmSisterStart, %function 7718 .text 7719 .balign 4 7720dvmAsmSisterStart: 7721 7722/* continuation for OP_CONST_STRING */ 7723 7724 /* 7725 * Continuation if the String has not yet been resolved. 7726 * r1: BBBB (String ref) 7727 * r9: target register 7728 */ 7729.LOP_CONST_STRING_resolve: 7730 EXPORT_PC() 7731 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7732 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7733 bl dvmResolveString @ r0<- String reference 7734 cmp r0, #0 @ failed? 7735 beq common_exceptionThrown @ yup, handle the exception 7736 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7737 SET_VREG(r0, r9) @ vAA<- r0 7738 GET_INST_OPCODE(ip) @ extract opcode from rINST 7739 GOTO_OPCODE(ip) @ jump to next instruction 7740 7741/* continuation for OP_CONST_STRING_JUMBO */ 7742 7743 /* 7744 * Continuation if the String has not yet been resolved. 7745 * r1: BBBBBBBB (String ref) 7746 * r9: target register 7747 */ 7748.LOP_CONST_STRING_JUMBO_resolve: 7749 EXPORT_PC() 7750 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7751 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7752 bl dvmResolveString @ r0<- String reference 7753 cmp r0, #0 @ failed? 7754 beq common_exceptionThrown @ yup, handle the exception 7755 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7756 SET_VREG(r0, r9) @ vAA<- r0 7757 GET_INST_OPCODE(ip) @ extract opcode from rINST 7758 GOTO_OPCODE(ip) @ jump to next instruction 7759 7760/* continuation for OP_CONST_CLASS */ 7761 7762 /* 7763 * Continuation if the Class has not yet been resolved. 7764 * r1: BBBB (Class ref) 7765 * r9: target register 7766 */ 7767.LOP_CONST_CLASS_resolve: 7768 EXPORT_PC() 7769 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7770 mov r2, #1 @ r2<- true 7771 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7772 bl dvmResolveClass @ r0<- Class reference 7773 cmp r0, #0 @ failed? 7774 beq common_exceptionThrown @ yup, handle the exception 7775 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7776 SET_VREG(r0, r9) @ vAA<- r0 7777 GET_INST_OPCODE(ip) @ extract opcode from rINST 7778 GOTO_OPCODE(ip) @ jump to next instruction 7779 7780/* continuation for OP_CHECK_CAST */ 7781 7782 /* 7783 * Trivial test failed, need to perform full check. This is common. 7784 * r0 holds obj->clazz 7785 * r1 holds desired class resolved from BBBB 7786 * r9 holds object 7787 */ 7788.LOP_CHECK_CAST_fullcheck: 7789 mov r10, r1 @ avoid ClassObject getting clobbered 7790 bl dvmInstanceofNonTrivial @ r0<- boolean result 7791 cmp r0, #0 @ failed? 7792 bne .LOP_CHECK_CAST_okay @ no, success 7793 7794 @ A cast has failed. We need to throw a ClassCastException. 7795 EXPORT_PC() @ about to throw 7796 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 7797 mov r1, r10 @ r1<- desired class 7798 bl dvmThrowClassCastException 7799 b common_exceptionThrown 7800 7801 /* 7802 * Resolution required. This is the least-likely path. 7803 * 7804 * r2 holds BBBB 7805 * r9 holds object 7806 */ 7807.LOP_CHECK_CAST_resolve: 7808 EXPORT_PC() @ resolve() could throw 7809 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 7810 mov r1, r2 @ r1<- BBBB 7811 mov r2, #0 @ r2<- false 7812 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7813 bl dvmResolveClass @ r0<- resolved ClassObject ptr 7814 cmp r0, #0 @ got null? 7815 beq common_exceptionThrown @ yes, handle exception 7816 mov r1, r0 @ r1<- class resolved from BBB 7817 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 7818 b .LOP_CHECK_CAST_resolved @ pick up where we left off 7819 7820/* continuation for OP_INSTANCE_OF */ 7821 7822 /* 7823 * Trivial test failed, need to perform full check. This is common. 7824 * r0 holds obj->clazz 7825 * r1 holds class resolved from BBBB 7826 * r9 holds A 7827 */ 7828.LOP_INSTANCE_OF_fullcheck: 7829 bl dvmInstanceofNonTrivial @ r0<- boolean result 7830 @ fall through to OP_INSTANCE_OF_store 7831 7832 /* 7833 * r0 holds boolean result 7834 * r9 holds A 7835 */ 7836.LOP_INSTANCE_OF_store: 7837 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7838 SET_VREG(r0, r9) @ vA<- r0 7839 GET_INST_OPCODE(ip) @ extract opcode from rINST 7840 GOTO_OPCODE(ip) @ jump to next instruction 7841 7842 /* 7843 * Trivial test succeeded, save and bail. 7844 * r9 holds A 7845 */ 7846.LOP_INSTANCE_OF_trivial: 7847 mov r0, #1 @ indicate success 7848 @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper 7849 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7850 SET_VREG(r0, r9) @ vA<- r0 7851 GET_INST_OPCODE(ip) @ extract opcode from rINST 7852 GOTO_OPCODE(ip) @ jump to next instruction 7853 7854 /* 7855 * Resolution required. This is the least-likely path. 7856 * 7857 * r3 holds BBBB 7858 * r9 holds A 7859 */ 7860.LOP_INSTANCE_OF_resolve: 7861 EXPORT_PC() @ resolve() could throw 7862 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7863 mov r1, r3 @ r1<- BBBB 7864 mov r2, #1 @ r2<- true 7865 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 7866 bl dvmResolveClass @ r0<- resolved ClassObject ptr 7867 cmp r0, #0 @ got null? 7868 beq common_exceptionThrown @ yes, handle exception 7869 mov r1, r0 @ r1<- class resolved from BBB 7870 mov r3, rINST, lsr #12 @ r3<- B 7871 GET_VREG(r0, r3) @ r0<- vB (object) 7872 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 7873 b .LOP_INSTANCE_OF_resolved @ pick up where we left off 7874 7875/* continuation for OP_NEW_INSTANCE */ 7876 7877 .balign 32 @ minimize cache lines 7878.LOP_NEW_INSTANCE_finish: @ r0=new object 7879 mov r3, rINST, lsr #8 @ r3<- AA 7880 cmp r0, #0 @ failed? 7881#if defined(WITH_JIT) 7882 /* 7883 * The JIT needs the class to be fully resolved before it can 7884 * include this instruction in a trace. 7885 */ 7886 ldrh r1, [rSELF, #offThread_subMode] 7887 beq common_exceptionThrown @ yes, handle the exception 7888 ands r1, #kSubModeJitTraceBuild @ under construction? 7889 bne .LOP_NEW_INSTANCE_jitCheck 7890#else 7891 beq common_exceptionThrown @ yes, handle the exception 7892#endif 7893.LOP_NEW_INSTANCE_end: 7894 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7895 SET_VREG(r0, r3) @ vAA<- r0 7896 GET_INST_OPCODE(ip) @ extract opcode from rINST 7897 GOTO_OPCODE(ip) @ jump to next instruction 7898 7899#if defined(WITH_JIT) 7900 /* 7901 * Check to see if we need to stop the trace building early. 7902 * r0: new object 7903 * r3: vAA 7904 */ 7905.LOP_NEW_INSTANCE_jitCheck: 7906 ldr r1, [r10] @ reload resolved class 7907 cmp r1, #0 @ okay? 7908 bne .LOP_NEW_INSTANCE_end @ yes, finish 7909 mov r9, r0 @ preserve new object 7910 mov r10, r3 @ preserve vAA 7911 mov r0, rSELF 7912 mov r1, rPC 7913 bl dvmJitEndTraceSelect @ (self, pc) 7914 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7915 SET_VREG(r9, r10) @ vAA<- new object 7916 GET_INST_OPCODE(ip) @ extract opcode from rINST 7917 GOTO_OPCODE(ip) @ jump to next instruction 7918#endif 7919 7920 /* 7921 * Class initialization required. 7922 * 7923 * r0 holds class object 7924 */ 7925.LOP_NEW_INSTANCE_needinit: 7926 mov r9, r0 @ save r0 7927 bl dvmInitClass @ initialize class 7928 cmp r0, #0 @ check boolean result 7929 mov r0, r9 @ restore r0 7930 bne .LOP_NEW_INSTANCE_initialized @ success, continue 7931 b common_exceptionThrown @ failed, deal with init exception 7932 7933 /* 7934 * Resolution required. This is the least-likely path. 7935 * 7936 * r1 holds BBBB 7937 */ 7938.LOP_NEW_INSTANCE_resolve: 7939 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 7940 mov r2, #0 @ r2<- false 7941 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7942 bl dvmResolveClass @ r0<- resolved ClassObject ptr 7943 cmp r0, #0 @ got null? 7944 bne .LOP_NEW_INSTANCE_resolved @ no, continue 7945 b common_exceptionThrown @ yes, handle exception 7946 7947/* continuation for OP_NEW_ARRAY */ 7948 7949 7950 /* 7951 * Resolve class. (This is an uncommon case.) 7952 * 7953 * r1 holds array length 7954 * r2 holds class ref CCCC 7955 */ 7956.LOP_NEW_ARRAY_resolve: 7957 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 7958 mov r9, r1 @ r9<- length (save) 7959 mov r1, r2 @ r1<- CCCC 7960 mov r2, #0 @ r2<- false 7961 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7962 bl dvmResolveClass @ r0<- call(clazz, ref) 7963 cmp r0, #0 @ got null? 7964 mov r1, r9 @ r1<- length (restore) 7965 beq common_exceptionThrown @ yes, handle exception 7966 @ fall through to OP_NEW_ARRAY_finish 7967 7968 /* 7969 * Finish allocation. 7970 * 7971 * r0 holds class 7972 * r1 holds array length 7973 */ 7974.LOP_NEW_ARRAY_finish: 7975 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 7976 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 7977 cmp r0, #0 @ failed? 7978 mov r2, rINST, lsr #8 @ r2<- A+ 7979 beq common_exceptionThrown @ yes, handle the exception 7980 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7981 and r2, r2, #15 @ r2<- A 7982 GET_INST_OPCODE(ip) @ extract opcode from rINST 7983 SET_VREG(r0, r2) @ vA<- r0 7984 GOTO_OPCODE(ip) @ jump to next instruction 7985 7986/* continuation for OP_FILLED_NEW_ARRAY */ 7987 7988 /* 7989 * On entry: 7990 * r0 holds array class 7991 * r10 holds AA or BA 7992 */ 7993.LOP_FILLED_NEW_ARRAY_continue: 7994 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 7995 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 7996 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 7997 .if 0 7998 mov r1, r10 @ r1<- AA (length) 7999 .else 8000 mov r1, r10, lsr #4 @ r1<- B (length) 8001 .endif 8002 cmp rINST, #'I' @ array of ints? 8003 cmpne rINST, #'L' @ array of objects? 8004 cmpne rINST, #'[' @ array of arrays? 8005 mov r9, r1 @ save length in r9 8006 bne .LOP_FILLED_NEW_ARRAY_notimpl @ no, not handled yet 8007 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 8008 cmp r0, #0 @ null return? 8009 beq common_exceptionThrown @ alloc failed, handle exception 8010 8011 FETCH(r1, 2) @ r1<- FEDC or CCCC 8012 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 8013 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 8014 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 8015 subs r9, r9, #1 @ length--, check for neg 8016 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 8017 bmi 2f @ was zero, bail 8018 8019 @ copy values from registers into the array 8020 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 8021 .if 0 8022 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 80231: ldr r3, [r2], #4 @ r3<- *r2++ 8024 subs r9, r9, #1 @ count-- 8025 str r3, [r0], #4 @ *contents++ = vX 8026 bpl 1b 8027 @ continue at 2 8028 .else 8029 cmp r9, #4 @ length was initially 5? 8030 and r2, r10, #15 @ r2<- A 8031 bne 1f @ <= 4 args, branch 8032 GET_VREG(r3, r2) @ r3<- vA 8033 sub r9, r9, #1 @ count-- 8034 str r3, [r0, #16] @ contents[4] = vA 80351: and r2, r1, #15 @ r2<- F/E/D/C 8036 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 8037 mov r1, r1, lsr #4 @ r1<- next reg in low 4 8038 subs r9, r9, #1 @ count-- 8039 str r3, [r0], #4 @ *contents++ = vX 8040 bpl 1b 8041 @ continue at 2 8042 .endif 8043 80442: 8045 ldr r0, [rSELF, #offThread_retval] @ r0<- object 8046 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 8047 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8048 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 8049 cmp r1, #'I' @ Is int array? 8050 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 8051 GOTO_OPCODE(ip) @ execute it 8052 8053 /* 8054 * Throw an exception indicating that we have not implemented this 8055 * mode of filled-new-array. 8056 */ 8057.LOP_FILLED_NEW_ARRAY_notimpl: 8058 ldr r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY 80593: add r0, pc 8060 bl dvmThrowInternalError 8061 b common_exceptionThrown 8062 8063 /* 8064 * Ideally we'd only define this once, but depending on layout we can 8065 * exceed the range of the load above. 8066 */ 8067 8068.L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY: 8069 .word PCREL_REF(.LstrFilledNewArrayNotImpl,3b) 8070 8071/* continuation for OP_FILLED_NEW_ARRAY_RANGE */ 8072 8073 /* 8074 * On entry: 8075 * r0 holds array class 8076 * r10 holds AA or BA 8077 */ 8078.LOP_FILLED_NEW_ARRAY_RANGE_continue: 8079 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 8080 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 8081 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 8082 .if 1 8083 mov r1, r10 @ r1<- AA (length) 8084 .else 8085 mov r1, r10, lsr #4 @ r1<- B (length) 8086 .endif 8087 cmp rINST, #'I' @ array of ints? 8088 cmpne rINST, #'L' @ array of objects? 8089 cmpne rINST, #'[' @ array of arrays? 8090 mov r9, r1 @ save length in r9 8091 bne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl @ no, not handled yet 8092 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 8093 cmp r0, #0 @ null return? 8094 beq common_exceptionThrown @ alloc failed, handle exception 8095 8096 FETCH(r1, 2) @ r1<- FEDC or CCCC 8097 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 8098 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 8099 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 8100 subs r9, r9, #1 @ length--, check for neg 8101 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 8102 bmi 2f @ was zero, bail 8103 8104 @ copy values from registers into the array 8105 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 8106 .if 1 8107 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 81081: ldr r3, [r2], #4 @ r3<- *r2++ 8109 subs r9, r9, #1 @ count-- 8110 str r3, [r0], #4 @ *contents++ = vX 8111 bpl 1b 8112 @ continue at 2 8113 .else 8114 cmp r9, #4 @ length was initially 5? 8115 and r2, r10, #15 @ r2<- A 8116 bne 1f @ <= 4 args, branch 8117 GET_VREG(r3, r2) @ r3<- vA 8118 sub r9, r9, #1 @ count-- 8119 str r3, [r0, #16] @ contents[4] = vA 81201: and r2, r1, #15 @ r2<- F/E/D/C 8121 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 8122 mov r1, r1, lsr #4 @ r1<- next reg in low 4 8123 subs r9, r9, #1 @ count-- 8124 str r3, [r0], #4 @ *contents++ = vX 8125 bpl 1b 8126 @ continue at 2 8127 .endif 8128 81292: 8130 ldr r0, [rSELF, #offThread_retval] @ r0<- object 8131 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 8132 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8133 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 8134 cmp r1, #'I' @ Is int array? 8135 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 8136 GOTO_OPCODE(ip) @ execute it 8137 8138 /* 8139 * Throw an exception indicating that we have not implemented this 8140 * mode of filled-new-array. 8141 */ 8142.LOP_FILLED_NEW_ARRAY_RANGE_notimpl: 8143 ldr r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE 81443: add r0, pc 8145 bl dvmThrowInternalError 8146 b common_exceptionThrown 8147 8148 /* 8149 * Ideally we'd only define this once, but depending on layout we can 8150 * exceed the range of the load above. 8151 */ 8152 8153.L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE: 8154 .word PCREL_REF(.LstrFilledNewArrayNotImpl,3b) 8155 8156/* continuation for OP_CMPL_FLOAT */ 8157.LOP_CMPL_FLOAT_finish: 8158 SET_VREG(r0, r9) @ vAA<- r0 8159 GOTO_OPCODE(ip) @ jump to next instruction 8160 8161/* continuation for OP_CMPG_FLOAT */ 8162.LOP_CMPG_FLOAT_finish: 8163 SET_VREG(r0, r9) @ vAA<- r0 8164 GOTO_OPCODE(ip) @ jump to next instruction 8165 8166/* continuation for OP_CMPL_DOUBLE */ 8167.LOP_CMPL_DOUBLE_finish: 8168 SET_VREG(r0, r9) @ vAA<- r0 8169 GOTO_OPCODE(ip) @ jump to next instruction 8170 8171/* continuation for OP_CMPG_DOUBLE */ 8172.LOP_CMPG_DOUBLE_finish: 8173 SET_VREG(r0, r9) @ vAA<- r0 8174 GOTO_OPCODE(ip) @ jump to next instruction 8175 8176/* continuation for OP_CMP_LONG */ 8177 8178.LOP_CMP_LONG_less: 8179 mvn r1, #0 @ r1<- -1 8180 @ Want to cond code the next mov so we can avoid branch, but don't see it; 8181 @ instead, we just replicate the tail end. 8182 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8183 SET_VREG(r1, r9) @ vAA<- r1 8184 GET_INST_OPCODE(ip) @ extract opcode from rINST 8185 GOTO_OPCODE(ip) @ jump to next instruction 8186 8187.LOP_CMP_LONG_greater: 8188 mov r1, #1 @ r1<- 1 8189 @ fall through to _finish 8190 8191.LOP_CMP_LONG_finish: 8192 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8193 SET_VREG(r1, r9) @ vAA<- r1 8194 GET_INST_OPCODE(ip) @ extract opcode from rINST 8195 GOTO_OPCODE(ip) @ jump to next instruction 8196 8197/* continuation for OP_AGET_WIDE */ 8198 8199.LOP_AGET_WIDE_finish: 8200 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8201 ldrd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 8202 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 8203 GET_INST_OPCODE(ip) @ extract opcode from rINST 8204 stmia r9, {r2-r3} @ vAA/vAA+1<- r2/r3 8205 GOTO_OPCODE(ip) @ jump to next instruction 8206 8207/* continuation for OP_APUT_WIDE */ 8208 8209.LOP_APUT_WIDE_finish: 8210 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8211 ldmia r9, {r2-r3} @ r2/r3<- vAA/vAA+1 8212 GET_INST_OPCODE(ip) @ extract opcode from rINST 8213 strd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 8214 GOTO_OPCODE(ip) @ jump to next instruction 8215 8216/* continuation for OP_APUT_OBJECT */ 8217 /* 8218 * On entry: 8219 * rINST = vBB (arrayObj) 8220 * r9 = vAA (obj) 8221 * r10 = offset into array (vBB + vCC * width) 8222 */ 8223.LOP_APUT_OBJECT_finish: 8224 cmp r9, #0 @ storing null reference? 8225 beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks 8226 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 8227 ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz 8228 bl dvmCanPutArrayElement @ test object type vs. array type 8229 cmp r0, #0 @ okay? 8230 beq .LOP_APUT_OBJECT_throw @ no 8231 mov r1, rINST @ r1<- arrayObj 8232 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8233 ldr r2, [rSELF, #offThread_cardTable] @ get biased CT base 8234 add r10, #offArrayObject_contents @ r0<- pointer to slot 8235 GET_INST_OPCODE(ip) @ extract opcode from rINST 8236 str r9, [r10] @ vBB[vCC]<- vAA 8237 strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head 8238 GOTO_OPCODE(ip) @ jump to next instruction 8239.LOP_APUT_OBJECT_skip_check: 8240 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8241 str r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA 8242 GET_INST_OPCODE(ip) @ extract opcode from rINST 8243 GOTO_OPCODE(ip) @ jump to next instruction 8244.LOP_APUT_OBJECT_throw: 8245 @ The types don't match. We need to throw an ArrayStoreException. 8246 ldr r0, [r9, #offObject_clazz] 8247 ldr r1, [rINST, #offObject_clazz] 8248 EXPORT_PC() 8249 bl dvmThrowArrayStoreExceptionIncompatibleElement 8250 b common_exceptionThrown 8251 8252/* continuation for OP_IGET */ 8253 8254 /* 8255 * Currently: 8256 * r0 holds resolved field 8257 * r9 holds object 8258 */ 8259.LOP_IGET_finish: 8260 @bl common_squeak0 8261 cmp r9, #0 @ check object for null 8262 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8263 beq common_errNullObject @ object was null 8264 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8265 @ no-op @ acquiring load 8266 mov r2, rINST, lsr #8 @ r2<- A+ 8267 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8268 and r2, r2, #15 @ r2<- A 8269 GET_INST_OPCODE(ip) @ extract opcode from rINST 8270 SET_VREG(r0, r2) @ fp[A]<- r0 8271 GOTO_OPCODE(ip) @ jump to next instruction 8272 8273/* continuation for OP_IGET_WIDE */ 8274 8275 /* 8276 * Currently: 8277 * r0 holds resolved field 8278 * r9 holds object 8279 */ 8280.LOP_IGET_WIDE_finish: 8281 cmp r9, #0 @ check object for null 8282 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8283 beq common_errNullObject @ object was null 8284 .if 0 8285 add r0, r9, r3 @ r0<- address of field 8286 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 8287 .else 8288 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 8289 .endif 8290 mov r2, rINST, lsr #8 @ r2<- A+ 8291 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8292 and r2, r2, #15 @ r2<- A 8293 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 8294 GET_INST_OPCODE(ip) @ extract opcode from rINST 8295 stmia r3, {r0-r1} @ fp[A]<- r0/r1 8296 GOTO_OPCODE(ip) @ jump to next instruction 8297 8298/* continuation for OP_IGET_OBJECT */ 8299 8300 /* 8301 * Currently: 8302 * r0 holds resolved field 8303 * r9 holds object 8304 */ 8305.LOP_IGET_OBJECT_finish: 8306 @bl common_squeak0 8307 cmp r9, #0 @ check object for null 8308 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8309 beq common_errNullObject @ object was null 8310 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8311 @ no-op @ acquiring load 8312 mov r2, rINST, lsr #8 @ r2<- A+ 8313 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8314 and r2, r2, #15 @ r2<- A 8315 GET_INST_OPCODE(ip) @ extract opcode from rINST 8316 SET_VREG(r0, r2) @ fp[A]<- r0 8317 GOTO_OPCODE(ip) @ jump to next instruction 8318 8319/* continuation for OP_IGET_BOOLEAN */ 8320 8321 /* 8322 * Currently: 8323 * r0 holds resolved field 8324 * r9 holds object 8325 */ 8326.LOP_IGET_BOOLEAN_finish: 8327 @bl common_squeak1 8328 cmp r9, #0 @ check object for null 8329 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8330 beq common_errNullObject @ object was null 8331 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8332 @ no-op @ acquiring load 8333 mov r2, rINST, lsr #8 @ r2<- A+ 8334 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8335 and r2, r2, #15 @ r2<- A 8336 GET_INST_OPCODE(ip) @ extract opcode from rINST 8337 SET_VREG(r0, r2) @ fp[A]<- r0 8338 GOTO_OPCODE(ip) @ jump to next instruction 8339 8340/* continuation for OP_IGET_BYTE */ 8341 8342 /* 8343 * Currently: 8344 * r0 holds resolved field 8345 * r9 holds object 8346 */ 8347.LOP_IGET_BYTE_finish: 8348 @bl common_squeak2 8349 cmp r9, #0 @ check object for null 8350 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8351 beq common_errNullObject @ object was null 8352 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8353 @ no-op @ acquiring load 8354 mov r2, rINST, lsr #8 @ r2<- A+ 8355 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8356 and r2, r2, #15 @ r2<- A 8357 GET_INST_OPCODE(ip) @ extract opcode from rINST 8358 SET_VREG(r0, r2) @ fp[A]<- r0 8359 GOTO_OPCODE(ip) @ jump to next instruction 8360 8361/* continuation for OP_IGET_CHAR */ 8362 8363 /* 8364 * Currently: 8365 * r0 holds resolved field 8366 * r9 holds object 8367 */ 8368.LOP_IGET_CHAR_finish: 8369 @bl common_squeak3 8370 cmp r9, #0 @ check object for null 8371 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8372 beq common_errNullObject @ object was null 8373 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8374 @ no-op @ acquiring load 8375 mov r2, rINST, lsr #8 @ r2<- A+ 8376 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8377 and r2, r2, #15 @ r2<- A 8378 GET_INST_OPCODE(ip) @ extract opcode from rINST 8379 SET_VREG(r0, r2) @ fp[A]<- r0 8380 GOTO_OPCODE(ip) @ jump to next instruction 8381 8382/* continuation for OP_IGET_SHORT */ 8383 8384 /* 8385 * Currently: 8386 * r0 holds resolved field 8387 * r9 holds object 8388 */ 8389.LOP_IGET_SHORT_finish: 8390 @bl common_squeak4 8391 cmp r9, #0 @ check object for null 8392 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8393 beq common_errNullObject @ object was null 8394 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 8395 @ no-op @ acquiring load 8396 mov r2, rINST, lsr #8 @ r2<- A+ 8397 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8398 and r2, r2, #15 @ r2<- A 8399 GET_INST_OPCODE(ip) @ extract opcode from rINST 8400 SET_VREG(r0, r2) @ fp[A]<- r0 8401 GOTO_OPCODE(ip) @ jump to next instruction 8402 8403/* continuation for OP_IPUT */ 8404 8405 /* 8406 * Currently: 8407 * r0 holds resolved field 8408 * r9 holds object 8409 */ 8410.LOP_IPUT_finish: 8411 @bl common_squeak0 8412 mov r1, rINST, lsr #8 @ r1<- A+ 8413 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8414 and r1, r1, #15 @ r1<- A 8415 cmp r9, #0 @ check object for null 8416 GET_VREG(r0, r1) @ r0<- fp[A] 8417 beq common_errNullObject @ object was null 8418 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8419 @ no-op @ releasing store 8420 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8421 @ no-op 8422 GET_INST_OPCODE(ip) @ extract opcode from rINST 8423 GOTO_OPCODE(ip) @ jump to next instruction 8424 8425/* continuation for OP_IPUT_WIDE */ 8426 8427 /* 8428 * Currently: 8429 * r0 holds resolved field 8430 * r9 holds object 8431 */ 8432.LOP_IPUT_WIDE_finish: 8433 mov r2, rINST, lsr #8 @ r2<- A+ 8434 cmp r9, #0 @ check object for null 8435 and r2, r2, #15 @ r2<- A 8436 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8437 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 8438 beq common_errNullObject @ object was null 8439 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8440 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 8441 GET_INST_OPCODE(r10) @ extract opcode from rINST 8442 .if 0 8443 add r2, r9, r3 @ r2<- target address 8444 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 8445 .else 8446 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 8447 .endif 8448 GOTO_OPCODE(r10) @ jump to next instruction 8449 8450/* continuation for OP_IPUT_OBJECT */ 8451 8452 /* 8453 * Currently: 8454 * r0 holds resolved field 8455 * r9 holds object 8456 */ 8457.LOP_IPUT_OBJECT_finish: 8458 @bl common_squeak0 8459 mov r1, rINST, lsr #8 @ r1<- A+ 8460 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8461 and r1, r1, #15 @ r1<- A 8462 cmp r9, #0 @ check object for null 8463 GET_VREG(r0, r1) @ r0<- fp[A] 8464 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 8465 beq common_errNullObject @ object was null 8466 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8467 @ no-op @ releasing store 8468 str r0, [r9, r3] @ obj.field (32 bits)<- r0 8469 @ no-op 8470 GET_INST_OPCODE(ip) @ extract opcode from rINST 8471 cmp r0, #0 @ stored a null reference? 8472 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 8473 GOTO_OPCODE(ip) @ jump to next instruction 8474 8475/* continuation for OP_IPUT_BOOLEAN */ 8476 8477 /* 8478 * Currently: 8479 * r0 holds resolved field 8480 * r9 holds object 8481 */ 8482.LOP_IPUT_BOOLEAN_finish: 8483 @bl common_squeak1 8484 mov r1, rINST, lsr #8 @ r1<- A+ 8485 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8486 and r1, r1, #15 @ r1<- A 8487 cmp r9, #0 @ check object for null 8488 GET_VREG(r0, r1) @ r0<- fp[A] 8489 beq common_errNullObject @ object was null 8490 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8491 @ no-op @ releasing store 8492 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8493 @ no-op 8494 GET_INST_OPCODE(ip) @ extract opcode from rINST 8495 GOTO_OPCODE(ip) @ jump to next instruction 8496 8497/* continuation for OP_IPUT_BYTE */ 8498 8499 /* 8500 * Currently: 8501 * r0 holds resolved field 8502 * r9 holds object 8503 */ 8504.LOP_IPUT_BYTE_finish: 8505 @bl common_squeak2 8506 mov r1, rINST, lsr #8 @ r1<- A+ 8507 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8508 and r1, r1, #15 @ r1<- A 8509 cmp r9, #0 @ check object for null 8510 GET_VREG(r0, r1) @ r0<- fp[A] 8511 beq common_errNullObject @ object was null 8512 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8513 @ no-op @ releasing store 8514 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8515 @ no-op 8516 GET_INST_OPCODE(ip) @ extract opcode from rINST 8517 GOTO_OPCODE(ip) @ jump to next instruction 8518 8519/* continuation for OP_IPUT_CHAR */ 8520 8521 /* 8522 * Currently: 8523 * r0 holds resolved field 8524 * r9 holds object 8525 */ 8526.LOP_IPUT_CHAR_finish: 8527 @bl common_squeak3 8528 mov r1, rINST, lsr #8 @ r1<- A+ 8529 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8530 and r1, r1, #15 @ r1<- A 8531 cmp r9, #0 @ check object for null 8532 GET_VREG(r0, r1) @ r0<- fp[A] 8533 beq common_errNullObject @ object was null 8534 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8535 @ no-op @ releasing store 8536 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8537 @ no-op 8538 GET_INST_OPCODE(ip) @ extract opcode from rINST 8539 GOTO_OPCODE(ip) @ jump to next instruction 8540 8541/* continuation for OP_IPUT_SHORT */ 8542 8543 /* 8544 * Currently: 8545 * r0 holds resolved field 8546 * r9 holds object 8547 */ 8548.LOP_IPUT_SHORT_finish: 8549 @bl common_squeak4 8550 mov r1, rINST, lsr #8 @ r1<- A+ 8551 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 8552 and r1, r1, #15 @ r1<- A 8553 cmp r9, #0 @ check object for null 8554 GET_VREG(r0, r1) @ r0<- fp[A] 8555 beq common_errNullObject @ object was null 8556 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 8557 @ no-op @ releasing store 8558 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 8559 @ no-op 8560 GET_INST_OPCODE(ip) @ extract opcode from rINST 8561 GOTO_OPCODE(ip) @ jump to next instruction 8562 8563/* continuation for OP_SGET */ 8564 8565 /* 8566 * Continuation if the field has not yet been resolved. 8567 * r1: BBBB field ref 8568 * r10: dvmDex->pResFields 8569 */ 8570.LOP_SGET_resolve: 8571 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8572#if defined(WITH_JIT) 8573 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8574#endif 8575 EXPORT_PC() @ resolve() could throw, so export now 8576 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8577 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8578 cmp r0, #0 @ success? 8579 beq common_exceptionThrown @ no, handle exception 8580#if defined(WITH_JIT) 8581 /* 8582 * If the JIT is actively building a trace we need to make sure 8583 * that the field is fully resolved before including this instruction. 8584 */ 8585 bl common_verifyField 8586#endif 8587 b .LOP_SGET_finish 8588 8589/* continuation for OP_SGET_WIDE */ 8590 8591 /* 8592 * Continuation if the field has not yet been resolved. 8593 * r1: BBBB field ref 8594 * r10: dvmDex->pResFields 8595 * 8596 * Returns StaticField pointer in r0. 8597 */ 8598.LOP_SGET_WIDE_resolve: 8599 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8600#if defined(WITH_JIT) 8601 add r10, r10, r1, lsl #2 @ r1<- &dvmDex->pResFields[field] 8602#endif 8603 EXPORT_PC() @ resolve() could throw, so export now 8604 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8605 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8606 cmp r0, #0 @ success? 8607 beq common_exceptionThrown @ no, handle exception 8608#if defined(WITH_JIT) 8609 /* 8610 * If the JIT is actively building a trace we need to make sure 8611 * that the field is fully resolved before including this instruction. 8612 */ 8613 bl common_verifyField 8614#endif 8615 b .LOP_SGET_WIDE_finish @ resume 8616 8617/* continuation for OP_SGET_OBJECT */ 8618 8619 /* 8620 * Continuation if the field has not yet been resolved. 8621 * r1: BBBB field ref 8622 * r10: dvmDex->pResFields 8623 */ 8624.LOP_SGET_OBJECT_resolve: 8625 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8626#if defined(WITH_JIT) 8627 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8628#endif 8629 EXPORT_PC() @ resolve() could throw, so export now 8630 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8631 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8632 cmp r0, #0 @ success? 8633 beq common_exceptionThrown @ no, handle exception 8634#if defined(WITH_JIT) 8635 /* 8636 * If the JIT is actively building a trace we need to make sure 8637 * that the field is fully resolved before including this instruction. 8638 */ 8639 bl common_verifyField 8640#endif 8641 b .LOP_SGET_OBJECT_finish 8642 8643/* continuation for OP_SGET_BOOLEAN */ 8644 8645 /* 8646 * Continuation if the field has not yet been resolved. 8647 * r1: BBBB field ref 8648 * r10: dvmDex->pResFields 8649 */ 8650.LOP_SGET_BOOLEAN_resolve: 8651 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8652#if defined(WITH_JIT) 8653 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8654#endif 8655 EXPORT_PC() @ resolve() could throw, so export now 8656 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8657 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8658 cmp r0, #0 @ success? 8659 beq common_exceptionThrown @ no, handle exception 8660#if defined(WITH_JIT) 8661 /* 8662 * If the JIT is actively building a trace we need to make sure 8663 * that the field is fully resolved before including this instruction. 8664 */ 8665 bl common_verifyField 8666#endif 8667 b .LOP_SGET_BOOLEAN_finish 8668 8669/* continuation for OP_SGET_BYTE */ 8670 8671 /* 8672 * Continuation if the field has not yet been resolved. 8673 * r1: BBBB field ref 8674 * r10: dvmDex->pResFields 8675 */ 8676.LOP_SGET_BYTE_resolve: 8677 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8678#if defined(WITH_JIT) 8679 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8680#endif 8681 EXPORT_PC() @ resolve() could throw, so export now 8682 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8683 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8684 cmp r0, #0 @ success? 8685 beq common_exceptionThrown @ no, handle exception 8686#if defined(WITH_JIT) 8687 /* 8688 * If the JIT is actively building a trace we need to make sure 8689 * that the field is fully resolved before including this instruction. 8690 */ 8691 bl common_verifyField 8692#endif 8693 b .LOP_SGET_BYTE_finish 8694 8695/* continuation for OP_SGET_CHAR */ 8696 8697 /* 8698 * Continuation if the field has not yet been resolved. 8699 * r1: BBBB field ref 8700 * r10: dvmDex->pResFields 8701 */ 8702.LOP_SGET_CHAR_resolve: 8703 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8704#if defined(WITH_JIT) 8705 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8706#endif 8707 EXPORT_PC() @ resolve() could throw, so export now 8708 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8709 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8710 cmp r0, #0 @ success? 8711 beq common_exceptionThrown @ no, handle exception 8712#if defined(WITH_JIT) 8713 /* 8714 * If the JIT is actively building a trace we need to make sure 8715 * that the field is fully resolved before including this instruction. 8716 */ 8717 bl common_verifyField 8718#endif 8719 b .LOP_SGET_CHAR_finish 8720 8721/* continuation for OP_SGET_SHORT */ 8722 8723 /* 8724 * Continuation if the field has not yet been resolved. 8725 * r1: BBBB field ref 8726 * r10: dvmDex->pResFields 8727 */ 8728.LOP_SGET_SHORT_resolve: 8729 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8730#if defined(WITH_JIT) 8731 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8732#endif 8733 EXPORT_PC() @ resolve() could throw, so export now 8734 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8735 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8736 cmp r0, #0 @ success? 8737 beq common_exceptionThrown @ no, handle exception 8738#if defined(WITH_JIT) 8739 /* 8740 * If the JIT is actively building a trace we need to make sure 8741 * that the field is fully resolved before including this instruction. 8742 */ 8743 bl common_verifyField 8744#endif 8745 b .LOP_SGET_SHORT_finish 8746 8747/* continuation for OP_SPUT */ 8748 8749 /* 8750 * Continuation if the field has not yet been resolved. 8751 * r1: BBBB field ref 8752 * r10: dvmDex->pResFields 8753 */ 8754.LOP_SPUT_resolve: 8755 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8756#if defined(WITH_JIT) 8757 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8758#endif 8759 EXPORT_PC() @ resolve() could throw, so export now 8760 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8761 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8762 cmp r0, #0 @ success? 8763 beq common_exceptionThrown @ no, handle exception 8764#if defined(WITH_JIT) 8765 /* 8766 * If the JIT is actively building a trace we need to make sure 8767 * that the field is fully resolved before including this instruction. 8768 */ 8769 bl common_verifyField 8770#endif 8771 b .LOP_SPUT_finish @ resume 8772 8773/* continuation for OP_SPUT_WIDE */ 8774 8775 /* 8776 * Continuation if the field has not yet been resolved. 8777 * r1: BBBB field ref 8778 * r9: &fp[AA] 8779 * r10: dvmDex->pResFields 8780 * 8781 * Returns StaticField pointer in r2. 8782 */ 8783.LOP_SPUT_WIDE_resolve: 8784 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8785#if defined(WITH_JIT) 8786 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8787#endif 8788 EXPORT_PC() @ resolve() could throw, so export now 8789 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8790 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8791 cmp r0, #0 @ success? 8792 mov r2, r0 @ copy to r2 8793 beq common_exceptionThrown @ no, handle exception 8794#if defined(WITH_JIT) 8795 /* 8796 * If the JIT is actively building a trace we need to make sure 8797 * that the field is fully resolved before including this instruction. 8798 */ 8799 bl common_verifyField 8800#endif 8801 b .LOP_SPUT_WIDE_finish @ resume 8802 8803/* continuation for OP_SPUT_OBJECT */ 8804 8805 8806.LOP_SPUT_OBJECT_end: 8807 str r1, [r0, #offStaticField_value] @ field<- vAA 8808 @ no-op 8809 cmp r1, #0 @ stored a null object? 8810 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 8811 GOTO_OPCODE(ip) @ jump to next instruction 8812 8813 /* Continuation if the field has not yet been resolved. 8814 * r1: BBBB field ref 8815 * r10: dvmDex->pResFields 8816 */ 8817.LOP_SPUT_OBJECT_resolve: 8818 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8819#if defined(WITH_JIT) 8820 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8821#endif 8822 EXPORT_PC() @ resolve() could throw, so export now 8823 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8824 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8825 cmp r0, #0 @ success? 8826 beq common_exceptionThrown @ no, handle exception 8827#if defined(WITH_JIT) 8828 /* 8829 * If the JIT is actively building a trace we need to make sure 8830 * that the field is fully resolved before including this instruction. 8831 */ 8832 bl common_verifyField 8833#endif 8834 b .LOP_SPUT_OBJECT_finish @ resume 8835 8836 8837/* continuation for OP_SPUT_BOOLEAN */ 8838 8839 /* 8840 * Continuation if the field has not yet been resolved. 8841 * r1: BBBB field ref 8842 * r10: dvmDex->pResFields 8843 */ 8844.LOP_SPUT_BOOLEAN_resolve: 8845 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8846#if defined(WITH_JIT) 8847 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8848#endif 8849 EXPORT_PC() @ resolve() could throw, so export now 8850 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8851 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8852 cmp r0, #0 @ success? 8853 beq common_exceptionThrown @ no, handle exception 8854#if defined(WITH_JIT) 8855 /* 8856 * If the JIT is actively building a trace we need to make sure 8857 * that the field is fully resolved before including this instruction. 8858 */ 8859 bl common_verifyField 8860#endif 8861 b .LOP_SPUT_BOOLEAN_finish @ resume 8862 8863/* continuation for OP_SPUT_BYTE */ 8864 8865 /* 8866 * Continuation if the field has not yet been resolved. 8867 * r1: BBBB field ref 8868 * r10: dvmDex->pResFields 8869 */ 8870.LOP_SPUT_BYTE_resolve: 8871 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8872#if defined(WITH_JIT) 8873 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8874#endif 8875 EXPORT_PC() @ resolve() could throw, so export now 8876 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8877 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8878 cmp r0, #0 @ success? 8879 beq common_exceptionThrown @ no, handle exception 8880#if defined(WITH_JIT) 8881 /* 8882 * If the JIT is actively building a trace we need to make sure 8883 * that the field is fully resolved before including this instruction. 8884 */ 8885 bl common_verifyField 8886#endif 8887 b .LOP_SPUT_BYTE_finish @ resume 8888 8889/* continuation for OP_SPUT_CHAR */ 8890 8891 /* 8892 * Continuation if the field has not yet been resolved. 8893 * r1: BBBB field ref 8894 * r10: dvmDex->pResFields 8895 */ 8896.LOP_SPUT_CHAR_resolve: 8897 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8898#if defined(WITH_JIT) 8899 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8900#endif 8901 EXPORT_PC() @ resolve() could throw, so export now 8902 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8903 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8904 cmp r0, #0 @ success? 8905 beq common_exceptionThrown @ no, handle exception 8906#if defined(WITH_JIT) 8907 /* 8908 * If the JIT is actively building a trace we need to make sure 8909 * that the field is fully resolved before including this instruction. 8910 */ 8911 bl common_verifyField 8912#endif 8913 b .LOP_SPUT_CHAR_finish @ resume 8914 8915/* continuation for OP_SPUT_SHORT */ 8916 8917 /* 8918 * Continuation if the field has not yet been resolved. 8919 * r1: BBBB field ref 8920 * r10: dvmDex->pResFields 8921 */ 8922.LOP_SPUT_SHORT_resolve: 8923 ldr r2, [rSELF, #offThread_method] @ r2<- current method 8924#if defined(WITH_JIT) 8925 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 8926#endif 8927 EXPORT_PC() @ resolve() could throw, so export now 8928 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8929 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8930 cmp r0, #0 @ success? 8931 beq common_exceptionThrown @ no, handle exception 8932#if defined(WITH_JIT) 8933 /* 8934 * If the JIT is actively building a trace we need to make sure 8935 * that the field is fully resolved before including this instruction. 8936 */ 8937 bl common_verifyField 8938#endif 8939 b .LOP_SPUT_SHORT_finish @ resume 8940 8941/* continuation for OP_INVOKE_VIRTUAL */ 8942 8943 /* 8944 * At this point: 8945 * r0 = resolved base method 8946 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 8947 */ 8948.LOP_INVOKE_VIRTUAL_continue: 8949 GET_VREG(r9, r10) @ r9<- "this" ptr 8950 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 8951 cmp r9, #0 @ is "this" null? 8952 beq common_errNullObject @ null "this", throw exception 8953 ldr r3, [r9, #offObject_clazz] @ r3<- thisPtr->clazz 8954 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 8955 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 8956 bl common_invokeMethodNoRange @ (r0=method, r9="this") 8957 8958/* continuation for OP_INVOKE_SUPER */ 8959 8960 /* 8961 * At this point: 8962 * r0 = resolved base method 8963 * r10 = method->clazz 8964 */ 8965.LOP_INVOKE_SUPER_continue: 8966 ldr r1, [r10, #offClassObject_super] @ r1<- method->clazz->super 8967 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 8968 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 8969 EXPORT_PC() @ must export for invoke 8970 cmp r2, r3 @ compare (methodIndex, vtableCount) 8971 bcs .LOP_INVOKE_SUPER_nsm @ method not present in superclass 8972 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 8973 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 8974 bl common_invokeMethodNoRange @ continue on 8975 8976.LOP_INVOKE_SUPER_resolve: 8977 mov r0, r10 @ r0<- method->clazz 8978 mov r2, #METHOD_VIRTUAL @ resolver method type 8979 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8980 cmp r0, #0 @ got null? 8981 bne .LOP_INVOKE_SUPER_continue @ no, continue 8982 b common_exceptionThrown @ yes, handle exception 8983 8984 /* 8985 * Throw a NoSuchMethodError with the method name as the message. 8986 * r0 = resolved base method 8987 */ 8988.LOP_INVOKE_SUPER_nsm: 8989 ldr r1, [r0, #offMethod_name] @ r1<- method name 8990 b common_errNoSuchMethod 8991 8992/* continuation for OP_INVOKE_DIRECT */ 8993 8994 /* 8995 * On entry: 8996 * r1 = reference (BBBB or CCCC) 8997 * r10 = "this" register 8998 */ 8999.LOP_INVOKE_DIRECT_resolve: 9000 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9001 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9002 mov r2, #METHOD_DIRECT @ resolver method type 9003 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9004 cmp r0, #0 @ got null? 9005 bne .LOP_INVOKE_DIRECT_finish @ no, continue 9006 b common_exceptionThrown @ yes, handle exception 9007 9008/* continuation for OP_INVOKE_STATIC */ 9009 9010 9011.LOP_INVOKE_STATIC_resolve: 9012 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9013 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9014 mov r2, #METHOD_STATIC @ resolver method type 9015 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9016 cmp r0, #0 @ got null? 9017#if defined(WITH_JIT) 9018 /* 9019 * Check to see if we're actively building a trace. If so, 9020 * we need to keep this instruction out of it. 9021 * r10: &resolved_methodToCall 9022 */ 9023 ldrh r2, [rSELF, #offThread_subMode] 9024 beq common_exceptionThrown @ null, handle exception 9025 ands r2, #kSubModeJitTraceBuild @ trace under construction? 9026 beq common_invokeMethodNoRange @ no (r0=method, r9="this") 9027 ldr r1, [r10] @ reload resolved method 9028 cmp r1, #0 @ finished resolving? 9029 bne common_invokeMethodNoRange @ yes (r0=method, r9="this") 9030 mov r10, r0 @ preserve method 9031 mov r0, rSELF 9032 mov r1, rPC 9033 bl dvmJitEndTraceSelect @ (self, pc) 9034 mov r0, r10 9035 b common_invokeMethodNoRange @ whew, finally! 9036#else 9037 bne common_invokeMethodNoRange @ (r0=method, r9="this") 9038 b common_exceptionThrown @ yes, handle exception 9039#endif 9040 9041/* continuation for OP_INVOKE_VIRTUAL_RANGE */ 9042 9043 /* 9044 * At this point: 9045 * r0 = resolved base method 9046 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 9047 */ 9048.LOP_INVOKE_VIRTUAL_RANGE_continue: 9049 GET_VREG(r9, r10) @ r9<- "this" ptr 9050 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 9051 cmp r9, #0 @ is "this" null? 9052 beq common_errNullObject @ null "this", throw exception 9053 ldr r3, [r9, #offObject_clazz] @ r3<- thisPtr->clazz 9054 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 9055 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 9056 bl common_invokeMethodRange @ (r0=method, r9="this") 9057 9058/* continuation for OP_INVOKE_SUPER_RANGE */ 9059 9060 /* 9061 * At this point: 9062 * r0 = resolved base method 9063 * r10 = method->clazz 9064 */ 9065.LOP_INVOKE_SUPER_RANGE_continue: 9066 ldr r1, [r10, #offClassObject_super] @ r1<- method->clazz->super 9067 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 9068 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 9069 EXPORT_PC() @ must export for invoke 9070 cmp r2, r3 @ compare (methodIndex, vtableCount) 9071 bcs .LOP_INVOKE_SUPER_RANGE_nsm @ method not present in superclass 9072 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 9073 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 9074 bl common_invokeMethodRange @ continue on 9075 9076.LOP_INVOKE_SUPER_RANGE_resolve: 9077 mov r0, r10 @ r0<- method->clazz 9078 mov r2, #METHOD_VIRTUAL @ resolver method type 9079 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9080 cmp r0, #0 @ got null? 9081 bne .LOP_INVOKE_SUPER_RANGE_continue @ no, continue 9082 b common_exceptionThrown @ yes, handle exception 9083 9084 /* 9085 * Throw a NoSuchMethodError with the method name as the message. 9086 * r0 = resolved base method 9087 */ 9088.LOP_INVOKE_SUPER_RANGE_nsm: 9089 ldr r1, [r0, #offMethod_name] @ r1<- method name 9090 b common_errNoSuchMethod 9091 9092/* continuation for OP_INVOKE_DIRECT_RANGE */ 9093 9094 /* 9095 * On entry: 9096 * r1 = reference (BBBB or CCCC) 9097 * r10 = "this" register 9098 */ 9099.LOP_INVOKE_DIRECT_RANGE_resolve: 9100 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9101 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9102 mov r2, #METHOD_DIRECT @ resolver method type 9103 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9104 cmp r0, #0 @ got null? 9105 bne .LOP_INVOKE_DIRECT_RANGE_finish @ no, continue 9106 b common_exceptionThrown @ yes, handle exception 9107 9108/* continuation for OP_INVOKE_STATIC_RANGE */ 9109 9110 9111.LOP_INVOKE_STATIC_RANGE_resolve: 9112 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 9113 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 9114 mov r2, #METHOD_STATIC @ resolver method type 9115 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 9116 cmp r0, #0 @ got null? 9117#if defined(WITH_JIT) 9118 /* 9119 * Check to see if we're actively building a trace. If so, 9120 * we need to keep this instruction out of it. 9121 * r10: &resolved_methodToCall 9122 */ 9123 ldrh r2, [rSELF, #offThread_subMode] 9124 beq common_exceptionThrown @ null, handle exception 9125 ands r2, #kSubModeJitTraceBuild @ trace under construction? 9126 beq common_invokeMethodRange @ no (r0=method, r9="this") 9127 ldr r1, [r10] @ reload resolved method 9128 cmp r1, #0 @ finished resolving? 9129 bne common_invokeMethodRange @ yes (r0=method, r9="this") 9130 mov r10, r0 @ preserve method 9131 mov r0, rSELF 9132 mov r1, rPC 9133 bl dvmJitEndTraceSelect @ (self, pc) 9134 mov r0, r10 9135 b common_invokeMethodRange @ whew, finally! 9136#else 9137 bne common_invokeMethodRange @ (r0=method, r9="this") 9138 b common_exceptionThrown @ yes, handle exception 9139#endif 9140 9141/* continuation for OP_FLOAT_TO_LONG */ 9142/* 9143 * Convert the float in r0 to a long in r0/r1. 9144 * 9145 * We have to clip values to long min/max per the specification. The 9146 * expected common case is a "reasonable" value that converts directly 9147 * to modest integer. The EABI convert function isn't doing this for us. 9148 */ 9149f2l_doconv: 9150 stmfd sp!, {r4, lr} 9151 mov r1, #0x5f000000 @ (float)maxlong 9152 mov r4, r0 9153 bl __aeabi_fcmpge @ is arg >= maxlong? 9154 cmp r0, #0 @ nonzero == yes 9155 mvnne r0, #0 @ return maxlong (7fffffff) 9156 mvnne r1, #0x80000000 9157 ldmnefd sp!, {r4, pc} 9158 9159 mov r0, r4 @ recover arg 9160 mov r1, #0xdf000000 @ (float)minlong 9161 bl __aeabi_fcmple @ is arg <= minlong? 9162 cmp r0, #0 @ nonzero == yes 9163 movne r0, #0 @ return minlong (80000000) 9164 movne r1, #0x80000000 9165 ldmnefd sp!, {r4, pc} 9166 9167 mov r0, r4 @ recover arg 9168 mov r1, r4 9169 bl __aeabi_fcmpeq @ is arg == self? 9170 cmp r0, #0 @ zero == no 9171 moveq r1, #0 @ return zero for NaN 9172 ldmeqfd sp!, {r4, pc} 9173 9174 mov r0, r4 @ recover arg 9175 bl __aeabi_f2lz @ convert float to long 9176 ldmfd sp!, {r4, pc} 9177 9178/* continuation for OP_DOUBLE_TO_LONG */ 9179/* 9180 * Convert the double in r0/r1 to a long in r0/r1. 9181 * 9182 * We have to clip values to long min/max per the specification. The 9183 * expected common case is a "reasonable" value that converts directly 9184 * to modest integer. The EABI convert function isn't doing this for us. 9185 */ 9186d2l_doconv: 9187 stmfd sp!, {r4, r5, lr} @ save regs 9188 mov r3, #0x43000000 @ maxlong, as a double (high word) 9189 add r3, #0x00e00000 @ 0x43e00000 9190 mov r2, #0 @ maxlong, as a double (low word) 9191 sub sp, sp, #4 @ align for EABI 9192 mov r4, r0 @ save a copy of r0 9193 mov r5, r1 @ and r1 9194 bl __aeabi_dcmpge @ is arg >= maxlong? 9195 cmp r0, #0 @ nonzero == yes 9196 mvnne r0, #0 @ return maxlong (7fffffffffffffff) 9197 mvnne r1, #0x80000000 9198 bne 1f 9199 9200 mov r0, r4 @ recover arg 9201 mov r1, r5 9202 mov r3, #0xc3000000 @ minlong, as a double (high word) 9203 add r3, #0x00e00000 @ 0xc3e00000 9204 mov r2, #0 @ minlong, as a double (low word) 9205 bl __aeabi_dcmple @ is arg <= minlong? 9206 cmp r0, #0 @ nonzero == yes 9207 movne r0, #0 @ return minlong (8000000000000000) 9208 movne r1, #0x80000000 9209 bne 1f 9210 9211 mov r0, r4 @ recover arg 9212 mov r1, r5 9213 mov r2, r4 @ compare against self 9214 mov r3, r5 9215 bl __aeabi_dcmpeq @ is arg == self? 9216 cmp r0, #0 @ zero == no 9217 moveq r1, #0 @ return zero for NaN 9218 beq 1f 9219 9220 mov r0, r4 @ recover arg 9221 mov r1, r5 9222 bl __aeabi_d2lz @ convert double to long 9223 92241: 9225 add sp, sp, #4 9226 ldmfd sp!, {r4, r5, pc} 9227 9228/* continuation for OP_MUL_LONG */ 9229 9230.LOP_MUL_LONG_finish: 9231 GET_INST_OPCODE(ip) @ extract opcode from rINST 9232 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 9233 GOTO_OPCODE(ip) @ jump to next instruction 9234 9235/* continuation for OP_SHL_LONG */ 9236 9237.LOP_SHL_LONG_finish: 9238 mov r0, r0, asl r2 @ r0<- r0 << r2 9239 GET_INST_OPCODE(ip) @ extract opcode from rINST 9240 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9241 GOTO_OPCODE(ip) @ jump to next instruction 9242 9243/* continuation for OP_SHR_LONG */ 9244 9245.LOP_SHR_LONG_finish: 9246 mov r1, r1, asr r2 @ r1<- r1 >> r2 9247 GET_INST_OPCODE(ip) @ extract opcode from rINST 9248 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9249 GOTO_OPCODE(ip) @ jump to next instruction 9250 9251/* continuation for OP_USHR_LONG */ 9252 9253.LOP_USHR_LONG_finish: 9254 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 9255 GET_INST_OPCODE(ip) @ extract opcode from rINST 9256 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9257 GOTO_OPCODE(ip) @ jump to next instruction 9258 9259/* continuation for OP_SHL_LONG_2ADDR */ 9260 9261.LOP_SHL_LONG_2ADDR_finish: 9262 GET_INST_OPCODE(ip) @ extract opcode from rINST 9263 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9264 GOTO_OPCODE(ip) @ jump to next instruction 9265 9266/* continuation for OP_SHR_LONG_2ADDR */ 9267 9268.LOP_SHR_LONG_2ADDR_finish: 9269 GET_INST_OPCODE(ip) @ extract opcode from rINST 9270 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9271 GOTO_OPCODE(ip) @ jump to next instruction 9272 9273/* continuation for OP_USHR_LONG_2ADDR */ 9274 9275.LOP_USHR_LONG_2ADDR_finish: 9276 GET_INST_OPCODE(ip) @ extract opcode from rINST 9277 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 9278 GOTO_OPCODE(ip) @ jump to next instruction 9279 9280/* continuation for OP_IGET_VOLATILE */ 9281 9282 /* 9283 * Currently: 9284 * r0 holds resolved field 9285 * r9 holds object 9286 */ 9287.LOP_IGET_VOLATILE_finish: 9288 @bl common_squeak0 9289 cmp r9, #0 @ check object for null 9290 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9291 beq common_errNullObject @ object was null 9292 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 9293 SMP_DMB @ acquiring load 9294 mov r2, rINST, lsr #8 @ r2<- A+ 9295 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9296 and r2, r2, #15 @ r2<- A 9297 GET_INST_OPCODE(ip) @ extract opcode from rINST 9298 SET_VREG(r0, r2) @ fp[A]<- r0 9299 GOTO_OPCODE(ip) @ jump to next instruction 9300 9301/* continuation for OP_IPUT_VOLATILE */ 9302 9303 /* 9304 * Currently: 9305 * r0 holds resolved field 9306 * r9 holds object 9307 */ 9308.LOP_IPUT_VOLATILE_finish: 9309 @bl common_squeak0 9310 mov r1, rINST, lsr #8 @ r1<- A+ 9311 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9312 and r1, r1, #15 @ r1<- A 9313 cmp r9, #0 @ check object for null 9314 GET_VREG(r0, r1) @ r0<- fp[A] 9315 beq common_errNullObject @ object was null 9316 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9317 SMP_DMB_ST @ releasing store 9318 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 9319 SMP_DMB 9320 GET_INST_OPCODE(ip) @ extract opcode from rINST 9321 GOTO_OPCODE(ip) @ jump to next instruction 9322 9323/* continuation for OP_SGET_VOLATILE */ 9324 9325 /* 9326 * Continuation if the field has not yet been resolved. 9327 * r1: BBBB field ref 9328 * r10: dvmDex->pResFields 9329 */ 9330.LOP_SGET_VOLATILE_resolve: 9331 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9332#if defined(WITH_JIT) 9333 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9334#endif 9335 EXPORT_PC() @ resolve() could throw, so export now 9336 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9337 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9338 cmp r0, #0 @ success? 9339 beq common_exceptionThrown @ no, handle exception 9340#if defined(WITH_JIT) 9341 /* 9342 * If the JIT is actively building a trace we need to make sure 9343 * that the field is fully resolved before including this instruction. 9344 */ 9345 bl common_verifyField 9346#endif 9347 b .LOP_SGET_VOLATILE_finish 9348 9349/* continuation for OP_SPUT_VOLATILE */ 9350 9351 /* 9352 * Continuation if the field has not yet been resolved. 9353 * r1: BBBB field ref 9354 * r10: dvmDex->pResFields 9355 */ 9356.LOP_SPUT_VOLATILE_resolve: 9357 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9358#if defined(WITH_JIT) 9359 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9360#endif 9361 EXPORT_PC() @ resolve() could throw, so export now 9362 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9363 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9364 cmp r0, #0 @ success? 9365 beq common_exceptionThrown @ no, handle exception 9366#if defined(WITH_JIT) 9367 /* 9368 * If the JIT is actively building a trace we need to make sure 9369 * that the field is fully resolved before including this instruction. 9370 */ 9371 bl common_verifyField 9372#endif 9373 b .LOP_SPUT_VOLATILE_finish @ resume 9374 9375/* continuation for OP_IGET_OBJECT_VOLATILE */ 9376 9377 /* 9378 * Currently: 9379 * r0 holds resolved field 9380 * r9 holds object 9381 */ 9382.LOP_IGET_OBJECT_VOLATILE_finish: 9383 @bl common_squeak0 9384 cmp r9, #0 @ check object for null 9385 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9386 beq common_errNullObject @ object was null 9387 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 9388 SMP_DMB @ acquiring load 9389 mov r2, rINST, lsr #8 @ r2<- A+ 9390 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9391 and r2, r2, #15 @ r2<- A 9392 GET_INST_OPCODE(ip) @ extract opcode from rINST 9393 SET_VREG(r0, r2) @ fp[A]<- r0 9394 GOTO_OPCODE(ip) @ jump to next instruction 9395 9396/* continuation for OP_IGET_WIDE_VOLATILE */ 9397 9398 /* 9399 * Currently: 9400 * r0 holds resolved field 9401 * r9 holds object 9402 */ 9403.LOP_IGET_WIDE_VOLATILE_finish: 9404 cmp r9, #0 @ check object for null 9405 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9406 beq common_errNullObject @ object was null 9407 .if 1 9408 add r0, r9, r3 @ r0<- address of field 9409 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 9410 .else 9411 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 9412 .endif 9413 mov r2, rINST, lsr #8 @ r2<- A+ 9414 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9415 and r2, r2, #15 @ r2<- A 9416 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 9417 GET_INST_OPCODE(ip) @ extract opcode from rINST 9418 stmia r3, {r0-r1} @ fp[A]<- r0/r1 9419 GOTO_OPCODE(ip) @ jump to next instruction 9420 9421/* continuation for OP_IPUT_WIDE_VOLATILE */ 9422 9423 /* 9424 * Currently: 9425 * r0 holds resolved field 9426 * r9 holds object 9427 */ 9428.LOP_IPUT_WIDE_VOLATILE_finish: 9429 mov r2, rINST, lsr #8 @ r2<- A+ 9430 cmp r9, #0 @ check object for null 9431 and r2, r2, #15 @ r2<- A 9432 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9433 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 9434 beq common_errNullObject @ object was null 9435 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9436 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 9437 GET_INST_OPCODE(r10) @ extract opcode from rINST 9438 .if 1 9439 add r2, r9, r3 @ r2<- target address 9440 bl dvmQuasiAtomicSwap64Sync @ stores r0/r1 into addr r2 9441 .else 9442 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 9443 .endif 9444 GOTO_OPCODE(r10) @ jump to next instruction 9445 9446/* continuation for OP_SGET_WIDE_VOLATILE */ 9447 9448 /* 9449 * Continuation if the field has not yet been resolved. 9450 * r1: BBBB field ref 9451 * r10: dvmDex->pResFields 9452 * 9453 * Returns StaticField pointer in r0. 9454 */ 9455.LOP_SGET_WIDE_VOLATILE_resolve: 9456 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9457#if defined(WITH_JIT) 9458 add r10, r10, r1, lsl #2 @ r1<- &dvmDex->pResFields[field] 9459#endif 9460 EXPORT_PC() @ resolve() could throw, so export now 9461 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9462 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9463 cmp r0, #0 @ success? 9464 beq common_exceptionThrown @ no, handle exception 9465#if defined(WITH_JIT) 9466 /* 9467 * If the JIT is actively building a trace we need to make sure 9468 * that the field is fully resolved before including this instruction. 9469 */ 9470 bl common_verifyField 9471#endif 9472 b .LOP_SGET_WIDE_VOLATILE_finish @ resume 9473 9474/* continuation for OP_SPUT_WIDE_VOLATILE */ 9475 9476 /* 9477 * Continuation if the field has not yet been resolved. 9478 * r1: BBBB field ref 9479 * r9: &fp[AA] 9480 * r10: dvmDex->pResFields 9481 * 9482 * Returns StaticField pointer in r2. 9483 */ 9484.LOP_SPUT_WIDE_VOLATILE_resolve: 9485 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9486#if defined(WITH_JIT) 9487 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9488#endif 9489 EXPORT_PC() @ resolve() could throw, so export now 9490 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9491 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9492 cmp r0, #0 @ success? 9493 mov r2, r0 @ copy to r2 9494 beq common_exceptionThrown @ no, handle exception 9495#if defined(WITH_JIT) 9496 /* 9497 * If the JIT is actively building a trace we need to make sure 9498 * that the field is fully resolved before including this instruction. 9499 */ 9500 bl common_verifyField 9501#endif 9502 b .LOP_SPUT_WIDE_VOLATILE_finish @ resume 9503 9504/* continuation for OP_EXECUTE_INLINE */ 9505 9506 /* 9507 * Extract args, call function. 9508 * r0 = #of args (0-4) 9509 * r10 = call index 9510 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 9511 * 9512 * Other ideas: 9513 * - Use a jump table from the main piece to jump directly into the 9514 * AND/LDR pairs. Costs a data load, saves a branch. 9515 * - Have five separate pieces that do the loading, so we can work the 9516 * interleave a little better. Increases code size. 9517 */ 9518.LOP_EXECUTE_INLINE_continue: 9519 rsb r0, r0, #4 @ r0<- 4-r0 9520 FETCH(rINST, 2) @ rINST<- FEDC 9521 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 9522 bl common_abort @ (skipped due to ARM prefetch) 95234: and ip, rINST, #0xf000 @ isolate F 9524 ldr r3, [rFP, ip, lsr #10] @ r3<- vF (shift right 12, left 2) 95253: and ip, rINST, #0x0f00 @ isolate E 9526 ldr r2, [rFP, ip, lsr #6] @ r2<- vE 95272: and ip, rINST, #0x00f0 @ isolate D 9528 ldr r1, [rFP, ip, lsr #2] @ r1<- vD 95291: and ip, rINST, #0x000f @ isolate C 9530 ldr r0, [rFP, ip, lsl #2] @ r0<- vC 95310: 9532 ldr rINST, .LOP_EXECUTE_INLINE_table @ table of InlineOperation 95335: add rINST, pc 9534 ldr pc, [rINST, r10, lsl #4] @ sizeof=16, "func" is first entry 9535 @ (not reached) 9536 9537 /* 9538 * We're debugging or profiling. 9539 * r10: opIndex 9540 */ 9541.LOP_EXECUTE_INLINE_debugmode: 9542 mov r0, r10 9543 bl dvmResolveInlineNative 9544 cmp r0, #0 @ did it resolve? 9545 beq .LOP_EXECUTE_INLINE_resume @ no, just move on 9546 mov r9, r0 @ remember method 9547 mov r1, rSELF 9548 bl dvmFastMethodTraceEnter @ (method, self) 9549 add r1, rSELF, #offThread_retval@ r1<- &self->retval 9550 sub sp, sp, #8 @ make room for arg, +64 bit align 9551 mov r0, rINST, lsr #12 @ r0<- B 9552 str r1, [sp] @ push &self->retval 9553 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 9554 mov rINST, r0 @ save result of inline 9555 add sp, sp, #8 @ pop stack 9556 mov r0, r9 @ r0<- method 9557 mov r1, rSELF 9558 bl dvmFastNativeMethodTraceExit @ (method, self) 9559 cmp rINST, #0 @ test boolean result of inline 9560 beq common_exceptionThrown @ returned false, handle exception 9561 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 9562 GET_INST_OPCODE(ip) @ extract opcode from rINST 9563 GOTO_OPCODE(ip) @ jump to next instruction 9564 9565 9566 9567 9568.LOP_EXECUTE_INLINE_table: 9569 .word PCREL_REF(gDvmInlineOpsTable,5b) 9570 9571/* continuation for OP_EXECUTE_INLINE_RANGE */ 9572 9573 /* 9574 * Extract args, call function. 9575 * r0 = #of args (0-4) 9576 * r10 = call index 9577 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 9578 */ 9579.LOP_EXECUTE_INLINE_RANGE_continue: 9580 rsb r0, r0, #4 @ r0<- 4-r0 9581 FETCH(r9, 2) @ r9<- CCCC 9582 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 9583 bl common_abort @ (skipped due to ARM prefetch) 95844: add ip, r9, #3 @ base+3 9585 GET_VREG(r3, ip) @ r3<- vBase[3] 95863: add ip, r9, #2 @ base+2 9587 GET_VREG(r2, ip) @ r2<- vBase[2] 95882: add ip, r9, #1 @ base+1 9589 GET_VREG(r1, ip) @ r1<- vBase[1] 95901: add ip, r9, #0 @ (nop) 9591 GET_VREG(r0, ip) @ r0<- vBase[0] 95920: 9593 ldr r9, .LOP_EXECUTE_INLINE_RANGE_table @ table of InlineOperation 95945: add r9, pc 9595 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 9596 @ (not reached) 9597 9598 9599 /* 9600 * We're debugging or profiling. 9601 * r10: opIndex 9602 */ 9603.LOP_EXECUTE_INLINE_RANGE_debugmode: 9604 mov r0, r10 9605 bl dvmResolveInlineNative 9606 cmp r0, #0 @ did it resolve? 9607 beq .LOP_EXECUTE_INLINE_RANGE_resume @ no, just move on 9608 mov r9, r0 @ remember method 9609 mov r1, rSELF 9610 bl dvmFastMethodTraceEnter @ (method, self) 9611 add r1, rSELF, #offThread_retval@ r1<- &self->retval 9612 sub sp, sp, #8 @ make room for arg, +64 bit align 9613 mov r0, rINST, lsr #8 @ r0<- B 9614 mov rINST, r9 @ rINST<- method 9615 str r1, [sp] @ push &self->retval 9616 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 9617 mov r9, r0 @ save result of inline 9618 add sp, sp, #8 @ pop stack 9619 mov r0, rINST @ r0<- method 9620 mov r1, rSELF 9621 bl dvmFastNativeMethodTraceExit @ (method, self) 9622 cmp r9, #0 @ test boolean result of inline 9623 beq common_exceptionThrown @ returned false, handle exception 9624 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 9625 GET_INST_OPCODE(ip) @ extract opcode from rINST 9626 GOTO_OPCODE(ip) @ jump to next instruction 9627 9628 9629 9630 9631.LOP_EXECUTE_INLINE_RANGE_table: 9632 .word PCREL_REF(gDvmInlineOpsTable,5b) 9633 9634 9635/* continuation for OP_INVOKE_OBJECT_INIT_RANGE */ 9636 9637.LOP_INVOKE_OBJECT_INIT_RANGE_setFinal: 9638 EXPORT_PC() @ can throw 9639 bl dvmSetFinalizable @ call dvmSetFinalizable(obj) 9640 ldr r0, [rSELF, #offThread_exception] @ r0<- self->exception 9641 cmp r0, #0 @ exception pending? 9642 bne common_exceptionThrown @ yes, handle it 9643 b .LOP_INVOKE_OBJECT_INIT_RANGE_finish 9644 9645 /* 9646 * A debugger is attached, so we need to go ahead and do 9647 * this. For simplicity, we'll just jump directly to the 9648 * corresponding handler. Note that we can't use 9649 * rIBASE here because it may be in single-step mode. 9650 * Load the primary table base directly. 9651 */ 9652.LOP_INVOKE_OBJECT_INIT_RANGE_debugger: 9653 ldr r1, [rSELF, #offThread_mainHandlerTable] 9654 mov ip, #OP_INVOKE_DIRECT_RANGE 9655 GOTO_OPCODE_BASE(r1,ip) @ execute it 9656 9657/* continuation for OP_IPUT_OBJECT_VOLATILE */ 9658 9659 /* 9660 * Currently: 9661 * r0 holds resolved field 9662 * r9 holds object 9663 */ 9664.LOP_IPUT_OBJECT_VOLATILE_finish: 9665 @bl common_squeak0 9666 mov r1, rINST, lsr #8 @ r1<- A+ 9667 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 9668 and r1, r1, #15 @ r1<- A 9669 cmp r9, #0 @ check object for null 9670 GET_VREG(r0, r1) @ r0<- fp[A] 9671 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 9672 beq common_errNullObject @ object was null 9673 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 9674 SMP_DMB_ST @ releasing store 9675 str r0, [r9, r3] @ obj.field (32 bits)<- r0 9676 SMP_DMB 9677 GET_INST_OPCODE(ip) @ extract opcode from rINST 9678 cmp r0, #0 @ stored a null reference? 9679 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 9680 GOTO_OPCODE(ip) @ jump to next instruction 9681 9682/* continuation for OP_SGET_OBJECT_VOLATILE */ 9683 9684 /* 9685 * Continuation if the field has not yet been resolved. 9686 * r1: BBBB field ref 9687 * r10: dvmDex->pResFields 9688 */ 9689.LOP_SGET_OBJECT_VOLATILE_resolve: 9690 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9691#if defined(WITH_JIT) 9692 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9693#endif 9694 EXPORT_PC() @ resolve() could throw, so export now 9695 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9696 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9697 cmp r0, #0 @ success? 9698 beq common_exceptionThrown @ no, handle exception 9699#if defined(WITH_JIT) 9700 /* 9701 * If the JIT is actively building a trace we need to make sure 9702 * that the field is fully resolved before including this instruction. 9703 */ 9704 bl common_verifyField 9705#endif 9706 b .LOP_SGET_OBJECT_VOLATILE_finish 9707 9708/* continuation for OP_SPUT_OBJECT_VOLATILE */ 9709 9710 9711.LOP_SPUT_OBJECT_VOLATILE_end: 9712 str r1, [r0, #offStaticField_value] @ field<- vAA 9713 SMP_DMB 9714 cmp r1, #0 @ stored a null object? 9715 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 9716 GOTO_OPCODE(ip) @ jump to next instruction 9717 9718 /* Continuation if the field has not yet been resolved. 9719 * r1: BBBB field ref 9720 * r10: dvmDex->pResFields 9721 */ 9722.LOP_SPUT_OBJECT_VOLATILE_resolve: 9723 ldr r2, [rSELF, #offThread_method] @ r2<- current method 9724#if defined(WITH_JIT) 9725 add r10, r10, r1, lsl #2 @ r10<- &dvmDex->pResFields[field] 9726#endif 9727 EXPORT_PC() @ resolve() could throw, so export now 9728 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 9729 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 9730 cmp r0, #0 @ success? 9731 beq common_exceptionThrown @ no, handle exception 9732#if defined(WITH_JIT) 9733 /* 9734 * If the JIT is actively building a trace we need to make sure 9735 * that the field is fully resolved before including this instruction. 9736 */ 9737 bl common_verifyField 9738#endif 9739 b .LOP_SPUT_OBJECT_VOLATILE_finish @ resume 9740 9741 9742 .size dvmAsmSisterStart, .-dvmAsmSisterStart 9743 .global dvmAsmSisterEnd 9744dvmAsmSisterEnd: 9745 9746 9747 .global dvmAsmAltInstructionStart 9748 .type dvmAsmAltInstructionStart, %function 9749 .text 9750 9751dvmAsmAltInstructionStart = .L_ALT_OP_NOP 9752/* ------------------------------ */ 9753 .balign 64 9754.L_ALT_OP_NOP: /* 0x00 */ 9755/* File: armv5te/alt_stub.S */ 9756/* 9757 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9758 * any interesting requests and then jump to the real instruction 9759 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9760 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9761 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9762 * bail to the real handler if breakFlags==0. 9763 */ 9764 ldrb r3, [rSELF, #offThread_breakFlags] 9765 adrl lr, dvmAsmInstructionStart + (0 * 64) 9766 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9767 cmp r3, #0 9768 bxeq lr @ nothing to do - jump to real handler 9769 EXPORT_PC() 9770 mov r0, rPC @ arg0 9771 mov r1, rFP @ arg1 9772 mov r2, rSELF @ arg2 9773 b dvmCheckBefore @ (dPC,dFP,self) tail call 9774 9775/* ------------------------------ */ 9776 .balign 64 9777.L_ALT_OP_MOVE: /* 0x01 */ 9778/* File: armv5te/alt_stub.S */ 9779/* 9780 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9781 * any interesting requests and then jump to the real instruction 9782 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9783 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9784 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9785 * bail to the real handler if breakFlags==0. 9786 */ 9787 ldrb r3, [rSELF, #offThread_breakFlags] 9788 adrl lr, dvmAsmInstructionStart + (1 * 64) 9789 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9790 cmp r3, #0 9791 bxeq lr @ nothing to do - jump to real handler 9792 EXPORT_PC() 9793 mov r0, rPC @ arg0 9794 mov r1, rFP @ arg1 9795 mov r2, rSELF @ arg2 9796 b dvmCheckBefore @ (dPC,dFP,self) tail call 9797 9798/* ------------------------------ */ 9799 .balign 64 9800.L_ALT_OP_MOVE_FROM16: /* 0x02 */ 9801/* File: armv5te/alt_stub.S */ 9802/* 9803 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9804 * any interesting requests and then jump to the real instruction 9805 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9806 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9807 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9808 * bail to the real handler if breakFlags==0. 9809 */ 9810 ldrb r3, [rSELF, #offThread_breakFlags] 9811 adrl lr, dvmAsmInstructionStart + (2 * 64) 9812 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9813 cmp r3, #0 9814 bxeq lr @ nothing to do - jump to real handler 9815 EXPORT_PC() 9816 mov r0, rPC @ arg0 9817 mov r1, rFP @ arg1 9818 mov r2, rSELF @ arg2 9819 b dvmCheckBefore @ (dPC,dFP,self) tail call 9820 9821/* ------------------------------ */ 9822 .balign 64 9823.L_ALT_OP_MOVE_16: /* 0x03 */ 9824/* File: armv5te/alt_stub.S */ 9825/* 9826 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9827 * any interesting requests and then jump to the real instruction 9828 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9829 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9830 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9831 * bail to the real handler if breakFlags==0. 9832 */ 9833 ldrb r3, [rSELF, #offThread_breakFlags] 9834 adrl lr, dvmAsmInstructionStart + (3 * 64) 9835 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9836 cmp r3, #0 9837 bxeq lr @ nothing to do - jump to real handler 9838 EXPORT_PC() 9839 mov r0, rPC @ arg0 9840 mov r1, rFP @ arg1 9841 mov r2, rSELF @ arg2 9842 b dvmCheckBefore @ (dPC,dFP,self) tail call 9843 9844/* ------------------------------ */ 9845 .balign 64 9846.L_ALT_OP_MOVE_WIDE: /* 0x04 */ 9847/* File: armv5te/alt_stub.S */ 9848/* 9849 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9850 * any interesting requests and then jump to the real instruction 9851 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9852 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9853 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9854 * bail to the real handler if breakFlags==0. 9855 */ 9856 ldrb r3, [rSELF, #offThread_breakFlags] 9857 adrl lr, dvmAsmInstructionStart + (4 * 64) 9858 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9859 cmp r3, #0 9860 bxeq lr @ nothing to do - jump to real handler 9861 EXPORT_PC() 9862 mov r0, rPC @ arg0 9863 mov r1, rFP @ arg1 9864 mov r2, rSELF @ arg2 9865 b dvmCheckBefore @ (dPC,dFP,self) tail call 9866 9867/* ------------------------------ */ 9868 .balign 64 9869.L_ALT_OP_MOVE_WIDE_FROM16: /* 0x05 */ 9870/* File: armv5te/alt_stub.S */ 9871/* 9872 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9873 * any interesting requests and then jump to the real instruction 9874 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9875 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9876 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9877 * bail to the real handler if breakFlags==0. 9878 */ 9879 ldrb r3, [rSELF, #offThread_breakFlags] 9880 adrl lr, dvmAsmInstructionStart + (5 * 64) 9881 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9882 cmp r3, #0 9883 bxeq lr @ nothing to do - jump to real handler 9884 EXPORT_PC() 9885 mov r0, rPC @ arg0 9886 mov r1, rFP @ arg1 9887 mov r2, rSELF @ arg2 9888 b dvmCheckBefore @ (dPC,dFP,self) tail call 9889 9890/* ------------------------------ */ 9891 .balign 64 9892.L_ALT_OP_MOVE_WIDE_16: /* 0x06 */ 9893/* File: armv5te/alt_stub.S */ 9894/* 9895 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9896 * any interesting requests and then jump to the real instruction 9897 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9898 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9899 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9900 * bail to the real handler if breakFlags==0. 9901 */ 9902 ldrb r3, [rSELF, #offThread_breakFlags] 9903 adrl lr, dvmAsmInstructionStart + (6 * 64) 9904 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9905 cmp r3, #0 9906 bxeq lr @ nothing to do - jump to real handler 9907 EXPORT_PC() 9908 mov r0, rPC @ arg0 9909 mov r1, rFP @ arg1 9910 mov r2, rSELF @ arg2 9911 b dvmCheckBefore @ (dPC,dFP,self) tail call 9912 9913/* ------------------------------ */ 9914 .balign 64 9915.L_ALT_OP_MOVE_OBJECT: /* 0x07 */ 9916/* File: armv5te/alt_stub.S */ 9917/* 9918 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9919 * any interesting requests and then jump to the real instruction 9920 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9921 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9922 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9923 * bail to the real handler if breakFlags==0. 9924 */ 9925 ldrb r3, [rSELF, #offThread_breakFlags] 9926 adrl lr, dvmAsmInstructionStart + (7 * 64) 9927 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9928 cmp r3, #0 9929 bxeq lr @ nothing to do - jump to real handler 9930 EXPORT_PC() 9931 mov r0, rPC @ arg0 9932 mov r1, rFP @ arg1 9933 mov r2, rSELF @ arg2 9934 b dvmCheckBefore @ (dPC,dFP,self) tail call 9935 9936/* ------------------------------ */ 9937 .balign 64 9938.L_ALT_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 9939/* File: armv5te/alt_stub.S */ 9940/* 9941 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9942 * any interesting requests and then jump to the real instruction 9943 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9944 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9945 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9946 * bail to the real handler if breakFlags==0. 9947 */ 9948 ldrb r3, [rSELF, #offThread_breakFlags] 9949 adrl lr, dvmAsmInstructionStart + (8 * 64) 9950 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9951 cmp r3, #0 9952 bxeq lr @ nothing to do - jump to real handler 9953 EXPORT_PC() 9954 mov r0, rPC @ arg0 9955 mov r1, rFP @ arg1 9956 mov r2, rSELF @ arg2 9957 b dvmCheckBefore @ (dPC,dFP,self) tail call 9958 9959/* ------------------------------ */ 9960 .balign 64 9961.L_ALT_OP_MOVE_OBJECT_16: /* 0x09 */ 9962/* File: armv5te/alt_stub.S */ 9963/* 9964 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9965 * any interesting requests and then jump to the real instruction 9966 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9967 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9968 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9969 * bail to the real handler if breakFlags==0. 9970 */ 9971 ldrb r3, [rSELF, #offThread_breakFlags] 9972 adrl lr, dvmAsmInstructionStart + (9 * 64) 9973 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9974 cmp r3, #0 9975 bxeq lr @ nothing to do - jump to real handler 9976 EXPORT_PC() 9977 mov r0, rPC @ arg0 9978 mov r1, rFP @ arg1 9979 mov r2, rSELF @ arg2 9980 b dvmCheckBefore @ (dPC,dFP,self) tail call 9981 9982/* ------------------------------ */ 9983 .balign 64 9984.L_ALT_OP_MOVE_RESULT: /* 0x0a */ 9985/* File: armv5te/alt_stub.S */ 9986/* 9987 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 9988 * any interesting requests and then jump to the real instruction 9989 * handler. Note that the call to dvmCheckBefore is done as a tail call. 9990 * rIBASE updates won't be seen until a refresh, and we can tell we have a 9991 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 9992 * bail to the real handler if breakFlags==0. 9993 */ 9994 ldrb r3, [rSELF, #offThread_breakFlags] 9995 adrl lr, dvmAsmInstructionStart + (10 * 64) 9996 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 9997 cmp r3, #0 9998 bxeq lr @ nothing to do - jump to real handler 9999 EXPORT_PC() 10000 mov r0, rPC @ arg0 10001 mov r1, rFP @ arg1 10002 mov r2, rSELF @ arg2 10003 b dvmCheckBefore @ (dPC,dFP,self) tail call 10004 10005/* ------------------------------ */ 10006 .balign 64 10007.L_ALT_OP_MOVE_RESULT_WIDE: /* 0x0b */ 10008/* File: armv5te/alt_stub.S */ 10009/* 10010 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10011 * any interesting requests and then jump to the real instruction 10012 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10013 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10014 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10015 * bail to the real handler if breakFlags==0. 10016 */ 10017 ldrb r3, [rSELF, #offThread_breakFlags] 10018 adrl lr, dvmAsmInstructionStart + (11 * 64) 10019 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10020 cmp r3, #0 10021 bxeq lr @ nothing to do - jump to real handler 10022 EXPORT_PC() 10023 mov r0, rPC @ arg0 10024 mov r1, rFP @ arg1 10025 mov r2, rSELF @ arg2 10026 b dvmCheckBefore @ (dPC,dFP,self) tail call 10027 10028/* ------------------------------ */ 10029 .balign 64 10030.L_ALT_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 10031/* File: armv5te/alt_stub.S */ 10032/* 10033 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10034 * any interesting requests and then jump to the real instruction 10035 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10036 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10037 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10038 * bail to the real handler if breakFlags==0. 10039 */ 10040 ldrb r3, [rSELF, #offThread_breakFlags] 10041 adrl lr, dvmAsmInstructionStart + (12 * 64) 10042 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10043 cmp r3, #0 10044 bxeq lr @ nothing to do - jump to real handler 10045 EXPORT_PC() 10046 mov r0, rPC @ arg0 10047 mov r1, rFP @ arg1 10048 mov r2, rSELF @ arg2 10049 b dvmCheckBefore @ (dPC,dFP,self) tail call 10050 10051/* ------------------------------ */ 10052 .balign 64 10053.L_ALT_OP_MOVE_EXCEPTION: /* 0x0d */ 10054/* File: armv5te/alt_stub.S */ 10055/* 10056 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10057 * any interesting requests and then jump to the real instruction 10058 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10059 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10060 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10061 * bail to the real handler if breakFlags==0. 10062 */ 10063 ldrb r3, [rSELF, #offThread_breakFlags] 10064 adrl lr, dvmAsmInstructionStart + (13 * 64) 10065 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10066 cmp r3, #0 10067 bxeq lr @ nothing to do - jump to real handler 10068 EXPORT_PC() 10069 mov r0, rPC @ arg0 10070 mov r1, rFP @ arg1 10071 mov r2, rSELF @ arg2 10072 b dvmCheckBefore @ (dPC,dFP,self) tail call 10073 10074/* ------------------------------ */ 10075 .balign 64 10076.L_ALT_OP_RETURN_VOID: /* 0x0e */ 10077/* File: armv5te/alt_stub.S */ 10078/* 10079 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10080 * any interesting requests and then jump to the real instruction 10081 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10082 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10083 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10084 * bail to the real handler if breakFlags==0. 10085 */ 10086 ldrb r3, [rSELF, #offThread_breakFlags] 10087 adrl lr, dvmAsmInstructionStart + (14 * 64) 10088 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10089 cmp r3, #0 10090 bxeq lr @ nothing to do - jump to real handler 10091 EXPORT_PC() 10092 mov r0, rPC @ arg0 10093 mov r1, rFP @ arg1 10094 mov r2, rSELF @ arg2 10095 b dvmCheckBefore @ (dPC,dFP,self) tail call 10096 10097/* ------------------------------ */ 10098 .balign 64 10099.L_ALT_OP_RETURN: /* 0x0f */ 10100/* File: armv5te/alt_stub.S */ 10101/* 10102 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10103 * any interesting requests and then jump to the real instruction 10104 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10105 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10106 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10107 * bail to the real handler if breakFlags==0. 10108 */ 10109 ldrb r3, [rSELF, #offThread_breakFlags] 10110 adrl lr, dvmAsmInstructionStart + (15 * 64) 10111 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10112 cmp r3, #0 10113 bxeq lr @ nothing to do - jump to real handler 10114 EXPORT_PC() 10115 mov r0, rPC @ arg0 10116 mov r1, rFP @ arg1 10117 mov r2, rSELF @ arg2 10118 b dvmCheckBefore @ (dPC,dFP,self) tail call 10119 10120/* ------------------------------ */ 10121 .balign 64 10122.L_ALT_OP_RETURN_WIDE: /* 0x10 */ 10123/* File: armv5te/alt_stub.S */ 10124/* 10125 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10126 * any interesting requests and then jump to the real instruction 10127 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10128 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10129 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10130 * bail to the real handler if breakFlags==0. 10131 */ 10132 ldrb r3, [rSELF, #offThread_breakFlags] 10133 adrl lr, dvmAsmInstructionStart + (16 * 64) 10134 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10135 cmp r3, #0 10136 bxeq lr @ nothing to do - jump to real handler 10137 EXPORT_PC() 10138 mov r0, rPC @ arg0 10139 mov r1, rFP @ arg1 10140 mov r2, rSELF @ arg2 10141 b dvmCheckBefore @ (dPC,dFP,self) tail call 10142 10143/* ------------------------------ */ 10144 .balign 64 10145.L_ALT_OP_RETURN_OBJECT: /* 0x11 */ 10146/* File: armv5te/alt_stub.S */ 10147/* 10148 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10149 * any interesting requests and then jump to the real instruction 10150 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10151 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10152 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10153 * bail to the real handler if breakFlags==0. 10154 */ 10155 ldrb r3, [rSELF, #offThread_breakFlags] 10156 adrl lr, dvmAsmInstructionStart + (17 * 64) 10157 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10158 cmp r3, #0 10159 bxeq lr @ nothing to do - jump to real handler 10160 EXPORT_PC() 10161 mov r0, rPC @ arg0 10162 mov r1, rFP @ arg1 10163 mov r2, rSELF @ arg2 10164 b dvmCheckBefore @ (dPC,dFP,self) tail call 10165 10166/* ------------------------------ */ 10167 .balign 64 10168.L_ALT_OP_CONST_4: /* 0x12 */ 10169/* File: armv5te/alt_stub.S */ 10170/* 10171 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10172 * any interesting requests and then jump to the real instruction 10173 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10174 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10175 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10176 * bail to the real handler if breakFlags==0. 10177 */ 10178 ldrb r3, [rSELF, #offThread_breakFlags] 10179 adrl lr, dvmAsmInstructionStart + (18 * 64) 10180 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10181 cmp r3, #0 10182 bxeq lr @ nothing to do - jump to real handler 10183 EXPORT_PC() 10184 mov r0, rPC @ arg0 10185 mov r1, rFP @ arg1 10186 mov r2, rSELF @ arg2 10187 b dvmCheckBefore @ (dPC,dFP,self) tail call 10188 10189/* ------------------------------ */ 10190 .balign 64 10191.L_ALT_OP_CONST_16: /* 0x13 */ 10192/* File: armv5te/alt_stub.S */ 10193/* 10194 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10195 * any interesting requests and then jump to the real instruction 10196 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10197 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10198 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10199 * bail to the real handler if breakFlags==0. 10200 */ 10201 ldrb r3, [rSELF, #offThread_breakFlags] 10202 adrl lr, dvmAsmInstructionStart + (19 * 64) 10203 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10204 cmp r3, #0 10205 bxeq lr @ nothing to do - jump to real handler 10206 EXPORT_PC() 10207 mov r0, rPC @ arg0 10208 mov r1, rFP @ arg1 10209 mov r2, rSELF @ arg2 10210 b dvmCheckBefore @ (dPC,dFP,self) tail call 10211 10212/* ------------------------------ */ 10213 .balign 64 10214.L_ALT_OP_CONST: /* 0x14 */ 10215/* File: armv5te/alt_stub.S */ 10216/* 10217 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10218 * any interesting requests and then jump to the real instruction 10219 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10220 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10221 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10222 * bail to the real handler if breakFlags==0. 10223 */ 10224 ldrb r3, [rSELF, #offThread_breakFlags] 10225 adrl lr, dvmAsmInstructionStart + (20 * 64) 10226 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10227 cmp r3, #0 10228 bxeq lr @ nothing to do - jump to real handler 10229 EXPORT_PC() 10230 mov r0, rPC @ arg0 10231 mov r1, rFP @ arg1 10232 mov r2, rSELF @ arg2 10233 b dvmCheckBefore @ (dPC,dFP,self) tail call 10234 10235/* ------------------------------ */ 10236 .balign 64 10237.L_ALT_OP_CONST_HIGH16: /* 0x15 */ 10238/* File: armv5te/alt_stub.S */ 10239/* 10240 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10241 * any interesting requests and then jump to the real instruction 10242 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10243 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10244 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10245 * bail to the real handler if breakFlags==0. 10246 */ 10247 ldrb r3, [rSELF, #offThread_breakFlags] 10248 adrl lr, dvmAsmInstructionStart + (21 * 64) 10249 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10250 cmp r3, #0 10251 bxeq lr @ nothing to do - jump to real handler 10252 EXPORT_PC() 10253 mov r0, rPC @ arg0 10254 mov r1, rFP @ arg1 10255 mov r2, rSELF @ arg2 10256 b dvmCheckBefore @ (dPC,dFP,self) tail call 10257 10258/* ------------------------------ */ 10259 .balign 64 10260.L_ALT_OP_CONST_WIDE_16: /* 0x16 */ 10261/* File: armv5te/alt_stub.S */ 10262/* 10263 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10264 * any interesting requests and then jump to the real instruction 10265 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10266 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10267 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10268 * bail to the real handler if breakFlags==0. 10269 */ 10270 ldrb r3, [rSELF, #offThread_breakFlags] 10271 adrl lr, dvmAsmInstructionStart + (22 * 64) 10272 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10273 cmp r3, #0 10274 bxeq lr @ nothing to do - jump to real handler 10275 EXPORT_PC() 10276 mov r0, rPC @ arg0 10277 mov r1, rFP @ arg1 10278 mov r2, rSELF @ arg2 10279 b dvmCheckBefore @ (dPC,dFP,self) tail call 10280 10281/* ------------------------------ */ 10282 .balign 64 10283.L_ALT_OP_CONST_WIDE_32: /* 0x17 */ 10284/* File: armv5te/alt_stub.S */ 10285/* 10286 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10287 * any interesting requests and then jump to the real instruction 10288 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10289 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10290 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10291 * bail to the real handler if breakFlags==0. 10292 */ 10293 ldrb r3, [rSELF, #offThread_breakFlags] 10294 adrl lr, dvmAsmInstructionStart + (23 * 64) 10295 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10296 cmp r3, #0 10297 bxeq lr @ nothing to do - jump to real handler 10298 EXPORT_PC() 10299 mov r0, rPC @ arg0 10300 mov r1, rFP @ arg1 10301 mov r2, rSELF @ arg2 10302 b dvmCheckBefore @ (dPC,dFP,self) tail call 10303 10304/* ------------------------------ */ 10305 .balign 64 10306.L_ALT_OP_CONST_WIDE: /* 0x18 */ 10307/* File: armv5te/alt_stub.S */ 10308/* 10309 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10310 * any interesting requests and then jump to the real instruction 10311 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10312 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10313 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10314 * bail to the real handler if breakFlags==0. 10315 */ 10316 ldrb r3, [rSELF, #offThread_breakFlags] 10317 adrl lr, dvmAsmInstructionStart + (24 * 64) 10318 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10319 cmp r3, #0 10320 bxeq lr @ nothing to do - jump to real handler 10321 EXPORT_PC() 10322 mov r0, rPC @ arg0 10323 mov r1, rFP @ arg1 10324 mov r2, rSELF @ arg2 10325 b dvmCheckBefore @ (dPC,dFP,self) tail call 10326 10327/* ------------------------------ */ 10328 .balign 64 10329.L_ALT_OP_CONST_WIDE_HIGH16: /* 0x19 */ 10330/* File: armv5te/alt_stub.S */ 10331/* 10332 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10333 * any interesting requests and then jump to the real instruction 10334 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10335 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10336 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10337 * bail to the real handler if breakFlags==0. 10338 */ 10339 ldrb r3, [rSELF, #offThread_breakFlags] 10340 adrl lr, dvmAsmInstructionStart + (25 * 64) 10341 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10342 cmp r3, #0 10343 bxeq lr @ nothing to do - jump to real handler 10344 EXPORT_PC() 10345 mov r0, rPC @ arg0 10346 mov r1, rFP @ arg1 10347 mov r2, rSELF @ arg2 10348 b dvmCheckBefore @ (dPC,dFP,self) tail call 10349 10350/* ------------------------------ */ 10351 .balign 64 10352.L_ALT_OP_CONST_STRING: /* 0x1a */ 10353/* File: armv5te/alt_stub.S */ 10354/* 10355 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10356 * any interesting requests and then jump to the real instruction 10357 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10358 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10359 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10360 * bail to the real handler if breakFlags==0. 10361 */ 10362 ldrb r3, [rSELF, #offThread_breakFlags] 10363 adrl lr, dvmAsmInstructionStart + (26 * 64) 10364 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10365 cmp r3, #0 10366 bxeq lr @ nothing to do - jump to real handler 10367 EXPORT_PC() 10368 mov r0, rPC @ arg0 10369 mov r1, rFP @ arg1 10370 mov r2, rSELF @ arg2 10371 b dvmCheckBefore @ (dPC,dFP,self) tail call 10372 10373/* ------------------------------ */ 10374 .balign 64 10375.L_ALT_OP_CONST_STRING_JUMBO: /* 0x1b */ 10376/* File: armv5te/alt_stub.S */ 10377/* 10378 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10379 * any interesting requests and then jump to the real instruction 10380 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10381 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10382 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10383 * bail to the real handler if breakFlags==0. 10384 */ 10385 ldrb r3, [rSELF, #offThread_breakFlags] 10386 adrl lr, dvmAsmInstructionStart + (27 * 64) 10387 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10388 cmp r3, #0 10389 bxeq lr @ nothing to do - jump to real handler 10390 EXPORT_PC() 10391 mov r0, rPC @ arg0 10392 mov r1, rFP @ arg1 10393 mov r2, rSELF @ arg2 10394 b dvmCheckBefore @ (dPC,dFP,self) tail call 10395 10396/* ------------------------------ */ 10397 .balign 64 10398.L_ALT_OP_CONST_CLASS: /* 0x1c */ 10399/* File: armv5te/alt_stub.S */ 10400/* 10401 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10402 * any interesting requests and then jump to the real instruction 10403 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10404 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10405 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10406 * bail to the real handler if breakFlags==0. 10407 */ 10408 ldrb r3, [rSELF, #offThread_breakFlags] 10409 adrl lr, dvmAsmInstructionStart + (28 * 64) 10410 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10411 cmp r3, #0 10412 bxeq lr @ nothing to do - jump to real handler 10413 EXPORT_PC() 10414 mov r0, rPC @ arg0 10415 mov r1, rFP @ arg1 10416 mov r2, rSELF @ arg2 10417 b dvmCheckBefore @ (dPC,dFP,self) tail call 10418 10419/* ------------------------------ */ 10420 .balign 64 10421.L_ALT_OP_MONITOR_ENTER: /* 0x1d */ 10422/* File: armv5te/alt_stub.S */ 10423/* 10424 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10425 * any interesting requests and then jump to the real instruction 10426 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10427 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10428 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10429 * bail to the real handler if breakFlags==0. 10430 */ 10431 ldrb r3, [rSELF, #offThread_breakFlags] 10432 adrl lr, dvmAsmInstructionStart + (29 * 64) 10433 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10434 cmp r3, #0 10435 bxeq lr @ nothing to do - jump to real handler 10436 EXPORT_PC() 10437 mov r0, rPC @ arg0 10438 mov r1, rFP @ arg1 10439 mov r2, rSELF @ arg2 10440 b dvmCheckBefore @ (dPC,dFP,self) tail call 10441 10442/* ------------------------------ */ 10443 .balign 64 10444.L_ALT_OP_MONITOR_EXIT: /* 0x1e */ 10445/* File: armv5te/alt_stub.S */ 10446/* 10447 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10448 * any interesting requests and then jump to the real instruction 10449 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10450 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10451 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10452 * bail to the real handler if breakFlags==0. 10453 */ 10454 ldrb r3, [rSELF, #offThread_breakFlags] 10455 adrl lr, dvmAsmInstructionStart + (30 * 64) 10456 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10457 cmp r3, #0 10458 bxeq lr @ nothing to do - jump to real handler 10459 EXPORT_PC() 10460 mov r0, rPC @ arg0 10461 mov r1, rFP @ arg1 10462 mov r2, rSELF @ arg2 10463 b dvmCheckBefore @ (dPC,dFP,self) tail call 10464 10465/* ------------------------------ */ 10466 .balign 64 10467.L_ALT_OP_CHECK_CAST: /* 0x1f */ 10468/* File: armv5te/alt_stub.S */ 10469/* 10470 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10471 * any interesting requests and then jump to the real instruction 10472 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10473 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10474 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10475 * bail to the real handler if breakFlags==0. 10476 */ 10477 ldrb r3, [rSELF, #offThread_breakFlags] 10478 adrl lr, dvmAsmInstructionStart + (31 * 64) 10479 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10480 cmp r3, #0 10481 bxeq lr @ nothing to do - jump to real handler 10482 EXPORT_PC() 10483 mov r0, rPC @ arg0 10484 mov r1, rFP @ arg1 10485 mov r2, rSELF @ arg2 10486 b dvmCheckBefore @ (dPC,dFP,self) tail call 10487 10488/* ------------------------------ */ 10489 .balign 64 10490.L_ALT_OP_INSTANCE_OF: /* 0x20 */ 10491/* File: armv5te/alt_stub.S */ 10492/* 10493 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10494 * any interesting requests and then jump to the real instruction 10495 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10496 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10497 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10498 * bail to the real handler if breakFlags==0. 10499 */ 10500 ldrb r3, [rSELF, #offThread_breakFlags] 10501 adrl lr, dvmAsmInstructionStart + (32 * 64) 10502 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10503 cmp r3, #0 10504 bxeq lr @ nothing to do - jump to real handler 10505 EXPORT_PC() 10506 mov r0, rPC @ arg0 10507 mov r1, rFP @ arg1 10508 mov r2, rSELF @ arg2 10509 b dvmCheckBefore @ (dPC,dFP,self) tail call 10510 10511/* ------------------------------ */ 10512 .balign 64 10513.L_ALT_OP_ARRAY_LENGTH: /* 0x21 */ 10514/* File: armv5te/alt_stub.S */ 10515/* 10516 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10517 * any interesting requests and then jump to the real instruction 10518 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10519 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10520 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10521 * bail to the real handler if breakFlags==0. 10522 */ 10523 ldrb r3, [rSELF, #offThread_breakFlags] 10524 adrl lr, dvmAsmInstructionStart + (33 * 64) 10525 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10526 cmp r3, #0 10527 bxeq lr @ nothing to do - jump to real handler 10528 EXPORT_PC() 10529 mov r0, rPC @ arg0 10530 mov r1, rFP @ arg1 10531 mov r2, rSELF @ arg2 10532 b dvmCheckBefore @ (dPC,dFP,self) tail call 10533 10534/* ------------------------------ */ 10535 .balign 64 10536.L_ALT_OP_NEW_INSTANCE: /* 0x22 */ 10537/* File: armv5te/alt_stub.S */ 10538/* 10539 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10540 * any interesting requests and then jump to the real instruction 10541 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10542 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10543 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10544 * bail to the real handler if breakFlags==0. 10545 */ 10546 ldrb r3, [rSELF, #offThread_breakFlags] 10547 adrl lr, dvmAsmInstructionStart + (34 * 64) 10548 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10549 cmp r3, #0 10550 bxeq lr @ nothing to do - jump to real handler 10551 EXPORT_PC() 10552 mov r0, rPC @ arg0 10553 mov r1, rFP @ arg1 10554 mov r2, rSELF @ arg2 10555 b dvmCheckBefore @ (dPC,dFP,self) tail call 10556 10557/* ------------------------------ */ 10558 .balign 64 10559.L_ALT_OP_NEW_ARRAY: /* 0x23 */ 10560/* File: armv5te/alt_stub.S */ 10561/* 10562 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10563 * any interesting requests and then jump to the real instruction 10564 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10565 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10566 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10567 * bail to the real handler if breakFlags==0. 10568 */ 10569 ldrb r3, [rSELF, #offThread_breakFlags] 10570 adrl lr, dvmAsmInstructionStart + (35 * 64) 10571 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10572 cmp r3, #0 10573 bxeq lr @ nothing to do - jump to real handler 10574 EXPORT_PC() 10575 mov r0, rPC @ arg0 10576 mov r1, rFP @ arg1 10577 mov r2, rSELF @ arg2 10578 b dvmCheckBefore @ (dPC,dFP,self) tail call 10579 10580/* ------------------------------ */ 10581 .balign 64 10582.L_ALT_OP_FILLED_NEW_ARRAY: /* 0x24 */ 10583/* File: armv5te/alt_stub.S */ 10584/* 10585 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10586 * any interesting requests and then jump to the real instruction 10587 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10588 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10589 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10590 * bail to the real handler if breakFlags==0. 10591 */ 10592 ldrb r3, [rSELF, #offThread_breakFlags] 10593 adrl lr, dvmAsmInstructionStart + (36 * 64) 10594 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10595 cmp r3, #0 10596 bxeq lr @ nothing to do - jump to real handler 10597 EXPORT_PC() 10598 mov r0, rPC @ arg0 10599 mov r1, rFP @ arg1 10600 mov r2, rSELF @ arg2 10601 b dvmCheckBefore @ (dPC,dFP,self) tail call 10602 10603/* ------------------------------ */ 10604 .balign 64 10605.L_ALT_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 10606/* File: armv5te/alt_stub.S */ 10607/* 10608 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10609 * any interesting requests and then jump to the real instruction 10610 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10611 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10612 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10613 * bail to the real handler if breakFlags==0. 10614 */ 10615 ldrb r3, [rSELF, #offThread_breakFlags] 10616 adrl lr, dvmAsmInstructionStart + (37 * 64) 10617 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10618 cmp r3, #0 10619 bxeq lr @ nothing to do - jump to real handler 10620 EXPORT_PC() 10621 mov r0, rPC @ arg0 10622 mov r1, rFP @ arg1 10623 mov r2, rSELF @ arg2 10624 b dvmCheckBefore @ (dPC,dFP,self) tail call 10625 10626/* ------------------------------ */ 10627 .balign 64 10628.L_ALT_OP_FILL_ARRAY_DATA: /* 0x26 */ 10629/* File: armv5te/alt_stub.S */ 10630/* 10631 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10632 * any interesting requests and then jump to the real instruction 10633 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10634 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10635 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10636 * bail to the real handler if breakFlags==0. 10637 */ 10638 ldrb r3, [rSELF, #offThread_breakFlags] 10639 adrl lr, dvmAsmInstructionStart + (38 * 64) 10640 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10641 cmp r3, #0 10642 bxeq lr @ nothing to do - jump to real handler 10643 EXPORT_PC() 10644 mov r0, rPC @ arg0 10645 mov r1, rFP @ arg1 10646 mov r2, rSELF @ arg2 10647 b dvmCheckBefore @ (dPC,dFP,self) tail call 10648 10649/* ------------------------------ */ 10650 .balign 64 10651.L_ALT_OP_THROW: /* 0x27 */ 10652/* File: armv5te/alt_stub.S */ 10653/* 10654 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10655 * any interesting requests and then jump to the real instruction 10656 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10657 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10658 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10659 * bail to the real handler if breakFlags==0. 10660 */ 10661 ldrb r3, [rSELF, #offThread_breakFlags] 10662 adrl lr, dvmAsmInstructionStart + (39 * 64) 10663 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10664 cmp r3, #0 10665 bxeq lr @ nothing to do - jump to real handler 10666 EXPORT_PC() 10667 mov r0, rPC @ arg0 10668 mov r1, rFP @ arg1 10669 mov r2, rSELF @ arg2 10670 b dvmCheckBefore @ (dPC,dFP,self) tail call 10671 10672/* ------------------------------ */ 10673 .balign 64 10674.L_ALT_OP_GOTO: /* 0x28 */ 10675/* File: armv5te/alt_stub.S */ 10676/* 10677 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10678 * any interesting requests and then jump to the real instruction 10679 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10680 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10681 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10682 * bail to the real handler if breakFlags==0. 10683 */ 10684 ldrb r3, [rSELF, #offThread_breakFlags] 10685 adrl lr, dvmAsmInstructionStart + (40 * 64) 10686 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10687 cmp r3, #0 10688 bxeq lr @ nothing to do - jump to real handler 10689 EXPORT_PC() 10690 mov r0, rPC @ arg0 10691 mov r1, rFP @ arg1 10692 mov r2, rSELF @ arg2 10693 b dvmCheckBefore @ (dPC,dFP,self) tail call 10694 10695/* ------------------------------ */ 10696 .balign 64 10697.L_ALT_OP_GOTO_16: /* 0x29 */ 10698/* File: armv5te/alt_stub.S */ 10699/* 10700 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10701 * any interesting requests and then jump to the real instruction 10702 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10703 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10704 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10705 * bail to the real handler if breakFlags==0. 10706 */ 10707 ldrb r3, [rSELF, #offThread_breakFlags] 10708 adrl lr, dvmAsmInstructionStart + (41 * 64) 10709 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10710 cmp r3, #0 10711 bxeq lr @ nothing to do - jump to real handler 10712 EXPORT_PC() 10713 mov r0, rPC @ arg0 10714 mov r1, rFP @ arg1 10715 mov r2, rSELF @ arg2 10716 b dvmCheckBefore @ (dPC,dFP,self) tail call 10717 10718/* ------------------------------ */ 10719 .balign 64 10720.L_ALT_OP_GOTO_32: /* 0x2a */ 10721/* File: armv5te/alt_stub.S */ 10722/* 10723 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10724 * any interesting requests and then jump to the real instruction 10725 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10726 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10727 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10728 * bail to the real handler if breakFlags==0. 10729 */ 10730 ldrb r3, [rSELF, #offThread_breakFlags] 10731 adrl lr, dvmAsmInstructionStart + (42 * 64) 10732 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10733 cmp r3, #0 10734 bxeq lr @ nothing to do - jump to real handler 10735 EXPORT_PC() 10736 mov r0, rPC @ arg0 10737 mov r1, rFP @ arg1 10738 mov r2, rSELF @ arg2 10739 b dvmCheckBefore @ (dPC,dFP,self) tail call 10740 10741/* ------------------------------ */ 10742 .balign 64 10743.L_ALT_OP_PACKED_SWITCH: /* 0x2b */ 10744/* File: armv5te/alt_stub.S */ 10745/* 10746 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10747 * any interesting requests and then jump to the real instruction 10748 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10749 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10750 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10751 * bail to the real handler if breakFlags==0. 10752 */ 10753 ldrb r3, [rSELF, #offThread_breakFlags] 10754 adrl lr, dvmAsmInstructionStart + (43 * 64) 10755 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10756 cmp r3, #0 10757 bxeq lr @ nothing to do - jump to real handler 10758 EXPORT_PC() 10759 mov r0, rPC @ arg0 10760 mov r1, rFP @ arg1 10761 mov r2, rSELF @ arg2 10762 b dvmCheckBefore @ (dPC,dFP,self) tail call 10763 10764/* ------------------------------ */ 10765 .balign 64 10766.L_ALT_OP_SPARSE_SWITCH: /* 0x2c */ 10767/* File: armv5te/alt_stub.S */ 10768/* 10769 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10770 * any interesting requests and then jump to the real instruction 10771 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10772 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10773 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10774 * bail to the real handler if breakFlags==0. 10775 */ 10776 ldrb r3, [rSELF, #offThread_breakFlags] 10777 adrl lr, dvmAsmInstructionStart + (44 * 64) 10778 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10779 cmp r3, #0 10780 bxeq lr @ nothing to do - jump to real handler 10781 EXPORT_PC() 10782 mov r0, rPC @ arg0 10783 mov r1, rFP @ arg1 10784 mov r2, rSELF @ arg2 10785 b dvmCheckBefore @ (dPC,dFP,self) tail call 10786 10787/* ------------------------------ */ 10788 .balign 64 10789.L_ALT_OP_CMPL_FLOAT: /* 0x2d */ 10790/* File: armv5te/alt_stub.S */ 10791/* 10792 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10793 * any interesting requests and then jump to the real instruction 10794 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10795 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10796 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10797 * bail to the real handler if breakFlags==0. 10798 */ 10799 ldrb r3, [rSELF, #offThread_breakFlags] 10800 adrl lr, dvmAsmInstructionStart + (45 * 64) 10801 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10802 cmp r3, #0 10803 bxeq lr @ nothing to do - jump to real handler 10804 EXPORT_PC() 10805 mov r0, rPC @ arg0 10806 mov r1, rFP @ arg1 10807 mov r2, rSELF @ arg2 10808 b dvmCheckBefore @ (dPC,dFP,self) tail call 10809 10810/* ------------------------------ */ 10811 .balign 64 10812.L_ALT_OP_CMPG_FLOAT: /* 0x2e */ 10813/* File: armv5te/alt_stub.S */ 10814/* 10815 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10816 * any interesting requests and then jump to the real instruction 10817 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10818 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10819 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10820 * bail to the real handler if breakFlags==0. 10821 */ 10822 ldrb r3, [rSELF, #offThread_breakFlags] 10823 adrl lr, dvmAsmInstructionStart + (46 * 64) 10824 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10825 cmp r3, #0 10826 bxeq lr @ nothing to do - jump to real handler 10827 EXPORT_PC() 10828 mov r0, rPC @ arg0 10829 mov r1, rFP @ arg1 10830 mov r2, rSELF @ arg2 10831 b dvmCheckBefore @ (dPC,dFP,self) tail call 10832 10833/* ------------------------------ */ 10834 .balign 64 10835.L_ALT_OP_CMPL_DOUBLE: /* 0x2f */ 10836/* File: armv5te/alt_stub.S */ 10837/* 10838 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10839 * any interesting requests and then jump to the real instruction 10840 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10841 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10842 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10843 * bail to the real handler if breakFlags==0. 10844 */ 10845 ldrb r3, [rSELF, #offThread_breakFlags] 10846 adrl lr, dvmAsmInstructionStart + (47 * 64) 10847 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10848 cmp r3, #0 10849 bxeq lr @ nothing to do - jump to real handler 10850 EXPORT_PC() 10851 mov r0, rPC @ arg0 10852 mov r1, rFP @ arg1 10853 mov r2, rSELF @ arg2 10854 b dvmCheckBefore @ (dPC,dFP,self) tail call 10855 10856/* ------------------------------ */ 10857 .balign 64 10858.L_ALT_OP_CMPG_DOUBLE: /* 0x30 */ 10859/* File: armv5te/alt_stub.S */ 10860/* 10861 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10862 * any interesting requests and then jump to the real instruction 10863 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10864 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10865 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10866 * bail to the real handler if breakFlags==0. 10867 */ 10868 ldrb r3, [rSELF, #offThread_breakFlags] 10869 adrl lr, dvmAsmInstructionStart + (48 * 64) 10870 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10871 cmp r3, #0 10872 bxeq lr @ nothing to do - jump to real handler 10873 EXPORT_PC() 10874 mov r0, rPC @ arg0 10875 mov r1, rFP @ arg1 10876 mov r2, rSELF @ arg2 10877 b dvmCheckBefore @ (dPC,dFP,self) tail call 10878 10879/* ------------------------------ */ 10880 .balign 64 10881.L_ALT_OP_CMP_LONG: /* 0x31 */ 10882/* File: armv5te/alt_stub.S */ 10883/* 10884 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10885 * any interesting requests and then jump to the real instruction 10886 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10887 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10888 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10889 * bail to the real handler if breakFlags==0. 10890 */ 10891 ldrb r3, [rSELF, #offThread_breakFlags] 10892 adrl lr, dvmAsmInstructionStart + (49 * 64) 10893 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10894 cmp r3, #0 10895 bxeq lr @ nothing to do - jump to real handler 10896 EXPORT_PC() 10897 mov r0, rPC @ arg0 10898 mov r1, rFP @ arg1 10899 mov r2, rSELF @ arg2 10900 b dvmCheckBefore @ (dPC,dFP,self) tail call 10901 10902/* ------------------------------ */ 10903 .balign 64 10904.L_ALT_OP_IF_EQ: /* 0x32 */ 10905/* File: armv5te/alt_stub.S */ 10906/* 10907 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10908 * any interesting requests and then jump to the real instruction 10909 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10910 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10911 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10912 * bail to the real handler if breakFlags==0. 10913 */ 10914 ldrb r3, [rSELF, #offThread_breakFlags] 10915 adrl lr, dvmAsmInstructionStart + (50 * 64) 10916 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10917 cmp r3, #0 10918 bxeq lr @ nothing to do - jump to real handler 10919 EXPORT_PC() 10920 mov r0, rPC @ arg0 10921 mov r1, rFP @ arg1 10922 mov r2, rSELF @ arg2 10923 b dvmCheckBefore @ (dPC,dFP,self) tail call 10924 10925/* ------------------------------ */ 10926 .balign 64 10927.L_ALT_OP_IF_NE: /* 0x33 */ 10928/* File: armv5te/alt_stub.S */ 10929/* 10930 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10931 * any interesting requests and then jump to the real instruction 10932 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10933 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10934 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10935 * bail to the real handler if breakFlags==0. 10936 */ 10937 ldrb r3, [rSELF, #offThread_breakFlags] 10938 adrl lr, dvmAsmInstructionStart + (51 * 64) 10939 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10940 cmp r3, #0 10941 bxeq lr @ nothing to do - jump to real handler 10942 EXPORT_PC() 10943 mov r0, rPC @ arg0 10944 mov r1, rFP @ arg1 10945 mov r2, rSELF @ arg2 10946 b dvmCheckBefore @ (dPC,dFP,self) tail call 10947 10948/* ------------------------------ */ 10949 .balign 64 10950.L_ALT_OP_IF_LT: /* 0x34 */ 10951/* File: armv5te/alt_stub.S */ 10952/* 10953 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10954 * any interesting requests and then jump to the real instruction 10955 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10956 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10957 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10958 * bail to the real handler if breakFlags==0. 10959 */ 10960 ldrb r3, [rSELF, #offThread_breakFlags] 10961 adrl lr, dvmAsmInstructionStart + (52 * 64) 10962 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10963 cmp r3, #0 10964 bxeq lr @ nothing to do - jump to real handler 10965 EXPORT_PC() 10966 mov r0, rPC @ arg0 10967 mov r1, rFP @ arg1 10968 mov r2, rSELF @ arg2 10969 b dvmCheckBefore @ (dPC,dFP,self) tail call 10970 10971/* ------------------------------ */ 10972 .balign 64 10973.L_ALT_OP_IF_GE: /* 0x35 */ 10974/* File: armv5te/alt_stub.S */ 10975/* 10976 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 10977 * any interesting requests and then jump to the real instruction 10978 * handler. Note that the call to dvmCheckBefore is done as a tail call. 10979 * rIBASE updates won't be seen until a refresh, and we can tell we have a 10980 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 10981 * bail to the real handler if breakFlags==0. 10982 */ 10983 ldrb r3, [rSELF, #offThread_breakFlags] 10984 adrl lr, dvmAsmInstructionStart + (53 * 64) 10985 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 10986 cmp r3, #0 10987 bxeq lr @ nothing to do - jump to real handler 10988 EXPORT_PC() 10989 mov r0, rPC @ arg0 10990 mov r1, rFP @ arg1 10991 mov r2, rSELF @ arg2 10992 b dvmCheckBefore @ (dPC,dFP,self) tail call 10993 10994/* ------------------------------ */ 10995 .balign 64 10996.L_ALT_OP_IF_GT: /* 0x36 */ 10997/* File: armv5te/alt_stub.S */ 10998/* 10999 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11000 * any interesting requests and then jump to the real instruction 11001 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11002 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11003 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11004 * bail to the real handler if breakFlags==0. 11005 */ 11006 ldrb r3, [rSELF, #offThread_breakFlags] 11007 adrl lr, dvmAsmInstructionStart + (54 * 64) 11008 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11009 cmp r3, #0 11010 bxeq lr @ nothing to do - jump to real handler 11011 EXPORT_PC() 11012 mov r0, rPC @ arg0 11013 mov r1, rFP @ arg1 11014 mov r2, rSELF @ arg2 11015 b dvmCheckBefore @ (dPC,dFP,self) tail call 11016 11017/* ------------------------------ */ 11018 .balign 64 11019.L_ALT_OP_IF_LE: /* 0x37 */ 11020/* File: armv5te/alt_stub.S */ 11021/* 11022 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11023 * any interesting requests and then jump to the real instruction 11024 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11025 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11026 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11027 * bail to the real handler if breakFlags==0. 11028 */ 11029 ldrb r3, [rSELF, #offThread_breakFlags] 11030 adrl lr, dvmAsmInstructionStart + (55 * 64) 11031 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11032 cmp r3, #0 11033 bxeq lr @ nothing to do - jump to real handler 11034 EXPORT_PC() 11035 mov r0, rPC @ arg0 11036 mov r1, rFP @ arg1 11037 mov r2, rSELF @ arg2 11038 b dvmCheckBefore @ (dPC,dFP,self) tail call 11039 11040/* ------------------------------ */ 11041 .balign 64 11042.L_ALT_OP_IF_EQZ: /* 0x38 */ 11043/* File: armv5te/alt_stub.S */ 11044/* 11045 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11046 * any interesting requests and then jump to the real instruction 11047 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11048 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11049 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11050 * bail to the real handler if breakFlags==0. 11051 */ 11052 ldrb r3, [rSELF, #offThread_breakFlags] 11053 adrl lr, dvmAsmInstructionStart + (56 * 64) 11054 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11055 cmp r3, #0 11056 bxeq lr @ nothing to do - jump to real handler 11057 EXPORT_PC() 11058 mov r0, rPC @ arg0 11059 mov r1, rFP @ arg1 11060 mov r2, rSELF @ arg2 11061 b dvmCheckBefore @ (dPC,dFP,self) tail call 11062 11063/* ------------------------------ */ 11064 .balign 64 11065.L_ALT_OP_IF_NEZ: /* 0x39 */ 11066/* File: armv5te/alt_stub.S */ 11067/* 11068 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11069 * any interesting requests and then jump to the real instruction 11070 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11071 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11072 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11073 * bail to the real handler if breakFlags==0. 11074 */ 11075 ldrb r3, [rSELF, #offThread_breakFlags] 11076 adrl lr, dvmAsmInstructionStart + (57 * 64) 11077 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11078 cmp r3, #0 11079 bxeq lr @ nothing to do - jump to real handler 11080 EXPORT_PC() 11081 mov r0, rPC @ arg0 11082 mov r1, rFP @ arg1 11083 mov r2, rSELF @ arg2 11084 b dvmCheckBefore @ (dPC,dFP,self) tail call 11085 11086/* ------------------------------ */ 11087 .balign 64 11088.L_ALT_OP_IF_LTZ: /* 0x3a */ 11089/* File: armv5te/alt_stub.S */ 11090/* 11091 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11092 * any interesting requests and then jump to the real instruction 11093 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11094 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11095 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11096 * bail to the real handler if breakFlags==0. 11097 */ 11098 ldrb r3, [rSELF, #offThread_breakFlags] 11099 adrl lr, dvmAsmInstructionStart + (58 * 64) 11100 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11101 cmp r3, #0 11102 bxeq lr @ nothing to do - jump to real handler 11103 EXPORT_PC() 11104 mov r0, rPC @ arg0 11105 mov r1, rFP @ arg1 11106 mov r2, rSELF @ arg2 11107 b dvmCheckBefore @ (dPC,dFP,self) tail call 11108 11109/* ------------------------------ */ 11110 .balign 64 11111.L_ALT_OP_IF_GEZ: /* 0x3b */ 11112/* File: armv5te/alt_stub.S */ 11113/* 11114 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11115 * any interesting requests and then jump to the real instruction 11116 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11117 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11118 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11119 * bail to the real handler if breakFlags==0. 11120 */ 11121 ldrb r3, [rSELF, #offThread_breakFlags] 11122 adrl lr, dvmAsmInstructionStart + (59 * 64) 11123 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11124 cmp r3, #0 11125 bxeq lr @ nothing to do - jump to real handler 11126 EXPORT_PC() 11127 mov r0, rPC @ arg0 11128 mov r1, rFP @ arg1 11129 mov r2, rSELF @ arg2 11130 b dvmCheckBefore @ (dPC,dFP,self) tail call 11131 11132/* ------------------------------ */ 11133 .balign 64 11134.L_ALT_OP_IF_GTZ: /* 0x3c */ 11135/* File: armv5te/alt_stub.S */ 11136/* 11137 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11138 * any interesting requests and then jump to the real instruction 11139 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11140 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11141 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11142 * bail to the real handler if breakFlags==0. 11143 */ 11144 ldrb r3, [rSELF, #offThread_breakFlags] 11145 adrl lr, dvmAsmInstructionStart + (60 * 64) 11146 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11147 cmp r3, #0 11148 bxeq lr @ nothing to do - jump to real handler 11149 EXPORT_PC() 11150 mov r0, rPC @ arg0 11151 mov r1, rFP @ arg1 11152 mov r2, rSELF @ arg2 11153 b dvmCheckBefore @ (dPC,dFP,self) tail call 11154 11155/* ------------------------------ */ 11156 .balign 64 11157.L_ALT_OP_IF_LEZ: /* 0x3d */ 11158/* File: armv5te/alt_stub.S */ 11159/* 11160 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11161 * any interesting requests and then jump to the real instruction 11162 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11163 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11164 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11165 * bail to the real handler if breakFlags==0. 11166 */ 11167 ldrb r3, [rSELF, #offThread_breakFlags] 11168 adrl lr, dvmAsmInstructionStart + (61 * 64) 11169 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11170 cmp r3, #0 11171 bxeq lr @ nothing to do - jump to real handler 11172 EXPORT_PC() 11173 mov r0, rPC @ arg0 11174 mov r1, rFP @ arg1 11175 mov r2, rSELF @ arg2 11176 b dvmCheckBefore @ (dPC,dFP,self) tail call 11177 11178/* ------------------------------ */ 11179 .balign 64 11180.L_ALT_OP_UNUSED_3E: /* 0x3e */ 11181/* File: armv5te/alt_stub.S */ 11182/* 11183 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11184 * any interesting requests and then jump to the real instruction 11185 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11186 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11187 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11188 * bail to the real handler if breakFlags==0. 11189 */ 11190 ldrb r3, [rSELF, #offThread_breakFlags] 11191 adrl lr, dvmAsmInstructionStart + (62 * 64) 11192 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11193 cmp r3, #0 11194 bxeq lr @ nothing to do - jump to real handler 11195 EXPORT_PC() 11196 mov r0, rPC @ arg0 11197 mov r1, rFP @ arg1 11198 mov r2, rSELF @ arg2 11199 b dvmCheckBefore @ (dPC,dFP,self) tail call 11200 11201/* ------------------------------ */ 11202 .balign 64 11203.L_ALT_OP_UNUSED_3F: /* 0x3f */ 11204/* File: armv5te/alt_stub.S */ 11205/* 11206 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11207 * any interesting requests and then jump to the real instruction 11208 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11209 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11210 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11211 * bail to the real handler if breakFlags==0. 11212 */ 11213 ldrb r3, [rSELF, #offThread_breakFlags] 11214 adrl lr, dvmAsmInstructionStart + (63 * 64) 11215 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11216 cmp r3, #0 11217 bxeq lr @ nothing to do - jump to real handler 11218 EXPORT_PC() 11219 mov r0, rPC @ arg0 11220 mov r1, rFP @ arg1 11221 mov r2, rSELF @ arg2 11222 b dvmCheckBefore @ (dPC,dFP,self) tail call 11223 11224/* ------------------------------ */ 11225 .balign 64 11226.L_ALT_OP_UNUSED_40: /* 0x40 */ 11227/* File: armv5te/alt_stub.S */ 11228/* 11229 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11230 * any interesting requests and then jump to the real instruction 11231 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11232 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11233 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11234 * bail to the real handler if breakFlags==0. 11235 */ 11236 ldrb r3, [rSELF, #offThread_breakFlags] 11237 adrl lr, dvmAsmInstructionStart + (64 * 64) 11238 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11239 cmp r3, #0 11240 bxeq lr @ nothing to do - jump to real handler 11241 EXPORT_PC() 11242 mov r0, rPC @ arg0 11243 mov r1, rFP @ arg1 11244 mov r2, rSELF @ arg2 11245 b dvmCheckBefore @ (dPC,dFP,self) tail call 11246 11247/* ------------------------------ */ 11248 .balign 64 11249.L_ALT_OP_UNUSED_41: /* 0x41 */ 11250/* File: armv5te/alt_stub.S */ 11251/* 11252 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11253 * any interesting requests and then jump to the real instruction 11254 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11255 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11256 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11257 * bail to the real handler if breakFlags==0. 11258 */ 11259 ldrb r3, [rSELF, #offThread_breakFlags] 11260 adrl lr, dvmAsmInstructionStart + (65 * 64) 11261 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11262 cmp r3, #0 11263 bxeq lr @ nothing to do - jump to real handler 11264 EXPORT_PC() 11265 mov r0, rPC @ arg0 11266 mov r1, rFP @ arg1 11267 mov r2, rSELF @ arg2 11268 b dvmCheckBefore @ (dPC,dFP,self) tail call 11269 11270/* ------------------------------ */ 11271 .balign 64 11272.L_ALT_OP_UNUSED_42: /* 0x42 */ 11273/* File: armv5te/alt_stub.S */ 11274/* 11275 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11276 * any interesting requests and then jump to the real instruction 11277 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11278 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11279 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11280 * bail to the real handler if breakFlags==0. 11281 */ 11282 ldrb r3, [rSELF, #offThread_breakFlags] 11283 adrl lr, dvmAsmInstructionStart + (66 * 64) 11284 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11285 cmp r3, #0 11286 bxeq lr @ nothing to do - jump to real handler 11287 EXPORT_PC() 11288 mov r0, rPC @ arg0 11289 mov r1, rFP @ arg1 11290 mov r2, rSELF @ arg2 11291 b dvmCheckBefore @ (dPC,dFP,self) tail call 11292 11293/* ------------------------------ */ 11294 .balign 64 11295.L_ALT_OP_UNUSED_43: /* 0x43 */ 11296/* File: armv5te/alt_stub.S */ 11297/* 11298 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11299 * any interesting requests and then jump to the real instruction 11300 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11301 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11302 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11303 * bail to the real handler if breakFlags==0. 11304 */ 11305 ldrb r3, [rSELF, #offThread_breakFlags] 11306 adrl lr, dvmAsmInstructionStart + (67 * 64) 11307 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11308 cmp r3, #0 11309 bxeq lr @ nothing to do - jump to real handler 11310 EXPORT_PC() 11311 mov r0, rPC @ arg0 11312 mov r1, rFP @ arg1 11313 mov r2, rSELF @ arg2 11314 b dvmCheckBefore @ (dPC,dFP,self) tail call 11315 11316/* ------------------------------ */ 11317 .balign 64 11318.L_ALT_OP_AGET: /* 0x44 */ 11319/* File: armv5te/alt_stub.S */ 11320/* 11321 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11322 * any interesting requests and then jump to the real instruction 11323 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11324 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11325 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11326 * bail to the real handler if breakFlags==0. 11327 */ 11328 ldrb r3, [rSELF, #offThread_breakFlags] 11329 adrl lr, dvmAsmInstructionStart + (68 * 64) 11330 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11331 cmp r3, #0 11332 bxeq lr @ nothing to do - jump to real handler 11333 EXPORT_PC() 11334 mov r0, rPC @ arg0 11335 mov r1, rFP @ arg1 11336 mov r2, rSELF @ arg2 11337 b dvmCheckBefore @ (dPC,dFP,self) tail call 11338 11339/* ------------------------------ */ 11340 .balign 64 11341.L_ALT_OP_AGET_WIDE: /* 0x45 */ 11342/* File: armv5te/alt_stub.S */ 11343/* 11344 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11345 * any interesting requests and then jump to the real instruction 11346 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11347 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11348 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11349 * bail to the real handler if breakFlags==0. 11350 */ 11351 ldrb r3, [rSELF, #offThread_breakFlags] 11352 adrl lr, dvmAsmInstructionStart + (69 * 64) 11353 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11354 cmp r3, #0 11355 bxeq lr @ nothing to do - jump to real handler 11356 EXPORT_PC() 11357 mov r0, rPC @ arg0 11358 mov r1, rFP @ arg1 11359 mov r2, rSELF @ arg2 11360 b dvmCheckBefore @ (dPC,dFP,self) tail call 11361 11362/* ------------------------------ */ 11363 .balign 64 11364.L_ALT_OP_AGET_OBJECT: /* 0x46 */ 11365/* File: armv5te/alt_stub.S */ 11366/* 11367 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11368 * any interesting requests and then jump to the real instruction 11369 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11370 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11371 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11372 * bail to the real handler if breakFlags==0. 11373 */ 11374 ldrb r3, [rSELF, #offThread_breakFlags] 11375 adrl lr, dvmAsmInstructionStart + (70 * 64) 11376 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11377 cmp r3, #0 11378 bxeq lr @ nothing to do - jump to real handler 11379 EXPORT_PC() 11380 mov r0, rPC @ arg0 11381 mov r1, rFP @ arg1 11382 mov r2, rSELF @ arg2 11383 b dvmCheckBefore @ (dPC,dFP,self) tail call 11384 11385/* ------------------------------ */ 11386 .balign 64 11387.L_ALT_OP_AGET_BOOLEAN: /* 0x47 */ 11388/* File: armv5te/alt_stub.S */ 11389/* 11390 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11391 * any interesting requests and then jump to the real instruction 11392 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11393 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11394 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11395 * bail to the real handler if breakFlags==0. 11396 */ 11397 ldrb r3, [rSELF, #offThread_breakFlags] 11398 adrl lr, dvmAsmInstructionStart + (71 * 64) 11399 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11400 cmp r3, #0 11401 bxeq lr @ nothing to do - jump to real handler 11402 EXPORT_PC() 11403 mov r0, rPC @ arg0 11404 mov r1, rFP @ arg1 11405 mov r2, rSELF @ arg2 11406 b dvmCheckBefore @ (dPC,dFP,self) tail call 11407 11408/* ------------------------------ */ 11409 .balign 64 11410.L_ALT_OP_AGET_BYTE: /* 0x48 */ 11411/* File: armv5te/alt_stub.S */ 11412/* 11413 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11414 * any interesting requests and then jump to the real instruction 11415 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11416 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11417 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11418 * bail to the real handler if breakFlags==0. 11419 */ 11420 ldrb r3, [rSELF, #offThread_breakFlags] 11421 adrl lr, dvmAsmInstructionStart + (72 * 64) 11422 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11423 cmp r3, #0 11424 bxeq lr @ nothing to do - jump to real handler 11425 EXPORT_PC() 11426 mov r0, rPC @ arg0 11427 mov r1, rFP @ arg1 11428 mov r2, rSELF @ arg2 11429 b dvmCheckBefore @ (dPC,dFP,self) tail call 11430 11431/* ------------------------------ */ 11432 .balign 64 11433.L_ALT_OP_AGET_CHAR: /* 0x49 */ 11434/* File: armv5te/alt_stub.S */ 11435/* 11436 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11437 * any interesting requests and then jump to the real instruction 11438 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11439 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11440 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11441 * bail to the real handler if breakFlags==0. 11442 */ 11443 ldrb r3, [rSELF, #offThread_breakFlags] 11444 adrl lr, dvmAsmInstructionStart + (73 * 64) 11445 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11446 cmp r3, #0 11447 bxeq lr @ nothing to do - jump to real handler 11448 EXPORT_PC() 11449 mov r0, rPC @ arg0 11450 mov r1, rFP @ arg1 11451 mov r2, rSELF @ arg2 11452 b dvmCheckBefore @ (dPC,dFP,self) tail call 11453 11454/* ------------------------------ */ 11455 .balign 64 11456.L_ALT_OP_AGET_SHORT: /* 0x4a */ 11457/* File: armv5te/alt_stub.S */ 11458/* 11459 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11460 * any interesting requests and then jump to the real instruction 11461 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11462 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11463 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11464 * bail to the real handler if breakFlags==0. 11465 */ 11466 ldrb r3, [rSELF, #offThread_breakFlags] 11467 adrl lr, dvmAsmInstructionStart + (74 * 64) 11468 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11469 cmp r3, #0 11470 bxeq lr @ nothing to do - jump to real handler 11471 EXPORT_PC() 11472 mov r0, rPC @ arg0 11473 mov r1, rFP @ arg1 11474 mov r2, rSELF @ arg2 11475 b dvmCheckBefore @ (dPC,dFP,self) tail call 11476 11477/* ------------------------------ */ 11478 .balign 64 11479.L_ALT_OP_APUT: /* 0x4b */ 11480/* File: armv5te/alt_stub.S */ 11481/* 11482 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11483 * any interesting requests and then jump to the real instruction 11484 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11485 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11486 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11487 * bail to the real handler if breakFlags==0. 11488 */ 11489 ldrb r3, [rSELF, #offThread_breakFlags] 11490 adrl lr, dvmAsmInstructionStart + (75 * 64) 11491 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11492 cmp r3, #0 11493 bxeq lr @ nothing to do - jump to real handler 11494 EXPORT_PC() 11495 mov r0, rPC @ arg0 11496 mov r1, rFP @ arg1 11497 mov r2, rSELF @ arg2 11498 b dvmCheckBefore @ (dPC,dFP,self) tail call 11499 11500/* ------------------------------ */ 11501 .balign 64 11502.L_ALT_OP_APUT_WIDE: /* 0x4c */ 11503/* File: armv5te/alt_stub.S */ 11504/* 11505 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11506 * any interesting requests and then jump to the real instruction 11507 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11508 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11509 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11510 * bail to the real handler if breakFlags==0. 11511 */ 11512 ldrb r3, [rSELF, #offThread_breakFlags] 11513 adrl lr, dvmAsmInstructionStart + (76 * 64) 11514 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11515 cmp r3, #0 11516 bxeq lr @ nothing to do - jump to real handler 11517 EXPORT_PC() 11518 mov r0, rPC @ arg0 11519 mov r1, rFP @ arg1 11520 mov r2, rSELF @ arg2 11521 b dvmCheckBefore @ (dPC,dFP,self) tail call 11522 11523/* ------------------------------ */ 11524 .balign 64 11525.L_ALT_OP_APUT_OBJECT: /* 0x4d */ 11526/* File: armv5te/alt_stub.S */ 11527/* 11528 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11529 * any interesting requests and then jump to the real instruction 11530 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11531 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11532 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11533 * bail to the real handler if breakFlags==0. 11534 */ 11535 ldrb r3, [rSELF, #offThread_breakFlags] 11536 adrl lr, dvmAsmInstructionStart + (77 * 64) 11537 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11538 cmp r3, #0 11539 bxeq lr @ nothing to do - jump to real handler 11540 EXPORT_PC() 11541 mov r0, rPC @ arg0 11542 mov r1, rFP @ arg1 11543 mov r2, rSELF @ arg2 11544 b dvmCheckBefore @ (dPC,dFP,self) tail call 11545 11546/* ------------------------------ */ 11547 .balign 64 11548.L_ALT_OP_APUT_BOOLEAN: /* 0x4e */ 11549/* File: armv5te/alt_stub.S */ 11550/* 11551 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11552 * any interesting requests and then jump to the real instruction 11553 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11554 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11555 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11556 * bail to the real handler if breakFlags==0. 11557 */ 11558 ldrb r3, [rSELF, #offThread_breakFlags] 11559 adrl lr, dvmAsmInstructionStart + (78 * 64) 11560 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11561 cmp r3, #0 11562 bxeq lr @ nothing to do - jump to real handler 11563 EXPORT_PC() 11564 mov r0, rPC @ arg0 11565 mov r1, rFP @ arg1 11566 mov r2, rSELF @ arg2 11567 b dvmCheckBefore @ (dPC,dFP,self) tail call 11568 11569/* ------------------------------ */ 11570 .balign 64 11571.L_ALT_OP_APUT_BYTE: /* 0x4f */ 11572/* File: armv5te/alt_stub.S */ 11573/* 11574 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11575 * any interesting requests and then jump to the real instruction 11576 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11577 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11578 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11579 * bail to the real handler if breakFlags==0. 11580 */ 11581 ldrb r3, [rSELF, #offThread_breakFlags] 11582 adrl lr, dvmAsmInstructionStart + (79 * 64) 11583 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11584 cmp r3, #0 11585 bxeq lr @ nothing to do - jump to real handler 11586 EXPORT_PC() 11587 mov r0, rPC @ arg0 11588 mov r1, rFP @ arg1 11589 mov r2, rSELF @ arg2 11590 b dvmCheckBefore @ (dPC,dFP,self) tail call 11591 11592/* ------------------------------ */ 11593 .balign 64 11594.L_ALT_OP_APUT_CHAR: /* 0x50 */ 11595/* File: armv5te/alt_stub.S */ 11596/* 11597 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11598 * any interesting requests and then jump to the real instruction 11599 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11600 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11601 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11602 * bail to the real handler if breakFlags==0. 11603 */ 11604 ldrb r3, [rSELF, #offThread_breakFlags] 11605 adrl lr, dvmAsmInstructionStart + (80 * 64) 11606 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11607 cmp r3, #0 11608 bxeq lr @ nothing to do - jump to real handler 11609 EXPORT_PC() 11610 mov r0, rPC @ arg0 11611 mov r1, rFP @ arg1 11612 mov r2, rSELF @ arg2 11613 b dvmCheckBefore @ (dPC,dFP,self) tail call 11614 11615/* ------------------------------ */ 11616 .balign 64 11617.L_ALT_OP_APUT_SHORT: /* 0x51 */ 11618/* File: armv5te/alt_stub.S */ 11619/* 11620 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11621 * any interesting requests and then jump to the real instruction 11622 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11623 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11624 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11625 * bail to the real handler if breakFlags==0. 11626 */ 11627 ldrb r3, [rSELF, #offThread_breakFlags] 11628 adrl lr, dvmAsmInstructionStart + (81 * 64) 11629 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11630 cmp r3, #0 11631 bxeq lr @ nothing to do - jump to real handler 11632 EXPORT_PC() 11633 mov r0, rPC @ arg0 11634 mov r1, rFP @ arg1 11635 mov r2, rSELF @ arg2 11636 b dvmCheckBefore @ (dPC,dFP,self) tail call 11637 11638/* ------------------------------ */ 11639 .balign 64 11640.L_ALT_OP_IGET: /* 0x52 */ 11641/* File: armv5te/alt_stub.S */ 11642/* 11643 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11644 * any interesting requests and then jump to the real instruction 11645 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11646 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11647 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11648 * bail to the real handler if breakFlags==0. 11649 */ 11650 ldrb r3, [rSELF, #offThread_breakFlags] 11651 adrl lr, dvmAsmInstructionStart + (82 * 64) 11652 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11653 cmp r3, #0 11654 bxeq lr @ nothing to do - jump to real handler 11655 EXPORT_PC() 11656 mov r0, rPC @ arg0 11657 mov r1, rFP @ arg1 11658 mov r2, rSELF @ arg2 11659 b dvmCheckBefore @ (dPC,dFP,self) tail call 11660 11661/* ------------------------------ */ 11662 .balign 64 11663.L_ALT_OP_IGET_WIDE: /* 0x53 */ 11664/* File: armv5te/alt_stub.S */ 11665/* 11666 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11667 * any interesting requests and then jump to the real instruction 11668 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11669 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11670 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11671 * bail to the real handler if breakFlags==0. 11672 */ 11673 ldrb r3, [rSELF, #offThread_breakFlags] 11674 adrl lr, dvmAsmInstructionStart + (83 * 64) 11675 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11676 cmp r3, #0 11677 bxeq lr @ nothing to do - jump to real handler 11678 EXPORT_PC() 11679 mov r0, rPC @ arg0 11680 mov r1, rFP @ arg1 11681 mov r2, rSELF @ arg2 11682 b dvmCheckBefore @ (dPC,dFP,self) tail call 11683 11684/* ------------------------------ */ 11685 .balign 64 11686.L_ALT_OP_IGET_OBJECT: /* 0x54 */ 11687/* File: armv5te/alt_stub.S */ 11688/* 11689 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11690 * any interesting requests and then jump to the real instruction 11691 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11692 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11693 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11694 * bail to the real handler if breakFlags==0. 11695 */ 11696 ldrb r3, [rSELF, #offThread_breakFlags] 11697 adrl lr, dvmAsmInstructionStart + (84 * 64) 11698 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11699 cmp r3, #0 11700 bxeq lr @ nothing to do - jump to real handler 11701 EXPORT_PC() 11702 mov r0, rPC @ arg0 11703 mov r1, rFP @ arg1 11704 mov r2, rSELF @ arg2 11705 b dvmCheckBefore @ (dPC,dFP,self) tail call 11706 11707/* ------------------------------ */ 11708 .balign 64 11709.L_ALT_OP_IGET_BOOLEAN: /* 0x55 */ 11710/* File: armv5te/alt_stub.S */ 11711/* 11712 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11713 * any interesting requests and then jump to the real instruction 11714 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11715 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11716 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11717 * bail to the real handler if breakFlags==0. 11718 */ 11719 ldrb r3, [rSELF, #offThread_breakFlags] 11720 adrl lr, dvmAsmInstructionStart + (85 * 64) 11721 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11722 cmp r3, #0 11723 bxeq lr @ nothing to do - jump to real handler 11724 EXPORT_PC() 11725 mov r0, rPC @ arg0 11726 mov r1, rFP @ arg1 11727 mov r2, rSELF @ arg2 11728 b dvmCheckBefore @ (dPC,dFP,self) tail call 11729 11730/* ------------------------------ */ 11731 .balign 64 11732.L_ALT_OP_IGET_BYTE: /* 0x56 */ 11733/* File: armv5te/alt_stub.S */ 11734/* 11735 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11736 * any interesting requests and then jump to the real instruction 11737 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11738 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11739 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11740 * bail to the real handler if breakFlags==0. 11741 */ 11742 ldrb r3, [rSELF, #offThread_breakFlags] 11743 adrl lr, dvmAsmInstructionStart + (86 * 64) 11744 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11745 cmp r3, #0 11746 bxeq lr @ nothing to do - jump to real handler 11747 EXPORT_PC() 11748 mov r0, rPC @ arg0 11749 mov r1, rFP @ arg1 11750 mov r2, rSELF @ arg2 11751 b dvmCheckBefore @ (dPC,dFP,self) tail call 11752 11753/* ------------------------------ */ 11754 .balign 64 11755.L_ALT_OP_IGET_CHAR: /* 0x57 */ 11756/* File: armv5te/alt_stub.S */ 11757/* 11758 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11759 * any interesting requests and then jump to the real instruction 11760 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11761 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11762 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11763 * bail to the real handler if breakFlags==0. 11764 */ 11765 ldrb r3, [rSELF, #offThread_breakFlags] 11766 adrl lr, dvmAsmInstructionStart + (87 * 64) 11767 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11768 cmp r3, #0 11769 bxeq lr @ nothing to do - jump to real handler 11770 EXPORT_PC() 11771 mov r0, rPC @ arg0 11772 mov r1, rFP @ arg1 11773 mov r2, rSELF @ arg2 11774 b dvmCheckBefore @ (dPC,dFP,self) tail call 11775 11776/* ------------------------------ */ 11777 .balign 64 11778.L_ALT_OP_IGET_SHORT: /* 0x58 */ 11779/* File: armv5te/alt_stub.S */ 11780/* 11781 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11782 * any interesting requests and then jump to the real instruction 11783 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11784 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11785 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11786 * bail to the real handler if breakFlags==0. 11787 */ 11788 ldrb r3, [rSELF, #offThread_breakFlags] 11789 adrl lr, dvmAsmInstructionStart + (88 * 64) 11790 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11791 cmp r3, #0 11792 bxeq lr @ nothing to do - jump to real handler 11793 EXPORT_PC() 11794 mov r0, rPC @ arg0 11795 mov r1, rFP @ arg1 11796 mov r2, rSELF @ arg2 11797 b dvmCheckBefore @ (dPC,dFP,self) tail call 11798 11799/* ------------------------------ */ 11800 .balign 64 11801.L_ALT_OP_IPUT: /* 0x59 */ 11802/* File: armv5te/alt_stub.S */ 11803/* 11804 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11805 * any interesting requests and then jump to the real instruction 11806 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11807 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11808 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11809 * bail to the real handler if breakFlags==0. 11810 */ 11811 ldrb r3, [rSELF, #offThread_breakFlags] 11812 adrl lr, dvmAsmInstructionStart + (89 * 64) 11813 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11814 cmp r3, #0 11815 bxeq lr @ nothing to do - jump to real handler 11816 EXPORT_PC() 11817 mov r0, rPC @ arg0 11818 mov r1, rFP @ arg1 11819 mov r2, rSELF @ arg2 11820 b dvmCheckBefore @ (dPC,dFP,self) tail call 11821 11822/* ------------------------------ */ 11823 .balign 64 11824.L_ALT_OP_IPUT_WIDE: /* 0x5a */ 11825/* File: armv5te/alt_stub.S */ 11826/* 11827 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11828 * any interesting requests and then jump to the real instruction 11829 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11830 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11831 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11832 * bail to the real handler if breakFlags==0. 11833 */ 11834 ldrb r3, [rSELF, #offThread_breakFlags] 11835 adrl lr, dvmAsmInstructionStart + (90 * 64) 11836 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11837 cmp r3, #0 11838 bxeq lr @ nothing to do - jump to real handler 11839 EXPORT_PC() 11840 mov r0, rPC @ arg0 11841 mov r1, rFP @ arg1 11842 mov r2, rSELF @ arg2 11843 b dvmCheckBefore @ (dPC,dFP,self) tail call 11844 11845/* ------------------------------ */ 11846 .balign 64 11847.L_ALT_OP_IPUT_OBJECT: /* 0x5b */ 11848/* File: armv5te/alt_stub.S */ 11849/* 11850 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11851 * any interesting requests and then jump to the real instruction 11852 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11853 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11854 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11855 * bail to the real handler if breakFlags==0. 11856 */ 11857 ldrb r3, [rSELF, #offThread_breakFlags] 11858 adrl lr, dvmAsmInstructionStart + (91 * 64) 11859 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11860 cmp r3, #0 11861 bxeq lr @ nothing to do - jump to real handler 11862 EXPORT_PC() 11863 mov r0, rPC @ arg0 11864 mov r1, rFP @ arg1 11865 mov r2, rSELF @ arg2 11866 b dvmCheckBefore @ (dPC,dFP,self) tail call 11867 11868/* ------------------------------ */ 11869 .balign 64 11870.L_ALT_OP_IPUT_BOOLEAN: /* 0x5c */ 11871/* File: armv5te/alt_stub.S */ 11872/* 11873 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11874 * any interesting requests and then jump to the real instruction 11875 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11876 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11877 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11878 * bail to the real handler if breakFlags==0. 11879 */ 11880 ldrb r3, [rSELF, #offThread_breakFlags] 11881 adrl lr, dvmAsmInstructionStart + (92 * 64) 11882 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11883 cmp r3, #0 11884 bxeq lr @ nothing to do - jump to real handler 11885 EXPORT_PC() 11886 mov r0, rPC @ arg0 11887 mov r1, rFP @ arg1 11888 mov r2, rSELF @ arg2 11889 b dvmCheckBefore @ (dPC,dFP,self) tail call 11890 11891/* ------------------------------ */ 11892 .balign 64 11893.L_ALT_OP_IPUT_BYTE: /* 0x5d */ 11894/* File: armv5te/alt_stub.S */ 11895/* 11896 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11897 * any interesting requests and then jump to the real instruction 11898 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11899 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11900 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11901 * bail to the real handler if breakFlags==0. 11902 */ 11903 ldrb r3, [rSELF, #offThread_breakFlags] 11904 adrl lr, dvmAsmInstructionStart + (93 * 64) 11905 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11906 cmp r3, #0 11907 bxeq lr @ nothing to do - jump to real handler 11908 EXPORT_PC() 11909 mov r0, rPC @ arg0 11910 mov r1, rFP @ arg1 11911 mov r2, rSELF @ arg2 11912 b dvmCheckBefore @ (dPC,dFP,self) tail call 11913 11914/* ------------------------------ */ 11915 .balign 64 11916.L_ALT_OP_IPUT_CHAR: /* 0x5e */ 11917/* File: armv5te/alt_stub.S */ 11918/* 11919 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11920 * any interesting requests and then jump to the real instruction 11921 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11922 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11923 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11924 * bail to the real handler if breakFlags==0. 11925 */ 11926 ldrb r3, [rSELF, #offThread_breakFlags] 11927 adrl lr, dvmAsmInstructionStart + (94 * 64) 11928 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11929 cmp r3, #0 11930 bxeq lr @ nothing to do - jump to real handler 11931 EXPORT_PC() 11932 mov r0, rPC @ arg0 11933 mov r1, rFP @ arg1 11934 mov r2, rSELF @ arg2 11935 b dvmCheckBefore @ (dPC,dFP,self) tail call 11936 11937/* ------------------------------ */ 11938 .balign 64 11939.L_ALT_OP_IPUT_SHORT: /* 0x5f */ 11940/* File: armv5te/alt_stub.S */ 11941/* 11942 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11943 * any interesting requests and then jump to the real instruction 11944 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11945 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11946 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11947 * bail to the real handler if breakFlags==0. 11948 */ 11949 ldrb r3, [rSELF, #offThread_breakFlags] 11950 adrl lr, dvmAsmInstructionStart + (95 * 64) 11951 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11952 cmp r3, #0 11953 bxeq lr @ nothing to do - jump to real handler 11954 EXPORT_PC() 11955 mov r0, rPC @ arg0 11956 mov r1, rFP @ arg1 11957 mov r2, rSELF @ arg2 11958 b dvmCheckBefore @ (dPC,dFP,self) tail call 11959 11960/* ------------------------------ */ 11961 .balign 64 11962.L_ALT_OP_SGET: /* 0x60 */ 11963/* File: armv5te/alt_stub.S */ 11964/* 11965 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11966 * any interesting requests and then jump to the real instruction 11967 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11968 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11969 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11970 * bail to the real handler if breakFlags==0. 11971 */ 11972 ldrb r3, [rSELF, #offThread_breakFlags] 11973 adrl lr, dvmAsmInstructionStart + (96 * 64) 11974 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11975 cmp r3, #0 11976 bxeq lr @ nothing to do - jump to real handler 11977 EXPORT_PC() 11978 mov r0, rPC @ arg0 11979 mov r1, rFP @ arg1 11980 mov r2, rSELF @ arg2 11981 b dvmCheckBefore @ (dPC,dFP,self) tail call 11982 11983/* ------------------------------ */ 11984 .balign 64 11985.L_ALT_OP_SGET_WIDE: /* 0x61 */ 11986/* File: armv5te/alt_stub.S */ 11987/* 11988 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 11989 * any interesting requests and then jump to the real instruction 11990 * handler. Note that the call to dvmCheckBefore is done as a tail call. 11991 * rIBASE updates won't be seen until a refresh, and we can tell we have a 11992 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 11993 * bail to the real handler if breakFlags==0. 11994 */ 11995 ldrb r3, [rSELF, #offThread_breakFlags] 11996 adrl lr, dvmAsmInstructionStart + (97 * 64) 11997 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 11998 cmp r3, #0 11999 bxeq lr @ nothing to do - jump to real handler 12000 EXPORT_PC() 12001 mov r0, rPC @ arg0 12002 mov r1, rFP @ arg1 12003 mov r2, rSELF @ arg2 12004 b dvmCheckBefore @ (dPC,dFP,self) tail call 12005 12006/* ------------------------------ */ 12007 .balign 64 12008.L_ALT_OP_SGET_OBJECT: /* 0x62 */ 12009/* File: armv5te/alt_stub.S */ 12010/* 12011 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12012 * any interesting requests and then jump to the real instruction 12013 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12014 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12015 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12016 * bail to the real handler if breakFlags==0. 12017 */ 12018 ldrb r3, [rSELF, #offThread_breakFlags] 12019 adrl lr, dvmAsmInstructionStart + (98 * 64) 12020 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12021 cmp r3, #0 12022 bxeq lr @ nothing to do - jump to real handler 12023 EXPORT_PC() 12024 mov r0, rPC @ arg0 12025 mov r1, rFP @ arg1 12026 mov r2, rSELF @ arg2 12027 b dvmCheckBefore @ (dPC,dFP,self) tail call 12028 12029/* ------------------------------ */ 12030 .balign 64 12031.L_ALT_OP_SGET_BOOLEAN: /* 0x63 */ 12032/* File: armv5te/alt_stub.S */ 12033/* 12034 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12035 * any interesting requests and then jump to the real instruction 12036 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12037 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12038 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12039 * bail to the real handler if breakFlags==0. 12040 */ 12041 ldrb r3, [rSELF, #offThread_breakFlags] 12042 adrl lr, dvmAsmInstructionStart + (99 * 64) 12043 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12044 cmp r3, #0 12045 bxeq lr @ nothing to do - jump to real handler 12046 EXPORT_PC() 12047 mov r0, rPC @ arg0 12048 mov r1, rFP @ arg1 12049 mov r2, rSELF @ arg2 12050 b dvmCheckBefore @ (dPC,dFP,self) tail call 12051 12052/* ------------------------------ */ 12053 .balign 64 12054.L_ALT_OP_SGET_BYTE: /* 0x64 */ 12055/* File: armv5te/alt_stub.S */ 12056/* 12057 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12058 * any interesting requests and then jump to the real instruction 12059 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12060 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12061 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12062 * bail to the real handler if breakFlags==0. 12063 */ 12064 ldrb r3, [rSELF, #offThread_breakFlags] 12065 adrl lr, dvmAsmInstructionStart + (100 * 64) 12066 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12067 cmp r3, #0 12068 bxeq lr @ nothing to do - jump to real handler 12069 EXPORT_PC() 12070 mov r0, rPC @ arg0 12071 mov r1, rFP @ arg1 12072 mov r2, rSELF @ arg2 12073 b dvmCheckBefore @ (dPC,dFP,self) tail call 12074 12075/* ------------------------------ */ 12076 .balign 64 12077.L_ALT_OP_SGET_CHAR: /* 0x65 */ 12078/* File: armv5te/alt_stub.S */ 12079/* 12080 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12081 * any interesting requests and then jump to the real instruction 12082 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12083 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12084 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12085 * bail to the real handler if breakFlags==0. 12086 */ 12087 ldrb r3, [rSELF, #offThread_breakFlags] 12088 adrl lr, dvmAsmInstructionStart + (101 * 64) 12089 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12090 cmp r3, #0 12091 bxeq lr @ nothing to do - jump to real handler 12092 EXPORT_PC() 12093 mov r0, rPC @ arg0 12094 mov r1, rFP @ arg1 12095 mov r2, rSELF @ arg2 12096 b dvmCheckBefore @ (dPC,dFP,self) tail call 12097 12098/* ------------------------------ */ 12099 .balign 64 12100.L_ALT_OP_SGET_SHORT: /* 0x66 */ 12101/* File: armv5te/alt_stub.S */ 12102/* 12103 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12104 * any interesting requests and then jump to the real instruction 12105 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12106 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12107 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12108 * bail to the real handler if breakFlags==0. 12109 */ 12110 ldrb r3, [rSELF, #offThread_breakFlags] 12111 adrl lr, dvmAsmInstructionStart + (102 * 64) 12112 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12113 cmp r3, #0 12114 bxeq lr @ nothing to do - jump to real handler 12115 EXPORT_PC() 12116 mov r0, rPC @ arg0 12117 mov r1, rFP @ arg1 12118 mov r2, rSELF @ arg2 12119 b dvmCheckBefore @ (dPC,dFP,self) tail call 12120 12121/* ------------------------------ */ 12122 .balign 64 12123.L_ALT_OP_SPUT: /* 0x67 */ 12124/* File: armv5te/alt_stub.S */ 12125/* 12126 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12127 * any interesting requests and then jump to the real instruction 12128 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12129 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12130 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12131 * bail to the real handler if breakFlags==0. 12132 */ 12133 ldrb r3, [rSELF, #offThread_breakFlags] 12134 adrl lr, dvmAsmInstructionStart + (103 * 64) 12135 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12136 cmp r3, #0 12137 bxeq lr @ nothing to do - jump to real handler 12138 EXPORT_PC() 12139 mov r0, rPC @ arg0 12140 mov r1, rFP @ arg1 12141 mov r2, rSELF @ arg2 12142 b dvmCheckBefore @ (dPC,dFP,self) tail call 12143 12144/* ------------------------------ */ 12145 .balign 64 12146.L_ALT_OP_SPUT_WIDE: /* 0x68 */ 12147/* File: armv5te/alt_stub.S */ 12148/* 12149 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12150 * any interesting requests and then jump to the real instruction 12151 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12152 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12153 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12154 * bail to the real handler if breakFlags==0. 12155 */ 12156 ldrb r3, [rSELF, #offThread_breakFlags] 12157 adrl lr, dvmAsmInstructionStart + (104 * 64) 12158 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12159 cmp r3, #0 12160 bxeq lr @ nothing to do - jump to real handler 12161 EXPORT_PC() 12162 mov r0, rPC @ arg0 12163 mov r1, rFP @ arg1 12164 mov r2, rSELF @ arg2 12165 b dvmCheckBefore @ (dPC,dFP,self) tail call 12166 12167/* ------------------------------ */ 12168 .balign 64 12169.L_ALT_OP_SPUT_OBJECT: /* 0x69 */ 12170/* File: armv5te/alt_stub.S */ 12171/* 12172 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12173 * any interesting requests and then jump to the real instruction 12174 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12175 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12176 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12177 * bail to the real handler if breakFlags==0. 12178 */ 12179 ldrb r3, [rSELF, #offThread_breakFlags] 12180 adrl lr, dvmAsmInstructionStart + (105 * 64) 12181 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12182 cmp r3, #0 12183 bxeq lr @ nothing to do - jump to real handler 12184 EXPORT_PC() 12185 mov r0, rPC @ arg0 12186 mov r1, rFP @ arg1 12187 mov r2, rSELF @ arg2 12188 b dvmCheckBefore @ (dPC,dFP,self) tail call 12189 12190/* ------------------------------ */ 12191 .balign 64 12192.L_ALT_OP_SPUT_BOOLEAN: /* 0x6a */ 12193/* File: armv5te/alt_stub.S */ 12194/* 12195 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12196 * any interesting requests and then jump to the real instruction 12197 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12198 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12199 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12200 * bail to the real handler if breakFlags==0. 12201 */ 12202 ldrb r3, [rSELF, #offThread_breakFlags] 12203 adrl lr, dvmAsmInstructionStart + (106 * 64) 12204 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12205 cmp r3, #0 12206 bxeq lr @ nothing to do - jump to real handler 12207 EXPORT_PC() 12208 mov r0, rPC @ arg0 12209 mov r1, rFP @ arg1 12210 mov r2, rSELF @ arg2 12211 b dvmCheckBefore @ (dPC,dFP,self) tail call 12212 12213/* ------------------------------ */ 12214 .balign 64 12215.L_ALT_OP_SPUT_BYTE: /* 0x6b */ 12216/* File: armv5te/alt_stub.S */ 12217/* 12218 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12219 * any interesting requests and then jump to the real instruction 12220 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12221 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12222 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12223 * bail to the real handler if breakFlags==0. 12224 */ 12225 ldrb r3, [rSELF, #offThread_breakFlags] 12226 adrl lr, dvmAsmInstructionStart + (107 * 64) 12227 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12228 cmp r3, #0 12229 bxeq lr @ nothing to do - jump to real handler 12230 EXPORT_PC() 12231 mov r0, rPC @ arg0 12232 mov r1, rFP @ arg1 12233 mov r2, rSELF @ arg2 12234 b dvmCheckBefore @ (dPC,dFP,self) tail call 12235 12236/* ------------------------------ */ 12237 .balign 64 12238.L_ALT_OP_SPUT_CHAR: /* 0x6c */ 12239/* File: armv5te/alt_stub.S */ 12240/* 12241 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12242 * any interesting requests and then jump to the real instruction 12243 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12244 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12245 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12246 * bail to the real handler if breakFlags==0. 12247 */ 12248 ldrb r3, [rSELF, #offThread_breakFlags] 12249 adrl lr, dvmAsmInstructionStart + (108 * 64) 12250 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12251 cmp r3, #0 12252 bxeq lr @ nothing to do - jump to real handler 12253 EXPORT_PC() 12254 mov r0, rPC @ arg0 12255 mov r1, rFP @ arg1 12256 mov r2, rSELF @ arg2 12257 b dvmCheckBefore @ (dPC,dFP,self) tail call 12258 12259/* ------------------------------ */ 12260 .balign 64 12261.L_ALT_OP_SPUT_SHORT: /* 0x6d */ 12262/* File: armv5te/alt_stub.S */ 12263/* 12264 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12265 * any interesting requests and then jump to the real instruction 12266 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12267 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12268 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12269 * bail to the real handler if breakFlags==0. 12270 */ 12271 ldrb r3, [rSELF, #offThread_breakFlags] 12272 adrl lr, dvmAsmInstructionStart + (109 * 64) 12273 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12274 cmp r3, #0 12275 bxeq lr @ nothing to do - jump to real handler 12276 EXPORT_PC() 12277 mov r0, rPC @ arg0 12278 mov r1, rFP @ arg1 12279 mov r2, rSELF @ arg2 12280 b dvmCheckBefore @ (dPC,dFP,self) tail call 12281 12282/* ------------------------------ */ 12283 .balign 64 12284.L_ALT_OP_INVOKE_VIRTUAL: /* 0x6e */ 12285/* File: armv5te/alt_stub.S */ 12286/* 12287 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12288 * any interesting requests and then jump to the real instruction 12289 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12290 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12291 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12292 * bail to the real handler if breakFlags==0. 12293 */ 12294 ldrb r3, [rSELF, #offThread_breakFlags] 12295 adrl lr, dvmAsmInstructionStart + (110 * 64) 12296 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12297 cmp r3, #0 12298 bxeq lr @ nothing to do - jump to real handler 12299 EXPORT_PC() 12300 mov r0, rPC @ arg0 12301 mov r1, rFP @ arg1 12302 mov r2, rSELF @ arg2 12303 b dvmCheckBefore @ (dPC,dFP,self) tail call 12304 12305/* ------------------------------ */ 12306 .balign 64 12307.L_ALT_OP_INVOKE_SUPER: /* 0x6f */ 12308/* File: armv5te/alt_stub.S */ 12309/* 12310 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12311 * any interesting requests and then jump to the real instruction 12312 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12313 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12314 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12315 * bail to the real handler if breakFlags==0. 12316 */ 12317 ldrb r3, [rSELF, #offThread_breakFlags] 12318 adrl lr, dvmAsmInstructionStart + (111 * 64) 12319 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12320 cmp r3, #0 12321 bxeq lr @ nothing to do - jump to real handler 12322 EXPORT_PC() 12323 mov r0, rPC @ arg0 12324 mov r1, rFP @ arg1 12325 mov r2, rSELF @ arg2 12326 b dvmCheckBefore @ (dPC,dFP,self) tail call 12327 12328/* ------------------------------ */ 12329 .balign 64 12330.L_ALT_OP_INVOKE_DIRECT: /* 0x70 */ 12331/* File: armv5te/alt_stub.S */ 12332/* 12333 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12334 * any interesting requests and then jump to the real instruction 12335 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12336 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12337 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12338 * bail to the real handler if breakFlags==0. 12339 */ 12340 ldrb r3, [rSELF, #offThread_breakFlags] 12341 adrl lr, dvmAsmInstructionStart + (112 * 64) 12342 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12343 cmp r3, #0 12344 bxeq lr @ nothing to do - jump to real handler 12345 EXPORT_PC() 12346 mov r0, rPC @ arg0 12347 mov r1, rFP @ arg1 12348 mov r2, rSELF @ arg2 12349 b dvmCheckBefore @ (dPC,dFP,self) tail call 12350 12351/* ------------------------------ */ 12352 .balign 64 12353.L_ALT_OP_INVOKE_STATIC: /* 0x71 */ 12354/* File: armv5te/alt_stub.S */ 12355/* 12356 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12357 * any interesting requests and then jump to the real instruction 12358 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12359 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12360 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12361 * bail to the real handler if breakFlags==0. 12362 */ 12363 ldrb r3, [rSELF, #offThread_breakFlags] 12364 adrl lr, dvmAsmInstructionStart + (113 * 64) 12365 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12366 cmp r3, #0 12367 bxeq lr @ nothing to do - jump to real handler 12368 EXPORT_PC() 12369 mov r0, rPC @ arg0 12370 mov r1, rFP @ arg1 12371 mov r2, rSELF @ arg2 12372 b dvmCheckBefore @ (dPC,dFP,self) tail call 12373 12374/* ------------------------------ */ 12375 .balign 64 12376.L_ALT_OP_INVOKE_INTERFACE: /* 0x72 */ 12377/* File: armv5te/alt_stub.S */ 12378/* 12379 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12380 * any interesting requests and then jump to the real instruction 12381 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12382 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12383 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12384 * bail to the real handler if breakFlags==0. 12385 */ 12386 ldrb r3, [rSELF, #offThread_breakFlags] 12387 adrl lr, dvmAsmInstructionStart + (114 * 64) 12388 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12389 cmp r3, #0 12390 bxeq lr @ nothing to do - jump to real handler 12391 EXPORT_PC() 12392 mov r0, rPC @ arg0 12393 mov r1, rFP @ arg1 12394 mov r2, rSELF @ arg2 12395 b dvmCheckBefore @ (dPC,dFP,self) tail call 12396 12397/* ------------------------------ */ 12398 .balign 64 12399.L_ALT_OP_UNUSED_73: /* 0x73 */ 12400/* File: armv5te/alt_stub.S */ 12401/* 12402 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12403 * any interesting requests and then jump to the real instruction 12404 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12405 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12406 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12407 * bail to the real handler if breakFlags==0. 12408 */ 12409 ldrb r3, [rSELF, #offThread_breakFlags] 12410 adrl lr, dvmAsmInstructionStart + (115 * 64) 12411 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12412 cmp r3, #0 12413 bxeq lr @ nothing to do - jump to real handler 12414 EXPORT_PC() 12415 mov r0, rPC @ arg0 12416 mov r1, rFP @ arg1 12417 mov r2, rSELF @ arg2 12418 b dvmCheckBefore @ (dPC,dFP,self) tail call 12419 12420/* ------------------------------ */ 12421 .balign 64 12422.L_ALT_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 12423/* File: armv5te/alt_stub.S */ 12424/* 12425 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12426 * any interesting requests and then jump to the real instruction 12427 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12428 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12429 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12430 * bail to the real handler if breakFlags==0. 12431 */ 12432 ldrb r3, [rSELF, #offThread_breakFlags] 12433 adrl lr, dvmAsmInstructionStart + (116 * 64) 12434 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12435 cmp r3, #0 12436 bxeq lr @ nothing to do - jump to real handler 12437 EXPORT_PC() 12438 mov r0, rPC @ arg0 12439 mov r1, rFP @ arg1 12440 mov r2, rSELF @ arg2 12441 b dvmCheckBefore @ (dPC,dFP,self) tail call 12442 12443/* ------------------------------ */ 12444 .balign 64 12445.L_ALT_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 12446/* File: armv5te/alt_stub.S */ 12447/* 12448 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12449 * any interesting requests and then jump to the real instruction 12450 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12451 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12452 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12453 * bail to the real handler if breakFlags==0. 12454 */ 12455 ldrb r3, [rSELF, #offThread_breakFlags] 12456 adrl lr, dvmAsmInstructionStart + (117 * 64) 12457 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12458 cmp r3, #0 12459 bxeq lr @ nothing to do - jump to real handler 12460 EXPORT_PC() 12461 mov r0, rPC @ arg0 12462 mov r1, rFP @ arg1 12463 mov r2, rSELF @ arg2 12464 b dvmCheckBefore @ (dPC,dFP,self) tail call 12465 12466/* ------------------------------ */ 12467 .balign 64 12468.L_ALT_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 12469/* File: armv5te/alt_stub.S */ 12470/* 12471 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12472 * any interesting requests and then jump to the real instruction 12473 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12474 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12475 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12476 * bail to the real handler if breakFlags==0. 12477 */ 12478 ldrb r3, [rSELF, #offThread_breakFlags] 12479 adrl lr, dvmAsmInstructionStart + (118 * 64) 12480 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12481 cmp r3, #0 12482 bxeq lr @ nothing to do - jump to real handler 12483 EXPORT_PC() 12484 mov r0, rPC @ arg0 12485 mov r1, rFP @ arg1 12486 mov r2, rSELF @ arg2 12487 b dvmCheckBefore @ (dPC,dFP,self) tail call 12488 12489/* ------------------------------ */ 12490 .balign 64 12491.L_ALT_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 12492/* File: armv5te/alt_stub.S */ 12493/* 12494 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12495 * any interesting requests and then jump to the real instruction 12496 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12497 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12498 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12499 * bail to the real handler if breakFlags==0. 12500 */ 12501 ldrb r3, [rSELF, #offThread_breakFlags] 12502 adrl lr, dvmAsmInstructionStart + (119 * 64) 12503 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12504 cmp r3, #0 12505 bxeq lr @ nothing to do - jump to real handler 12506 EXPORT_PC() 12507 mov r0, rPC @ arg0 12508 mov r1, rFP @ arg1 12509 mov r2, rSELF @ arg2 12510 b dvmCheckBefore @ (dPC,dFP,self) tail call 12511 12512/* ------------------------------ */ 12513 .balign 64 12514.L_ALT_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 12515/* File: armv5te/alt_stub.S */ 12516/* 12517 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12518 * any interesting requests and then jump to the real instruction 12519 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12520 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12521 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12522 * bail to the real handler if breakFlags==0. 12523 */ 12524 ldrb r3, [rSELF, #offThread_breakFlags] 12525 adrl lr, dvmAsmInstructionStart + (120 * 64) 12526 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12527 cmp r3, #0 12528 bxeq lr @ nothing to do - jump to real handler 12529 EXPORT_PC() 12530 mov r0, rPC @ arg0 12531 mov r1, rFP @ arg1 12532 mov r2, rSELF @ arg2 12533 b dvmCheckBefore @ (dPC,dFP,self) tail call 12534 12535/* ------------------------------ */ 12536 .balign 64 12537.L_ALT_OP_UNUSED_79: /* 0x79 */ 12538/* File: armv5te/alt_stub.S */ 12539/* 12540 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12541 * any interesting requests and then jump to the real instruction 12542 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12543 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12544 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12545 * bail to the real handler if breakFlags==0. 12546 */ 12547 ldrb r3, [rSELF, #offThread_breakFlags] 12548 adrl lr, dvmAsmInstructionStart + (121 * 64) 12549 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12550 cmp r3, #0 12551 bxeq lr @ nothing to do - jump to real handler 12552 EXPORT_PC() 12553 mov r0, rPC @ arg0 12554 mov r1, rFP @ arg1 12555 mov r2, rSELF @ arg2 12556 b dvmCheckBefore @ (dPC,dFP,self) tail call 12557 12558/* ------------------------------ */ 12559 .balign 64 12560.L_ALT_OP_UNUSED_7A: /* 0x7a */ 12561/* File: armv5te/alt_stub.S */ 12562/* 12563 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12564 * any interesting requests and then jump to the real instruction 12565 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12566 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12567 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12568 * bail to the real handler if breakFlags==0. 12569 */ 12570 ldrb r3, [rSELF, #offThread_breakFlags] 12571 adrl lr, dvmAsmInstructionStart + (122 * 64) 12572 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12573 cmp r3, #0 12574 bxeq lr @ nothing to do - jump to real handler 12575 EXPORT_PC() 12576 mov r0, rPC @ arg0 12577 mov r1, rFP @ arg1 12578 mov r2, rSELF @ arg2 12579 b dvmCheckBefore @ (dPC,dFP,self) tail call 12580 12581/* ------------------------------ */ 12582 .balign 64 12583.L_ALT_OP_NEG_INT: /* 0x7b */ 12584/* File: armv5te/alt_stub.S */ 12585/* 12586 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12587 * any interesting requests and then jump to the real instruction 12588 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12589 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12590 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12591 * bail to the real handler if breakFlags==0. 12592 */ 12593 ldrb r3, [rSELF, #offThread_breakFlags] 12594 adrl lr, dvmAsmInstructionStart + (123 * 64) 12595 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12596 cmp r3, #0 12597 bxeq lr @ nothing to do - jump to real handler 12598 EXPORT_PC() 12599 mov r0, rPC @ arg0 12600 mov r1, rFP @ arg1 12601 mov r2, rSELF @ arg2 12602 b dvmCheckBefore @ (dPC,dFP,self) tail call 12603 12604/* ------------------------------ */ 12605 .balign 64 12606.L_ALT_OP_NOT_INT: /* 0x7c */ 12607/* File: armv5te/alt_stub.S */ 12608/* 12609 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12610 * any interesting requests and then jump to the real instruction 12611 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12612 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12613 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12614 * bail to the real handler if breakFlags==0. 12615 */ 12616 ldrb r3, [rSELF, #offThread_breakFlags] 12617 adrl lr, dvmAsmInstructionStart + (124 * 64) 12618 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12619 cmp r3, #0 12620 bxeq lr @ nothing to do - jump to real handler 12621 EXPORT_PC() 12622 mov r0, rPC @ arg0 12623 mov r1, rFP @ arg1 12624 mov r2, rSELF @ arg2 12625 b dvmCheckBefore @ (dPC,dFP,self) tail call 12626 12627/* ------------------------------ */ 12628 .balign 64 12629.L_ALT_OP_NEG_LONG: /* 0x7d */ 12630/* File: armv5te/alt_stub.S */ 12631/* 12632 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12633 * any interesting requests and then jump to the real instruction 12634 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12635 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12636 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12637 * bail to the real handler if breakFlags==0. 12638 */ 12639 ldrb r3, [rSELF, #offThread_breakFlags] 12640 adrl lr, dvmAsmInstructionStart + (125 * 64) 12641 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12642 cmp r3, #0 12643 bxeq lr @ nothing to do - jump to real handler 12644 EXPORT_PC() 12645 mov r0, rPC @ arg0 12646 mov r1, rFP @ arg1 12647 mov r2, rSELF @ arg2 12648 b dvmCheckBefore @ (dPC,dFP,self) tail call 12649 12650/* ------------------------------ */ 12651 .balign 64 12652.L_ALT_OP_NOT_LONG: /* 0x7e */ 12653/* File: armv5te/alt_stub.S */ 12654/* 12655 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12656 * any interesting requests and then jump to the real instruction 12657 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12658 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12659 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12660 * bail to the real handler if breakFlags==0. 12661 */ 12662 ldrb r3, [rSELF, #offThread_breakFlags] 12663 adrl lr, dvmAsmInstructionStart + (126 * 64) 12664 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12665 cmp r3, #0 12666 bxeq lr @ nothing to do - jump to real handler 12667 EXPORT_PC() 12668 mov r0, rPC @ arg0 12669 mov r1, rFP @ arg1 12670 mov r2, rSELF @ arg2 12671 b dvmCheckBefore @ (dPC,dFP,self) tail call 12672 12673/* ------------------------------ */ 12674 .balign 64 12675.L_ALT_OP_NEG_FLOAT: /* 0x7f */ 12676/* File: armv5te/alt_stub.S */ 12677/* 12678 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12679 * any interesting requests and then jump to the real instruction 12680 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12681 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12682 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12683 * bail to the real handler if breakFlags==0. 12684 */ 12685 ldrb r3, [rSELF, #offThread_breakFlags] 12686 adrl lr, dvmAsmInstructionStart + (127 * 64) 12687 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12688 cmp r3, #0 12689 bxeq lr @ nothing to do - jump to real handler 12690 EXPORT_PC() 12691 mov r0, rPC @ arg0 12692 mov r1, rFP @ arg1 12693 mov r2, rSELF @ arg2 12694 b dvmCheckBefore @ (dPC,dFP,self) tail call 12695 12696/* ------------------------------ */ 12697 .balign 64 12698.L_ALT_OP_NEG_DOUBLE: /* 0x80 */ 12699/* File: armv5te/alt_stub.S */ 12700/* 12701 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12702 * any interesting requests and then jump to the real instruction 12703 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12704 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12705 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12706 * bail to the real handler if breakFlags==0. 12707 */ 12708 ldrb r3, [rSELF, #offThread_breakFlags] 12709 adrl lr, dvmAsmInstructionStart + (128 * 64) 12710 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12711 cmp r3, #0 12712 bxeq lr @ nothing to do - jump to real handler 12713 EXPORT_PC() 12714 mov r0, rPC @ arg0 12715 mov r1, rFP @ arg1 12716 mov r2, rSELF @ arg2 12717 b dvmCheckBefore @ (dPC,dFP,self) tail call 12718 12719/* ------------------------------ */ 12720 .balign 64 12721.L_ALT_OP_INT_TO_LONG: /* 0x81 */ 12722/* File: armv5te/alt_stub.S */ 12723/* 12724 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12725 * any interesting requests and then jump to the real instruction 12726 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12727 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12728 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12729 * bail to the real handler if breakFlags==0. 12730 */ 12731 ldrb r3, [rSELF, #offThread_breakFlags] 12732 adrl lr, dvmAsmInstructionStart + (129 * 64) 12733 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12734 cmp r3, #0 12735 bxeq lr @ nothing to do - jump to real handler 12736 EXPORT_PC() 12737 mov r0, rPC @ arg0 12738 mov r1, rFP @ arg1 12739 mov r2, rSELF @ arg2 12740 b dvmCheckBefore @ (dPC,dFP,self) tail call 12741 12742/* ------------------------------ */ 12743 .balign 64 12744.L_ALT_OP_INT_TO_FLOAT: /* 0x82 */ 12745/* File: armv5te/alt_stub.S */ 12746/* 12747 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12748 * any interesting requests and then jump to the real instruction 12749 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12750 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12751 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12752 * bail to the real handler if breakFlags==0. 12753 */ 12754 ldrb r3, [rSELF, #offThread_breakFlags] 12755 adrl lr, dvmAsmInstructionStart + (130 * 64) 12756 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12757 cmp r3, #0 12758 bxeq lr @ nothing to do - jump to real handler 12759 EXPORT_PC() 12760 mov r0, rPC @ arg0 12761 mov r1, rFP @ arg1 12762 mov r2, rSELF @ arg2 12763 b dvmCheckBefore @ (dPC,dFP,self) tail call 12764 12765/* ------------------------------ */ 12766 .balign 64 12767.L_ALT_OP_INT_TO_DOUBLE: /* 0x83 */ 12768/* File: armv5te/alt_stub.S */ 12769/* 12770 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12771 * any interesting requests and then jump to the real instruction 12772 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12773 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12774 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12775 * bail to the real handler if breakFlags==0. 12776 */ 12777 ldrb r3, [rSELF, #offThread_breakFlags] 12778 adrl lr, dvmAsmInstructionStart + (131 * 64) 12779 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12780 cmp r3, #0 12781 bxeq lr @ nothing to do - jump to real handler 12782 EXPORT_PC() 12783 mov r0, rPC @ arg0 12784 mov r1, rFP @ arg1 12785 mov r2, rSELF @ arg2 12786 b dvmCheckBefore @ (dPC,dFP,self) tail call 12787 12788/* ------------------------------ */ 12789 .balign 64 12790.L_ALT_OP_LONG_TO_INT: /* 0x84 */ 12791/* File: armv5te/alt_stub.S */ 12792/* 12793 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12794 * any interesting requests and then jump to the real instruction 12795 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12796 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12797 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12798 * bail to the real handler if breakFlags==0. 12799 */ 12800 ldrb r3, [rSELF, #offThread_breakFlags] 12801 adrl lr, dvmAsmInstructionStart + (132 * 64) 12802 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12803 cmp r3, #0 12804 bxeq lr @ nothing to do - jump to real handler 12805 EXPORT_PC() 12806 mov r0, rPC @ arg0 12807 mov r1, rFP @ arg1 12808 mov r2, rSELF @ arg2 12809 b dvmCheckBefore @ (dPC,dFP,self) tail call 12810 12811/* ------------------------------ */ 12812 .balign 64 12813.L_ALT_OP_LONG_TO_FLOAT: /* 0x85 */ 12814/* File: armv5te/alt_stub.S */ 12815/* 12816 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12817 * any interesting requests and then jump to the real instruction 12818 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12819 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12820 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12821 * bail to the real handler if breakFlags==0. 12822 */ 12823 ldrb r3, [rSELF, #offThread_breakFlags] 12824 adrl lr, dvmAsmInstructionStart + (133 * 64) 12825 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12826 cmp r3, #0 12827 bxeq lr @ nothing to do - jump to real handler 12828 EXPORT_PC() 12829 mov r0, rPC @ arg0 12830 mov r1, rFP @ arg1 12831 mov r2, rSELF @ arg2 12832 b dvmCheckBefore @ (dPC,dFP,self) tail call 12833 12834/* ------------------------------ */ 12835 .balign 64 12836.L_ALT_OP_LONG_TO_DOUBLE: /* 0x86 */ 12837/* File: armv5te/alt_stub.S */ 12838/* 12839 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12840 * any interesting requests and then jump to the real instruction 12841 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12842 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12843 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12844 * bail to the real handler if breakFlags==0. 12845 */ 12846 ldrb r3, [rSELF, #offThread_breakFlags] 12847 adrl lr, dvmAsmInstructionStart + (134 * 64) 12848 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12849 cmp r3, #0 12850 bxeq lr @ nothing to do - jump to real handler 12851 EXPORT_PC() 12852 mov r0, rPC @ arg0 12853 mov r1, rFP @ arg1 12854 mov r2, rSELF @ arg2 12855 b dvmCheckBefore @ (dPC,dFP,self) tail call 12856 12857/* ------------------------------ */ 12858 .balign 64 12859.L_ALT_OP_FLOAT_TO_INT: /* 0x87 */ 12860/* File: armv5te/alt_stub.S */ 12861/* 12862 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12863 * any interesting requests and then jump to the real instruction 12864 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12865 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12866 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12867 * bail to the real handler if breakFlags==0. 12868 */ 12869 ldrb r3, [rSELF, #offThread_breakFlags] 12870 adrl lr, dvmAsmInstructionStart + (135 * 64) 12871 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12872 cmp r3, #0 12873 bxeq lr @ nothing to do - jump to real handler 12874 EXPORT_PC() 12875 mov r0, rPC @ arg0 12876 mov r1, rFP @ arg1 12877 mov r2, rSELF @ arg2 12878 b dvmCheckBefore @ (dPC,dFP,self) tail call 12879 12880/* ------------------------------ */ 12881 .balign 64 12882.L_ALT_OP_FLOAT_TO_LONG: /* 0x88 */ 12883/* File: armv5te/alt_stub.S */ 12884/* 12885 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12886 * any interesting requests and then jump to the real instruction 12887 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12888 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12889 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12890 * bail to the real handler if breakFlags==0. 12891 */ 12892 ldrb r3, [rSELF, #offThread_breakFlags] 12893 adrl lr, dvmAsmInstructionStart + (136 * 64) 12894 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12895 cmp r3, #0 12896 bxeq lr @ nothing to do - jump to real handler 12897 EXPORT_PC() 12898 mov r0, rPC @ arg0 12899 mov r1, rFP @ arg1 12900 mov r2, rSELF @ arg2 12901 b dvmCheckBefore @ (dPC,dFP,self) tail call 12902 12903/* ------------------------------ */ 12904 .balign 64 12905.L_ALT_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 12906/* File: armv5te/alt_stub.S */ 12907/* 12908 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12909 * any interesting requests and then jump to the real instruction 12910 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12911 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12912 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12913 * bail to the real handler if breakFlags==0. 12914 */ 12915 ldrb r3, [rSELF, #offThread_breakFlags] 12916 adrl lr, dvmAsmInstructionStart + (137 * 64) 12917 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12918 cmp r3, #0 12919 bxeq lr @ nothing to do - jump to real handler 12920 EXPORT_PC() 12921 mov r0, rPC @ arg0 12922 mov r1, rFP @ arg1 12923 mov r2, rSELF @ arg2 12924 b dvmCheckBefore @ (dPC,dFP,self) tail call 12925 12926/* ------------------------------ */ 12927 .balign 64 12928.L_ALT_OP_DOUBLE_TO_INT: /* 0x8a */ 12929/* File: armv5te/alt_stub.S */ 12930/* 12931 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12932 * any interesting requests and then jump to the real instruction 12933 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12934 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12935 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12936 * bail to the real handler if breakFlags==0. 12937 */ 12938 ldrb r3, [rSELF, #offThread_breakFlags] 12939 adrl lr, dvmAsmInstructionStart + (138 * 64) 12940 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12941 cmp r3, #0 12942 bxeq lr @ nothing to do - jump to real handler 12943 EXPORT_PC() 12944 mov r0, rPC @ arg0 12945 mov r1, rFP @ arg1 12946 mov r2, rSELF @ arg2 12947 b dvmCheckBefore @ (dPC,dFP,self) tail call 12948 12949/* ------------------------------ */ 12950 .balign 64 12951.L_ALT_OP_DOUBLE_TO_LONG: /* 0x8b */ 12952/* File: armv5te/alt_stub.S */ 12953/* 12954 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12955 * any interesting requests and then jump to the real instruction 12956 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12957 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12958 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12959 * bail to the real handler if breakFlags==0. 12960 */ 12961 ldrb r3, [rSELF, #offThread_breakFlags] 12962 adrl lr, dvmAsmInstructionStart + (139 * 64) 12963 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12964 cmp r3, #0 12965 bxeq lr @ nothing to do - jump to real handler 12966 EXPORT_PC() 12967 mov r0, rPC @ arg0 12968 mov r1, rFP @ arg1 12969 mov r2, rSELF @ arg2 12970 b dvmCheckBefore @ (dPC,dFP,self) tail call 12971 12972/* ------------------------------ */ 12973 .balign 64 12974.L_ALT_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 12975/* File: armv5te/alt_stub.S */ 12976/* 12977 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 12978 * any interesting requests and then jump to the real instruction 12979 * handler. Note that the call to dvmCheckBefore is done as a tail call. 12980 * rIBASE updates won't be seen until a refresh, and we can tell we have a 12981 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 12982 * bail to the real handler if breakFlags==0. 12983 */ 12984 ldrb r3, [rSELF, #offThread_breakFlags] 12985 adrl lr, dvmAsmInstructionStart + (140 * 64) 12986 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 12987 cmp r3, #0 12988 bxeq lr @ nothing to do - jump to real handler 12989 EXPORT_PC() 12990 mov r0, rPC @ arg0 12991 mov r1, rFP @ arg1 12992 mov r2, rSELF @ arg2 12993 b dvmCheckBefore @ (dPC,dFP,self) tail call 12994 12995/* ------------------------------ */ 12996 .balign 64 12997.L_ALT_OP_INT_TO_BYTE: /* 0x8d */ 12998/* File: armv5te/alt_stub.S */ 12999/* 13000 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13001 * any interesting requests and then jump to the real instruction 13002 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13003 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13004 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13005 * bail to the real handler if breakFlags==0. 13006 */ 13007 ldrb r3, [rSELF, #offThread_breakFlags] 13008 adrl lr, dvmAsmInstructionStart + (141 * 64) 13009 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13010 cmp r3, #0 13011 bxeq lr @ nothing to do - jump to real handler 13012 EXPORT_PC() 13013 mov r0, rPC @ arg0 13014 mov r1, rFP @ arg1 13015 mov r2, rSELF @ arg2 13016 b dvmCheckBefore @ (dPC,dFP,self) tail call 13017 13018/* ------------------------------ */ 13019 .balign 64 13020.L_ALT_OP_INT_TO_CHAR: /* 0x8e */ 13021/* File: armv5te/alt_stub.S */ 13022/* 13023 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13024 * any interesting requests and then jump to the real instruction 13025 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13026 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13027 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13028 * bail to the real handler if breakFlags==0. 13029 */ 13030 ldrb r3, [rSELF, #offThread_breakFlags] 13031 adrl lr, dvmAsmInstructionStart + (142 * 64) 13032 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13033 cmp r3, #0 13034 bxeq lr @ nothing to do - jump to real handler 13035 EXPORT_PC() 13036 mov r0, rPC @ arg0 13037 mov r1, rFP @ arg1 13038 mov r2, rSELF @ arg2 13039 b dvmCheckBefore @ (dPC,dFP,self) tail call 13040 13041/* ------------------------------ */ 13042 .balign 64 13043.L_ALT_OP_INT_TO_SHORT: /* 0x8f */ 13044/* File: armv5te/alt_stub.S */ 13045/* 13046 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13047 * any interesting requests and then jump to the real instruction 13048 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13049 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13050 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13051 * bail to the real handler if breakFlags==0. 13052 */ 13053 ldrb r3, [rSELF, #offThread_breakFlags] 13054 adrl lr, dvmAsmInstructionStart + (143 * 64) 13055 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13056 cmp r3, #0 13057 bxeq lr @ nothing to do - jump to real handler 13058 EXPORT_PC() 13059 mov r0, rPC @ arg0 13060 mov r1, rFP @ arg1 13061 mov r2, rSELF @ arg2 13062 b dvmCheckBefore @ (dPC,dFP,self) tail call 13063 13064/* ------------------------------ */ 13065 .balign 64 13066.L_ALT_OP_ADD_INT: /* 0x90 */ 13067/* File: armv5te/alt_stub.S */ 13068/* 13069 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13070 * any interesting requests and then jump to the real instruction 13071 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13072 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13073 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13074 * bail to the real handler if breakFlags==0. 13075 */ 13076 ldrb r3, [rSELF, #offThread_breakFlags] 13077 adrl lr, dvmAsmInstructionStart + (144 * 64) 13078 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13079 cmp r3, #0 13080 bxeq lr @ nothing to do - jump to real handler 13081 EXPORT_PC() 13082 mov r0, rPC @ arg0 13083 mov r1, rFP @ arg1 13084 mov r2, rSELF @ arg2 13085 b dvmCheckBefore @ (dPC,dFP,self) tail call 13086 13087/* ------------------------------ */ 13088 .balign 64 13089.L_ALT_OP_SUB_INT: /* 0x91 */ 13090/* File: armv5te/alt_stub.S */ 13091/* 13092 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13093 * any interesting requests and then jump to the real instruction 13094 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13095 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13096 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13097 * bail to the real handler if breakFlags==0. 13098 */ 13099 ldrb r3, [rSELF, #offThread_breakFlags] 13100 adrl lr, dvmAsmInstructionStart + (145 * 64) 13101 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13102 cmp r3, #0 13103 bxeq lr @ nothing to do - jump to real handler 13104 EXPORT_PC() 13105 mov r0, rPC @ arg0 13106 mov r1, rFP @ arg1 13107 mov r2, rSELF @ arg2 13108 b dvmCheckBefore @ (dPC,dFP,self) tail call 13109 13110/* ------------------------------ */ 13111 .balign 64 13112.L_ALT_OP_MUL_INT: /* 0x92 */ 13113/* File: armv5te/alt_stub.S */ 13114/* 13115 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13116 * any interesting requests and then jump to the real instruction 13117 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13118 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13119 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13120 * bail to the real handler if breakFlags==0. 13121 */ 13122 ldrb r3, [rSELF, #offThread_breakFlags] 13123 adrl lr, dvmAsmInstructionStart + (146 * 64) 13124 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13125 cmp r3, #0 13126 bxeq lr @ nothing to do - jump to real handler 13127 EXPORT_PC() 13128 mov r0, rPC @ arg0 13129 mov r1, rFP @ arg1 13130 mov r2, rSELF @ arg2 13131 b dvmCheckBefore @ (dPC,dFP,self) tail call 13132 13133/* ------------------------------ */ 13134 .balign 64 13135.L_ALT_OP_DIV_INT: /* 0x93 */ 13136/* File: armv5te/alt_stub.S */ 13137/* 13138 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13139 * any interesting requests and then jump to the real instruction 13140 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13141 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13142 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13143 * bail to the real handler if breakFlags==0. 13144 */ 13145 ldrb r3, [rSELF, #offThread_breakFlags] 13146 adrl lr, dvmAsmInstructionStart + (147 * 64) 13147 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13148 cmp r3, #0 13149 bxeq lr @ nothing to do - jump to real handler 13150 EXPORT_PC() 13151 mov r0, rPC @ arg0 13152 mov r1, rFP @ arg1 13153 mov r2, rSELF @ arg2 13154 b dvmCheckBefore @ (dPC,dFP,self) tail call 13155 13156/* ------------------------------ */ 13157 .balign 64 13158.L_ALT_OP_REM_INT: /* 0x94 */ 13159/* File: armv5te/alt_stub.S */ 13160/* 13161 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13162 * any interesting requests and then jump to the real instruction 13163 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13164 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13165 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13166 * bail to the real handler if breakFlags==0. 13167 */ 13168 ldrb r3, [rSELF, #offThread_breakFlags] 13169 adrl lr, dvmAsmInstructionStart + (148 * 64) 13170 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13171 cmp r3, #0 13172 bxeq lr @ nothing to do - jump to real handler 13173 EXPORT_PC() 13174 mov r0, rPC @ arg0 13175 mov r1, rFP @ arg1 13176 mov r2, rSELF @ arg2 13177 b dvmCheckBefore @ (dPC,dFP,self) tail call 13178 13179/* ------------------------------ */ 13180 .balign 64 13181.L_ALT_OP_AND_INT: /* 0x95 */ 13182/* File: armv5te/alt_stub.S */ 13183/* 13184 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13185 * any interesting requests and then jump to the real instruction 13186 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13187 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13188 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13189 * bail to the real handler if breakFlags==0. 13190 */ 13191 ldrb r3, [rSELF, #offThread_breakFlags] 13192 adrl lr, dvmAsmInstructionStart + (149 * 64) 13193 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13194 cmp r3, #0 13195 bxeq lr @ nothing to do - jump to real handler 13196 EXPORT_PC() 13197 mov r0, rPC @ arg0 13198 mov r1, rFP @ arg1 13199 mov r2, rSELF @ arg2 13200 b dvmCheckBefore @ (dPC,dFP,self) tail call 13201 13202/* ------------------------------ */ 13203 .balign 64 13204.L_ALT_OP_OR_INT: /* 0x96 */ 13205/* File: armv5te/alt_stub.S */ 13206/* 13207 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13208 * any interesting requests and then jump to the real instruction 13209 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13210 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13211 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13212 * bail to the real handler if breakFlags==0. 13213 */ 13214 ldrb r3, [rSELF, #offThread_breakFlags] 13215 adrl lr, dvmAsmInstructionStart + (150 * 64) 13216 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13217 cmp r3, #0 13218 bxeq lr @ nothing to do - jump to real handler 13219 EXPORT_PC() 13220 mov r0, rPC @ arg0 13221 mov r1, rFP @ arg1 13222 mov r2, rSELF @ arg2 13223 b dvmCheckBefore @ (dPC,dFP,self) tail call 13224 13225/* ------------------------------ */ 13226 .balign 64 13227.L_ALT_OP_XOR_INT: /* 0x97 */ 13228/* File: armv5te/alt_stub.S */ 13229/* 13230 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13231 * any interesting requests and then jump to the real instruction 13232 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13233 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13234 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13235 * bail to the real handler if breakFlags==0. 13236 */ 13237 ldrb r3, [rSELF, #offThread_breakFlags] 13238 adrl lr, dvmAsmInstructionStart + (151 * 64) 13239 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13240 cmp r3, #0 13241 bxeq lr @ nothing to do - jump to real handler 13242 EXPORT_PC() 13243 mov r0, rPC @ arg0 13244 mov r1, rFP @ arg1 13245 mov r2, rSELF @ arg2 13246 b dvmCheckBefore @ (dPC,dFP,self) tail call 13247 13248/* ------------------------------ */ 13249 .balign 64 13250.L_ALT_OP_SHL_INT: /* 0x98 */ 13251/* File: armv5te/alt_stub.S */ 13252/* 13253 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13254 * any interesting requests and then jump to the real instruction 13255 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13256 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13257 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13258 * bail to the real handler if breakFlags==0. 13259 */ 13260 ldrb r3, [rSELF, #offThread_breakFlags] 13261 adrl lr, dvmAsmInstructionStart + (152 * 64) 13262 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13263 cmp r3, #0 13264 bxeq lr @ nothing to do - jump to real handler 13265 EXPORT_PC() 13266 mov r0, rPC @ arg0 13267 mov r1, rFP @ arg1 13268 mov r2, rSELF @ arg2 13269 b dvmCheckBefore @ (dPC,dFP,self) tail call 13270 13271/* ------------------------------ */ 13272 .balign 64 13273.L_ALT_OP_SHR_INT: /* 0x99 */ 13274/* File: armv5te/alt_stub.S */ 13275/* 13276 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13277 * any interesting requests and then jump to the real instruction 13278 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13279 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13280 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13281 * bail to the real handler if breakFlags==0. 13282 */ 13283 ldrb r3, [rSELF, #offThread_breakFlags] 13284 adrl lr, dvmAsmInstructionStart + (153 * 64) 13285 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13286 cmp r3, #0 13287 bxeq lr @ nothing to do - jump to real handler 13288 EXPORT_PC() 13289 mov r0, rPC @ arg0 13290 mov r1, rFP @ arg1 13291 mov r2, rSELF @ arg2 13292 b dvmCheckBefore @ (dPC,dFP,self) tail call 13293 13294/* ------------------------------ */ 13295 .balign 64 13296.L_ALT_OP_USHR_INT: /* 0x9a */ 13297/* File: armv5te/alt_stub.S */ 13298/* 13299 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13300 * any interesting requests and then jump to the real instruction 13301 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13302 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13303 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13304 * bail to the real handler if breakFlags==0. 13305 */ 13306 ldrb r3, [rSELF, #offThread_breakFlags] 13307 adrl lr, dvmAsmInstructionStart + (154 * 64) 13308 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13309 cmp r3, #0 13310 bxeq lr @ nothing to do - jump to real handler 13311 EXPORT_PC() 13312 mov r0, rPC @ arg0 13313 mov r1, rFP @ arg1 13314 mov r2, rSELF @ arg2 13315 b dvmCheckBefore @ (dPC,dFP,self) tail call 13316 13317/* ------------------------------ */ 13318 .balign 64 13319.L_ALT_OP_ADD_LONG: /* 0x9b */ 13320/* File: armv5te/alt_stub.S */ 13321/* 13322 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13323 * any interesting requests and then jump to the real instruction 13324 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13325 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13326 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13327 * bail to the real handler if breakFlags==0. 13328 */ 13329 ldrb r3, [rSELF, #offThread_breakFlags] 13330 adrl lr, dvmAsmInstructionStart + (155 * 64) 13331 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13332 cmp r3, #0 13333 bxeq lr @ nothing to do - jump to real handler 13334 EXPORT_PC() 13335 mov r0, rPC @ arg0 13336 mov r1, rFP @ arg1 13337 mov r2, rSELF @ arg2 13338 b dvmCheckBefore @ (dPC,dFP,self) tail call 13339 13340/* ------------------------------ */ 13341 .balign 64 13342.L_ALT_OP_SUB_LONG: /* 0x9c */ 13343/* File: armv5te/alt_stub.S */ 13344/* 13345 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13346 * any interesting requests and then jump to the real instruction 13347 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13348 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13349 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13350 * bail to the real handler if breakFlags==0. 13351 */ 13352 ldrb r3, [rSELF, #offThread_breakFlags] 13353 adrl lr, dvmAsmInstructionStart + (156 * 64) 13354 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13355 cmp r3, #0 13356 bxeq lr @ nothing to do - jump to real handler 13357 EXPORT_PC() 13358 mov r0, rPC @ arg0 13359 mov r1, rFP @ arg1 13360 mov r2, rSELF @ arg2 13361 b dvmCheckBefore @ (dPC,dFP,self) tail call 13362 13363/* ------------------------------ */ 13364 .balign 64 13365.L_ALT_OP_MUL_LONG: /* 0x9d */ 13366/* File: armv5te/alt_stub.S */ 13367/* 13368 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13369 * any interesting requests and then jump to the real instruction 13370 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13371 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13372 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13373 * bail to the real handler if breakFlags==0. 13374 */ 13375 ldrb r3, [rSELF, #offThread_breakFlags] 13376 adrl lr, dvmAsmInstructionStart + (157 * 64) 13377 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13378 cmp r3, #0 13379 bxeq lr @ nothing to do - jump to real handler 13380 EXPORT_PC() 13381 mov r0, rPC @ arg0 13382 mov r1, rFP @ arg1 13383 mov r2, rSELF @ arg2 13384 b dvmCheckBefore @ (dPC,dFP,self) tail call 13385 13386/* ------------------------------ */ 13387 .balign 64 13388.L_ALT_OP_DIV_LONG: /* 0x9e */ 13389/* File: armv5te/alt_stub.S */ 13390/* 13391 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13392 * any interesting requests and then jump to the real instruction 13393 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13394 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13395 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13396 * bail to the real handler if breakFlags==0. 13397 */ 13398 ldrb r3, [rSELF, #offThread_breakFlags] 13399 adrl lr, dvmAsmInstructionStart + (158 * 64) 13400 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13401 cmp r3, #0 13402 bxeq lr @ nothing to do - jump to real handler 13403 EXPORT_PC() 13404 mov r0, rPC @ arg0 13405 mov r1, rFP @ arg1 13406 mov r2, rSELF @ arg2 13407 b dvmCheckBefore @ (dPC,dFP,self) tail call 13408 13409/* ------------------------------ */ 13410 .balign 64 13411.L_ALT_OP_REM_LONG: /* 0x9f */ 13412/* File: armv5te/alt_stub.S */ 13413/* 13414 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13415 * any interesting requests and then jump to the real instruction 13416 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13417 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13418 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13419 * bail to the real handler if breakFlags==0. 13420 */ 13421 ldrb r3, [rSELF, #offThread_breakFlags] 13422 adrl lr, dvmAsmInstructionStart + (159 * 64) 13423 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13424 cmp r3, #0 13425 bxeq lr @ nothing to do - jump to real handler 13426 EXPORT_PC() 13427 mov r0, rPC @ arg0 13428 mov r1, rFP @ arg1 13429 mov r2, rSELF @ arg2 13430 b dvmCheckBefore @ (dPC,dFP,self) tail call 13431 13432/* ------------------------------ */ 13433 .balign 64 13434.L_ALT_OP_AND_LONG: /* 0xa0 */ 13435/* File: armv5te/alt_stub.S */ 13436/* 13437 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13438 * any interesting requests and then jump to the real instruction 13439 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13440 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13441 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13442 * bail to the real handler if breakFlags==0. 13443 */ 13444 ldrb r3, [rSELF, #offThread_breakFlags] 13445 adrl lr, dvmAsmInstructionStart + (160 * 64) 13446 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13447 cmp r3, #0 13448 bxeq lr @ nothing to do - jump to real handler 13449 EXPORT_PC() 13450 mov r0, rPC @ arg0 13451 mov r1, rFP @ arg1 13452 mov r2, rSELF @ arg2 13453 b dvmCheckBefore @ (dPC,dFP,self) tail call 13454 13455/* ------------------------------ */ 13456 .balign 64 13457.L_ALT_OP_OR_LONG: /* 0xa1 */ 13458/* File: armv5te/alt_stub.S */ 13459/* 13460 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13461 * any interesting requests and then jump to the real instruction 13462 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13463 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13464 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13465 * bail to the real handler if breakFlags==0. 13466 */ 13467 ldrb r3, [rSELF, #offThread_breakFlags] 13468 adrl lr, dvmAsmInstructionStart + (161 * 64) 13469 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13470 cmp r3, #0 13471 bxeq lr @ nothing to do - jump to real handler 13472 EXPORT_PC() 13473 mov r0, rPC @ arg0 13474 mov r1, rFP @ arg1 13475 mov r2, rSELF @ arg2 13476 b dvmCheckBefore @ (dPC,dFP,self) tail call 13477 13478/* ------------------------------ */ 13479 .balign 64 13480.L_ALT_OP_XOR_LONG: /* 0xa2 */ 13481/* File: armv5te/alt_stub.S */ 13482/* 13483 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13484 * any interesting requests and then jump to the real instruction 13485 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13486 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13487 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13488 * bail to the real handler if breakFlags==0. 13489 */ 13490 ldrb r3, [rSELF, #offThread_breakFlags] 13491 adrl lr, dvmAsmInstructionStart + (162 * 64) 13492 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13493 cmp r3, #0 13494 bxeq lr @ nothing to do - jump to real handler 13495 EXPORT_PC() 13496 mov r0, rPC @ arg0 13497 mov r1, rFP @ arg1 13498 mov r2, rSELF @ arg2 13499 b dvmCheckBefore @ (dPC,dFP,self) tail call 13500 13501/* ------------------------------ */ 13502 .balign 64 13503.L_ALT_OP_SHL_LONG: /* 0xa3 */ 13504/* File: armv5te/alt_stub.S */ 13505/* 13506 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13507 * any interesting requests and then jump to the real instruction 13508 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13509 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13510 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13511 * bail to the real handler if breakFlags==0. 13512 */ 13513 ldrb r3, [rSELF, #offThread_breakFlags] 13514 adrl lr, dvmAsmInstructionStart + (163 * 64) 13515 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13516 cmp r3, #0 13517 bxeq lr @ nothing to do - jump to real handler 13518 EXPORT_PC() 13519 mov r0, rPC @ arg0 13520 mov r1, rFP @ arg1 13521 mov r2, rSELF @ arg2 13522 b dvmCheckBefore @ (dPC,dFP,self) tail call 13523 13524/* ------------------------------ */ 13525 .balign 64 13526.L_ALT_OP_SHR_LONG: /* 0xa4 */ 13527/* File: armv5te/alt_stub.S */ 13528/* 13529 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13530 * any interesting requests and then jump to the real instruction 13531 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13532 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13533 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13534 * bail to the real handler if breakFlags==0. 13535 */ 13536 ldrb r3, [rSELF, #offThread_breakFlags] 13537 adrl lr, dvmAsmInstructionStart + (164 * 64) 13538 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13539 cmp r3, #0 13540 bxeq lr @ nothing to do - jump to real handler 13541 EXPORT_PC() 13542 mov r0, rPC @ arg0 13543 mov r1, rFP @ arg1 13544 mov r2, rSELF @ arg2 13545 b dvmCheckBefore @ (dPC,dFP,self) tail call 13546 13547/* ------------------------------ */ 13548 .balign 64 13549.L_ALT_OP_USHR_LONG: /* 0xa5 */ 13550/* File: armv5te/alt_stub.S */ 13551/* 13552 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13553 * any interesting requests and then jump to the real instruction 13554 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13555 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13556 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13557 * bail to the real handler if breakFlags==0. 13558 */ 13559 ldrb r3, [rSELF, #offThread_breakFlags] 13560 adrl lr, dvmAsmInstructionStart + (165 * 64) 13561 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13562 cmp r3, #0 13563 bxeq lr @ nothing to do - jump to real handler 13564 EXPORT_PC() 13565 mov r0, rPC @ arg0 13566 mov r1, rFP @ arg1 13567 mov r2, rSELF @ arg2 13568 b dvmCheckBefore @ (dPC,dFP,self) tail call 13569 13570/* ------------------------------ */ 13571 .balign 64 13572.L_ALT_OP_ADD_FLOAT: /* 0xa6 */ 13573/* File: armv5te/alt_stub.S */ 13574/* 13575 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13576 * any interesting requests and then jump to the real instruction 13577 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13578 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13579 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13580 * bail to the real handler if breakFlags==0. 13581 */ 13582 ldrb r3, [rSELF, #offThread_breakFlags] 13583 adrl lr, dvmAsmInstructionStart + (166 * 64) 13584 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13585 cmp r3, #0 13586 bxeq lr @ nothing to do - jump to real handler 13587 EXPORT_PC() 13588 mov r0, rPC @ arg0 13589 mov r1, rFP @ arg1 13590 mov r2, rSELF @ arg2 13591 b dvmCheckBefore @ (dPC,dFP,self) tail call 13592 13593/* ------------------------------ */ 13594 .balign 64 13595.L_ALT_OP_SUB_FLOAT: /* 0xa7 */ 13596/* File: armv5te/alt_stub.S */ 13597/* 13598 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13599 * any interesting requests and then jump to the real instruction 13600 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13601 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13602 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13603 * bail to the real handler if breakFlags==0. 13604 */ 13605 ldrb r3, [rSELF, #offThread_breakFlags] 13606 adrl lr, dvmAsmInstructionStart + (167 * 64) 13607 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13608 cmp r3, #0 13609 bxeq lr @ nothing to do - jump to real handler 13610 EXPORT_PC() 13611 mov r0, rPC @ arg0 13612 mov r1, rFP @ arg1 13613 mov r2, rSELF @ arg2 13614 b dvmCheckBefore @ (dPC,dFP,self) tail call 13615 13616/* ------------------------------ */ 13617 .balign 64 13618.L_ALT_OP_MUL_FLOAT: /* 0xa8 */ 13619/* File: armv5te/alt_stub.S */ 13620/* 13621 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13622 * any interesting requests and then jump to the real instruction 13623 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13624 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13625 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13626 * bail to the real handler if breakFlags==0. 13627 */ 13628 ldrb r3, [rSELF, #offThread_breakFlags] 13629 adrl lr, dvmAsmInstructionStart + (168 * 64) 13630 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13631 cmp r3, #0 13632 bxeq lr @ nothing to do - jump to real handler 13633 EXPORT_PC() 13634 mov r0, rPC @ arg0 13635 mov r1, rFP @ arg1 13636 mov r2, rSELF @ arg2 13637 b dvmCheckBefore @ (dPC,dFP,self) tail call 13638 13639/* ------------------------------ */ 13640 .balign 64 13641.L_ALT_OP_DIV_FLOAT: /* 0xa9 */ 13642/* File: armv5te/alt_stub.S */ 13643/* 13644 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13645 * any interesting requests and then jump to the real instruction 13646 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13647 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13648 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13649 * bail to the real handler if breakFlags==0. 13650 */ 13651 ldrb r3, [rSELF, #offThread_breakFlags] 13652 adrl lr, dvmAsmInstructionStart + (169 * 64) 13653 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13654 cmp r3, #0 13655 bxeq lr @ nothing to do - jump to real handler 13656 EXPORT_PC() 13657 mov r0, rPC @ arg0 13658 mov r1, rFP @ arg1 13659 mov r2, rSELF @ arg2 13660 b dvmCheckBefore @ (dPC,dFP,self) tail call 13661 13662/* ------------------------------ */ 13663 .balign 64 13664.L_ALT_OP_REM_FLOAT: /* 0xaa */ 13665/* File: armv5te/alt_stub.S */ 13666/* 13667 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13668 * any interesting requests and then jump to the real instruction 13669 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13670 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13671 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13672 * bail to the real handler if breakFlags==0. 13673 */ 13674 ldrb r3, [rSELF, #offThread_breakFlags] 13675 adrl lr, dvmAsmInstructionStart + (170 * 64) 13676 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13677 cmp r3, #0 13678 bxeq lr @ nothing to do - jump to real handler 13679 EXPORT_PC() 13680 mov r0, rPC @ arg0 13681 mov r1, rFP @ arg1 13682 mov r2, rSELF @ arg2 13683 b dvmCheckBefore @ (dPC,dFP,self) tail call 13684 13685/* ------------------------------ */ 13686 .balign 64 13687.L_ALT_OP_ADD_DOUBLE: /* 0xab */ 13688/* File: armv5te/alt_stub.S */ 13689/* 13690 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13691 * any interesting requests and then jump to the real instruction 13692 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13693 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13694 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13695 * bail to the real handler if breakFlags==0. 13696 */ 13697 ldrb r3, [rSELF, #offThread_breakFlags] 13698 adrl lr, dvmAsmInstructionStart + (171 * 64) 13699 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13700 cmp r3, #0 13701 bxeq lr @ nothing to do - jump to real handler 13702 EXPORT_PC() 13703 mov r0, rPC @ arg0 13704 mov r1, rFP @ arg1 13705 mov r2, rSELF @ arg2 13706 b dvmCheckBefore @ (dPC,dFP,self) tail call 13707 13708/* ------------------------------ */ 13709 .balign 64 13710.L_ALT_OP_SUB_DOUBLE: /* 0xac */ 13711/* File: armv5te/alt_stub.S */ 13712/* 13713 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13714 * any interesting requests and then jump to the real instruction 13715 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13716 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13717 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13718 * bail to the real handler if breakFlags==0. 13719 */ 13720 ldrb r3, [rSELF, #offThread_breakFlags] 13721 adrl lr, dvmAsmInstructionStart + (172 * 64) 13722 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13723 cmp r3, #0 13724 bxeq lr @ nothing to do - jump to real handler 13725 EXPORT_PC() 13726 mov r0, rPC @ arg0 13727 mov r1, rFP @ arg1 13728 mov r2, rSELF @ arg2 13729 b dvmCheckBefore @ (dPC,dFP,self) tail call 13730 13731/* ------------------------------ */ 13732 .balign 64 13733.L_ALT_OP_MUL_DOUBLE: /* 0xad */ 13734/* File: armv5te/alt_stub.S */ 13735/* 13736 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13737 * any interesting requests and then jump to the real instruction 13738 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13739 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13740 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13741 * bail to the real handler if breakFlags==0. 13742 */ 13743 ldrb r3, [rSELF, #offThread_breakFlags] 13744 adrl lr, dvmAsmInstructionStart + (173 * 64) 13745 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13746 cmp r3, #0 13747 bxeq lr @ nothing to do - jump to real handler 13748 EXPORT_PC() 13749 mov r0, rPC @ arg0 13750 mov r1, rFP @ arg1 13751 mov r2, rSELF @ arg2 13752 b dvmCheckBefore @ (dPC,dFP,self) tail call 13753 13754/* ------------------------------ */ 13755 .balign 64 13756.L_ALT_OP_DIV_DOUBLE: /* 0xae */ 13757/* File: armv5te/alt_stub.S */ 13758/* 13759 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13760 * any interesting requests and then jump to the real instruction 13761 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13762 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13763 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13764 * bail to the real handler if breakFlags==0. 13765 */ 13766 ldrb r3, [rSELF, #offThread_breakFlags] 13767 adrl lr, dvmAsmInstructionStart + (174 * 64) 13768 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13769 cmp r3, #0 13770 bxeq lr @ nothing to do - jump to real handler 13771 EXPORT_PC() 13772 mov r0, rPC @ arg0 13773 mov r1, rFP @ arg1 13774 mov r2, rSELF @ arg2 13775 b dvmCheckBefore @ (dPC,dFP,self) tail call 13776 13777/* ------------------------------ */ 13778 .balign 64 13779.L_ALT_OP_REM_DOUBLE: /* 0xaf */ 13780/* File: armv5te/alt_stub.S */ 13781/* 13782 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13783 * any interesting requests and then jump to the real instruction 13784 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13785 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13786 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13787 * bail to the real handler if breakFlags==0. 13788 */ 13789 ldrb r3, [rSELF, #offThread_breakFlags] 13790 adrl lr, dvmAsmInstructionStart + (175 * 64) 13791 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13792 cmp r3, #0 13793 bxeq lr @ nothing to do - jump to real handler 13794 EXPORT_PC() 13795 mov r0, rPC @ arg0 13796 mov r1, rFP @ arg1 13797 mov r2, rSELF @ arg2 13798 b dvmCheckBefore @ (dPC,dFP,self) tail call 13799 13800/* ------------------------------ */ 13801 .balign 64 13802.L_ALT_OP_ADD_INT_2ADDR: /* 0xb0 */ 13803/* File: armv5te/alt_stub.S */ 13804/* 13805 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13806 * any interesting requests and then jump to the real instruction 13807 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13808 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13809 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13810 * bail to the real handler if breakFlags==0. 13811 */ 13812 ldrb r3, [rSELF, #offThread_breakFlags] 13813 adrl lr, dvmAsmInstructionStart + (176 * 64) 13814 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13815 cmp r3, #0 13816 bxeq lr @ nothing to do - jump to real handler 13817 EXPORT_PC() 13818 mov r0, rPC @ arg0 13819 mov r1, rFP @ arg1 13820 mov r2, rSELF @ arg2 13821 b dvmCheckBefore @ (dPC,dFP,self) tail call 13822 13823/* ------------------------------ */ 13824 .balign 64 13825.L_ALT_OP_SUB_INT_2ADDR: /* 0xb1 */ 13826/* File: armv5te/alt_stub.S */ 13827/* 13828 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13829 * any interesting requests and then jump to the real instruction 13830 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13831 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13832 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13833 * bail to the real handler if breakFlags==0. 13834 */ 13835 ldrb r3, [rSELF, #offThread_breakFlags] 13836 adrl lr, dvmAsmInstructionStart + (177 * 64) 13837 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13838 cmp r3, #0 13839 bxeq lr @ nothing to do - jump to real handler 13840 EXPORT_PC() 13841 mov r0, rPC @ arg0 13842 mov r1, rFP @ arg1 13843 mov r2, rSELF @ arg2 13844 b dvmCheckBefore @ (dPC,dFP,self) tail call 13845 13846/* ------------------------------ */ 13847 .balign 64 13848.L_ALT_OP_MUL_INT_2ADDR: /* 0xb2 */ 13849/* File: armv5te/alt_stub.S */ 13850/* 13851 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13852 * any interesting requests and then jump to the real instruction 13853 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13854 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13855 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13856 * bail to the real handler if breakFlags==0. 13857 */ 13858 ldrb r3, [rSELF, #offThread_breakFlags] 13859 adrl lr, dvmAsmInstructionStart + (178 * 64) 13860 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13861 cmp r3, #0 13862 bxeq lr @ nothing to do - jump to real handler 13863 EXPORT_PC() 13864 mov r0, rPC @ arg0 13865 mov r1, rFP @ arg1 13866 mov r2, rSELF @ arg2 13867 b dvmCheckBefore @ (dPC,dFP,self) tail call 13868 13869/* ------------------------------ */ 13870 .balign 64 13871.L_ALT_OP_DIV_INT_2ADDR: /* 0xb3 */ 13872/* File: armv5te/alt_stub.S */ 13873/* 13874 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13875 * any interesting requests and then jump to the real instruction 13876 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13877 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13878 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13879 * bail to the real handler if breakFlags==0. 13880 */ 13881 ldrb r3, [rSELF, #offThread_breakFlags] 13882 adrl lr, dvmAsmInstructionStart + (179 * 64) 13883 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13884 cmp r3, #0 13885 bxeq lr @ nothing to do - jump to real handler 13886 EXPORT_PC() 13887 mov r0, rPC @ arg0 13888 mov r1, rFP @ arg1 13889 mov r2, rSELF @ arg2 13890 b dvmCheckBefore @ (dPC,dFP,self) tail call 13891 13892/* ------------------------------ */ 13893 .balign 64 13894.L_ALT_OP_REM_INT_2ADDR: /* 0xb4 */ 13895/* File: armv5te/alt_stub.S */ 13896/* 13897 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13898 * any interesting requests and then jump to the real instruction 13899 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13900 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13901 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13902 * bail to the real handler if breakFlags==0. 13903 */ 13904 ldrb r3, [rSELF, #offThread_breakFlags] 13905 adrl lr, dvmAsmInstructionStart + (180 * 64) 13906 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13907 cmp r3, #0 13908 bxeq lr @ nothing to do - jump to real handler 13909 EXPORT_PC() 13910 mov r0, rPC @ arg0 13911 mov r1, rFP @ arg1 13912 mov r2, rSELF @ arg2 13913 b dvmCheckBefore @ (dPC,dFP,self) tail call 13914 13915/* ------------------------------ */ 13916 .balign 64 13917.L_ALT_OP_AND_INT_2ADDR: /* 0xb5 */ 13918/* File: armv5te/alt_stub.S */ 13919/* 13920 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13921 * any interesting requests and then jump to the real instruction 13922 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13923 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13924 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13925 * bail to the real handler if breakFlags==0. 13926 */ 13927 ldrb r3, [rSELF, #offThread_breakFlags] 13928 adrl lr, dvmAsmInstructionStart + (181 * 64) 13929 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13930 cmp r3, #0 13931 bxeq lr @ nothing to do - jump to real handler 13932 EXPORT_PC() 13933 mov r0, rPC @ arg0 13934 mov r1, rFP @ arg1 13935 mov r2, rSELF @ arg2 13936 b dvmCheckBefore @ (dPC,dFP,self) tail call 13937 13938/* ------------------------------ */ 13939 .balign 64 13940.L_ALT_OP_OR_INT_2ADDR: /* 0xb6 */ 13941/* File: armv5te/alt_stub.S */ 13942/* 13943 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13944 * any interesting requests and then jump to the real instruction 13945 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13946 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13947 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13948 * bail to the real handler if breakFlags==0. 13949 */ 13950 ldrb r3, [rSELF, #offThread_breakFlags] 13951 adrl lr, dvmAsmInstructionStart + (182 * 64) 13952 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13953 cmp r3, #0 13954 bxeq lr @ nothing to do - jump to real handler 13955 EXPORT_PC() 13956 mov r0, rPC @ arg0 13957 mov r1, rFP @ arg1 13958 mov r2, rSELF @ arg2 13959 b dvmCheckBefore @ (dPC,dFP,self) tail call 13960 13961/* ------------------------------ */ 13962 .balign 64 13963.L_ALT_OP_XOR_INT_2ADDR: /* 0xb7 */ 13964/* File: armv5te/alt_stub.S */ 13965/* 13966 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13967 * any interesting requests and then jump to the real instruction 13968 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13969 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13970 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13971 * bail to the real handler if breakFlags==0. 13972 */ 13973 ldrb r3, [rSELF, #offThread_breakFlags] 13974 adrl lr, dvmAsmInstructionStart + (183 * 64) 13975 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13976 cmp r3, #0 13977 bxeq lr @ nothing to do - jump to real handler 13978 EXPORT_PC() 13979 mov r0, rPC @ arg0 13980 mov r1, rFP @ arg1 13981 mov r2, rSELF @ arg2 13982 b dvmCheckBefore @ (dPC,dFP,self) tail call 13983 13984/* ------------------------------ */ 13985 .balign 64 13986.L_ALT_OP_SHL_INT_2ADDR: /* 0xb8 */ 13987/* File: armv5te/alt_stub.S */ 13988/* 13989 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 13990 * any interesting requests and then jump to the real instruction 13991 * handler. Note that the call to dvmCheckBefore is done as a tail call. 13992 * rIBASE updates won't be seen until a refresh, and we can tell we have a 13993 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 13994 * bail to the real handler if breakFlags==0. 13995 */ 13996 ldrb r3, [rSELF, #offThread_breakFlags] 13997 adrl lr, dvmAsmInstructionStart + (184 * 64) 13998 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 13999 cmp r3, #0 14000 bxeq lr @ nothing to do - jump to real handler 14001 EXPORT_PC() 14002 mov r0, rPC @ arg0 14003 mov r1, rFP @ arg1 14004 mov r2, rSELF @ arg2 14005 b dvmCheckBefore @ (dPC,dFP,self) tail call 14006 14007/* ------------------------------ */ 14008 .balign 64 14009.L_ALT_OP_SHR_INT_2ADDR: /* 0xb9 */ 14010/* File: armv5te/alt_stub.S */ 14011/* 14012 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14013 * any interesting requests and then jump to the real instruction 14014 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14015 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14016 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14017 * bail to the real handler if breakFlags==0. 14018 */ 14019 ldrb r3, [rSELF, #offThread_breakFlags] 14020 adrl lr, dvmAsmInstructionStart + (185 * 64) 14021 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14022 cmp r3, #0 14023 bxeq lr @ nothing to do - jump to real handler 14024 EXPORT_PC() 14025 mov r0, rPC @ arg0 14026 mov r1, rFP @ arg1 14027 mov r2, rSELF @ arg2 14028 b dvmCheckBefore @ (dPC,dFP,self) tail call 14029 14030/* ------------------------------ */ 14031 .balign 64 14032.L_ALT_OP_USHR_INT_2ADDR: /* 0xba */ 14033/* File: armv5te/alt_stub.S */ 14034/* 14035 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14036 * any interesting requests and then jump to the real instruction 14037 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14038 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14039 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14040 * bail to the real handler if breakFlags==0. 14041 */ 14042 ldrb r3, [rSELF, #offThread_breakFlags] 14043 adrl lr, dvmAsmInstructionStart + (186 * 64) 14044 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14045 cmp r3, #0 14046 bxeq lr @ nothing to do - jump to real handler 14047 EXPORT_PC() 14048 mov r0, rPC @ arg0 14049 mov r1, rFP @ arg1 14050 mov r2, rSELF @ arg2 14051 b dvmCheckBefore @ (dPC,dFP,self) tail call 14052 14053/* ------------------------------ */ 14054 .balign 64 14055.L_ALT_OP_ADD_LONG_2ADDR: /* 0xbb */ 14056/* File: armv5te/alt_stub.S */ 14057/* 14058 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14059 * any interesting requests and then jump to the real instruction 14060 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14061 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14062 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14063 * bail to the real handler if breakFlags==0. 14064 */ 14065 ldrb r3, [rSELF, #offThread_breakFlags] 14066 adrl lr, dvmAsmInstructionStart + (187 * 64) 14067 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14068 cmp r3, #0 14069 bxeq lr @ nothing to do - jump to real handler 14070 EXPORT_PC() 14071 mov r0, rPC @ arg0 14072 mov r1, rFP @ arg1 14073 mov r2, rSELF @ arg2 14074 b dvmCheckBefore @ (dPC,dFP,self) tail call 14075 14076/* ------------------------------ */ 14077 .balign 64 14078.L_ALT_OP_SUB_LONG_2ADDR: /* 0xbc */ 14079/* File: armv5te/alt_stub.S */ 14080/* 14081 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14082 * any interesting requests and then jump to the real instruction 14083 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14084 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14085 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14086 * bail to the real handler if breakFlags==0. 14087 */ 14088 ldrb r3, [rSELF, #offThread_breakFlags] 14089 adrl lr, dvmAsmInstructionStart + (188 * 64) 14090 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14091 cmp r3, #0 14092 bxeq lr @ nothing to do - jump to real handler 14093 EXPORT_PC() 14094 mov r0, rPC @ arg0 14095 mov r1, rFP @ arg1 14096 mov r2, rSELF @ arg2 14097 b dvmCheckBefore @ (dPC,dFP,self) tail call 14098 14099/* ------------------------------ */ 14100 .balign 64 14101.L_ALT_OP_MUL_LONG_2ADDR: /* 0xbd */ 14102/* File: armv5te/alt_stub.S */ 14103/* 14104 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14105 * any interesting requests and then jump to the real instruction 14106 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14107 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14108 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14109 * bail to the real handler if breakFlags==0. 14110 */ 14111 ldrb r3, [rSELF, #offThread_breakFlags] 14112 adrl lr, dvmAsmInstructionStart + (189 * 64) 14113 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14114 cmp r3, #0 14115 bxeq lr @ nothing to do - jump to real handler 14116 EXPORT_PC() 14117 mov r0, rPC @ arg0 14118 mov r1, rFP @ arg1 14119 mov r2, rSELF @ arg2 14120 b dvmCheckBefore @ (dPC,dFP,self) tail call 14121 14122/* ------------------------------ */ 14123 .balign 64 14124.L_ALT_OP_DIV_LONG_2ADDR: /* 0xbe */ 14125/* File: armv5te/alt_stub.S */ 14126/* 14127 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14128 * any interesting requests and then jump to the real instruction 14129 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14130 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14131 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14132 * bail to the real handler if breakFlags==0. 14133 */ 14134 ldrb r3, [rSELF, #offThread_breakFlags] 14135 adrl lr, dvmAsmInstructionStart + (190 * 64) 14136 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14137 cmp r3, #0 14138 bxeq lr @ nothing to do - jump to real handler 14139 EXPORT_PC() 14140 mov r0, rPC @ arg0 14141 mov r1, rFP @ arg1 14142 mov r2, rSELF @ arg2 14143 b dvmCheckBefore @ (dPC,dFP,self) tail call 14144 14145/* ------------------------------ */ 14146 .balign 64 14147.L_ALT_OP_REM_LONG_2ADDR: /* 0xbf */ 14148/* File: armv5te/alt_stub.S */ 14149/* 14150 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14151 * any interesting requests and then jump to the real instruction 14152 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14153 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14154 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14155 * bail to the real handler if breakFlags==0. 14156 */ 14157 ldrb r3, [rSELF, #offThread_breakFlags] 14158 adrl lr, dvmAsmInstructionStart + (191 * 64) 14159 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14160 cmp r3, #0 14161 bxeq lr @ nothing to do - jump to real handler 14162 EXPORT_PC() 14163 mov r0, rPC @ arg0 14164 mov r1, rFP @ arg1 14165 mov r2, rSELF @ arg2 14166 b dvmCheckBefore @ (dPC,dFP,self) tail call 14167 14168/* ------------------------------ */ 14169 .balign 64 14170.L_ALT_OP_AND_LONG_2ADDR: /* 0xc0 */ 14171/* File: armv5te/alt_stub.S */ 14172/* 14173 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14174 * any interesting requests and then jump to the real instruction 14175 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14176 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14177 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14178 * bail to the real handler if breakFlags==0. 14179 */ 14180 ldrb r3, [rSELF, #offThread_breakFlags] 14181 adrl lr, dvmAsmInstructionStart + (192 * 64) 14182 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14183 cmp r3, #0 14184 bxeq lr @ nothing to do - jump to real handler 14185 EXPORT_PC() 14186 mov r0, rPC @ arg0 14187 mov r1, rFP @ arg1 14188 mov r2, rSELF @ arg2 14189 b dvmCheckBefore @ (dPC,dFP,self) tail call 14190 14191/* ------------------------------ */ 14192 .balign 64 14193.L_ALT_OP_OR_LONG_2ADDR: /* 0xc1 */ 14194/* File: armv5te/alt_stub.S */ 14195/* 14196 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14197 * any interesting requests and then jump to the real instruction 14198 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14199 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14200 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14201 * bail to the real handler if breakFlags==0. 14202 */ 14203 ldrb r3, [rSELF, #offThread_breakFlags] 14204 adrl lr, dvmAsmInstructionStart + (193 * 64) 14205 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14206 cmp r3, #0 14207 bxeq lr @ nothing to do - jump to real handler 14208 EXPORT_PC() 14209 mov r0, rPC @ arg0 14210 mov r1, rFP @ arg1 14211 mov r2, rSELF @ arg2 14212 b dvmCheckBefore @ (dPC,dFP,self) tail call 14213 14214/* ------------------------------ */ 14215 .balign 64 14216.L_ALT_OP_XOR_LONG_2ADDR: /* 0xc2 */ 14217/* File: armv5te/alt_stub.S */ 14218/* 14219 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14220 * any interesting requests and then jump to the real instruction 14221 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14222 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14223 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14224 * bail to the real handler if breakFlags==0. 14225 */ 14226 ldrb r3, [rSELF, #offThread_breakFlags] 14227 adrl lr, dvmAsmInstructionStart + (194 * 64) 14228 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14229 cmp r3, #0 14230 bxeq lr @ nothing to do - jump to real handler 14231 EXPORT_PC() 14232 mov r0, rPC @ arg0 14233 mov r1, rFP @ arg1 14234 mov r2, rSELF @ arg2 14235 b dvmCheckBefore @ (dPC,dFP,self) tail call 14236 14237/* ------------------------------ */ 14238 .balign 64 14239.L_ALT_OP_SHL_LONG_2ADDR: /* 0xc3 */ 14240/* File: armv5te/alt_stub.S */ 14241/* 14242 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14243 * any interesting requests and then jump to the real instruction 14244 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14245 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14246 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14247 * bail to the real handler if breakFlags==0. 14248 */ 14249 ldrb r3, [rSELF, #offThread_breakFlags] 14250 adrl lr, dvmAsmInstructionStart + (195 * 64) 14251 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14252 cmp r3, #0 14253 bxeq lr @ nothing to do - jump to real handler 14254 EXPORT_PC() 14255 mov r0, rPC @ arg0 14256 mov r1, rFP @ arg1 14257 mov r2, rSELF @ arg2 14258 b dvmCheckBefore @ (dPC,dFP,self) tail call 14259 14260/* ------------------------------ */ 14261 .balign 64 14262.L_ALT_OP_SHR_LONG_2ADDR: /* 0xc4 */ 14263/* File: armv5te/alt_stub.S */ 14264/* 14265 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14266 * any interesting requests and then jump to the real instruction 14267 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14268 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14269 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14270 * bail to the real handler if breakFlags==0. 14271 */ 14272 ldrb r3, [rSELF, #offThread_breakFlags] 14273 adrl lr, dvmAsmInstructionStart + (196 * 64) 14274 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14275 cmp r3, #0 14276 bxeq lr @ nothing to do - jump to real handler 14277 EXPORT_PC() 14278 mov r0, rPC @ arg0 14279 mov r1, rFP @ arg1 14280 mov r2, rSELF @ arg2 14281 b dvmCheckBefore @ (dPC,dFP,self) tail call 14282 14283/* ------------------------------ */ 14284 .balign 64 14285.L_ALT_OP_USHR_LONG_2ADDR: /* 0xc5 */ 14286/* File: armv5te/alt_stub.S */ 14287/* 14288 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14289 * any interesting requests and then jump to the real instruction 14290 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14291 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14292 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14293 * bail to the real handler if breakFlags==0. 14294 */ 14295 ldrb r3, [rSELF, #offThread_breakFlags] 14296 adrl lr, dvmAsmInstructionStart + (197 * 64) 14297 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14298 cmp r3, #0 14299 bxeq lr @ nothing to do - jump to real handler 14300 EXPORT_PC() 14301 mov r0, rPC @ arg0 14302 mov r1, rFP @ arg1 14303 mov r2, rSELF @ arg2 14304 b dvmCheckBefore @ (dPC,dFP,self) tail call 14305 14306/* ------------------------------ */ 14307 .balign 64 14308.L_ALT_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 14309/* File: armv5te/alt_stub.S */ 14310/* 14311 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14312 * any interesting requests and then jump to the real instruction 14313 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14314 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14315 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14316 * bail to the real handler if breakFlags==0. 14317 */ 14318 ldrb r3, [rSELF, #offThread_breakFlags] 14319 adrl lr, dvmAsmInstructionStart + (198 * 64) 14320 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14321 cmp r3, #0 14322 bxeq lr @ nothing to do - jump to real handler 14323 EXPORT_PC() 14324 mov r0, rPC @ arg0 14325 mov r1, rFP @ arg1 14326 mov r2, rSELF @ arg2 14327 b dvmCheckBefore @ (dPC,dFP,self) tail call 14328 14329/* ------------------------------ */ 14330 .balign 64 14331.L_ALT_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 14332/* File: armv5te/alt_stub.S */ 14333/* 14334 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14335 * any interesting requests and then jump to the real instruction 14336 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14337 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14338 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14339 * bail to the real handler if breakFlags==0. 14340 */ 14341 ldrb r3, [rSELF, #offThread_breakFlags] 14342 adrl lr, dvmAsmInstructionStart + (199 * 64) 14343 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14344 cmp r3, #0 14345 bxeq lr @ nothing to do - jump to real handler 14346 EXPORT_PC() 14347 mov r0, rPC @ arg0 14348 mov r1, rFP @ arg1 14349 mov r2, rSELF @ arg2 14350 b dvmCheckBefore @ (dPC,dFP,self) tail call 14351 14352/* ------------------------------ */ 14353 .balign 64 14354.L_ALT_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 14355/* File: armv5te/alt_stub.S */ 14356/* 14357 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14358 * any interesting requests and then jump to the real instruction 14359 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14360 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14361 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14362 * bail to the real handler if breakFlags==0. 14363 */ 14364 ldrb r3, [rSELF, #offThread_breakFlags] 14365 adrl lr, dvmAsmInstructionStart + (200 * 64) 14366 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14367 cmp r3, #0 14368 bxeq lr @ nothing to do - jump to real handler 14369 EXPORT_PC() 14370 mov r0, rPC @ arg0 14371 mov r1, rFP @ arg1 14372 mov r2, rSELF @ arg2 14373 b dvmCheckBefore @ (dPC,dFP,self) tail call 14374 14375/* ------------------------------ */ 14376 .balign 64 14377.L_ALT_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 14378/* File: armv5te/alt_stub.S */ 14379/* 14380 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14381 * any interesting requests and then jump to the real instruction 14382 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14383 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14384 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14385 * bail to the real handler if breakFlags==0. 14386 */ 14387 ldrb r3, [rSELF, #offThread_breakFlags] 14388 adrl lr, dvmAsmInstructionStart + (201 * 64) 14389 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14390 cmp r3, #0 14391 bxeq lr @ nothing to do - jump to real handler 14392 EXPORT_PC() 14393 mov r0, rPC @ arg0 14394 mov r1, rFP @ arg1 14395 mov r2, rSELF @ arg2 14396 b dvmCheckBefore @ (dPC,dFP,self) tail call 14397 14398/* ------------------------------ */ 14399 .balign 64 14400.L_ALT_OP_REM_FLOAT_2ADDR: /* 0xca */ 14401/* File: armv5te/alt_stub.S */ 14402/* 14403 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14404 * any interesting requests and then jump to the real instruction 14405 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14406 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14407 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14408 * bail to the real handler if breakFlags==0. 14409 */ 14410 ldrb r3, [rSELF, #offThread_breakFlags] 14411 adrl lr, dvmAsmInstructionStart + (202 * 64) 14412 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14413 cmp r3, #0 14414 bxeq lr @ nothing to do - jump to real handler 14415 EXPORT_PC() 14416 mov r0, rPC @ arg0 14417 mov r1, rFP @ arg1 14418 mov r2, rSELF @ arg2 14419 b dvmCheckBefore @ (dPC,dFP,self) tail call 14420 14421/* ------------------------------ */ 14422 .balign 64 14423.L_ALT_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 14424/* File: armv5te/alt_stub.S */ 14425/* 14426 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14427 * any interesting requests and then jump to the real instruction 14428 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14429 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14430 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14431 * bail to the real handler if breakFlags==0. 14432 */ 14433 ldrb r3, [rSELF, #offThread_breakFlags] 14434 adrl lr, dvmAsmInstructionStart + (203 * 64) 14435 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14436 cmp r3, #0 14437 bxeq lr @ nothing to do - jump to real handler 14438 EXPORT_PC() 14439 mov r0, rPC @ arg0 14440 mov r1, rFP @ arg1 14441 mov r2, rSELF @ arg2 14442 b dvmCheckBefore @ (dPC,dFP,self) tail call 14443 14444/* ------------------------------ */ 14445 .balign 64 14446.L_ALT_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 14447/* File: armv5te/alt_stub.S */ 14448/* 14449 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14450 * any interesting requests and then jump to the real instruction 14451 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14452 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14453 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14454 * bail to the real handler if breakFlags==0. 14455 */ 14456 ldrb r3, [rSELF, #offThread_breakFlags] 14457 adrl lr, dvmAsmInstructionStart + (204 * 64) 14458 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14459 cmp r3, #0 14460 bxeq lr @ nothing to do - jump to real handler 14461 EXPORT_PC() 14462 mov r0, rPC @ arg0 14463 mov r1, rFP @ arg1 14464 mov r2, rSELF @ arg2 14465 b dvmCheckBefore @ (dPC,dFP,self) tail call 14466 14467/* ------------------------------ */ 14468 .balign 64 14469.L_ALT_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 14470/* File: armv5te/alt_stub.S */ 14471/* 14472 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14473 * any interesting requests and then jump to the real instruction 14474 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14475 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14476 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14477 * bail to the real handler if breakFlags==0. 14478 */ 14479 ldrb r3, [rSELF, #offThread_breakFlags] 14480 adrl lr, dvmAsmInstructionStart + (205 * 64) 14481 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14482 cmp r3, #0 14483 bxeq lr @ nothing to do - jump to real handler 14484 EXPORT_PC() 14485 mov r0, rPC @ arg0 14486 mov r1, rFP @ arg1 14487 mov r2, rSELF @ arg2 14488 b dvmCheckBefore @ (dPC,dFP,self) tail call 14489 14490/* ------------------------------ */ 14491 .balign 64 14492.L_ALT_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 14493/* File: armv5te/alt_stub.S */ 14494/* 14495 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14496 * any interesting requests and then jump to the real instruction 14497 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14498 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14499 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14500 * bail to the real handler if breakFlags==0. 14501 */ 14502 ldrb r3, [rSELF, #offThread_breakFlags] 14503 adrl lr, dvmAsmInstructionStart + (206 * 64) 14504 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14505 cmp r3, #0 14506 bxeq lr @ nothing to do - jump to real handler 14507 EXPORT_PC() 14508 mov r0, rPC @ arg0 14509 mov r1, rFP @ arg1 14510 mov r2, rSELF @ arg2 14511 b dvmCheckBefore @ (dPC,dFP,self) tail call 14512 14513/* ------------------------------ */ 14514 .balign 64 14515.L_ALT_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 14516/* File: armv5te/alt_stub.S */ 14517/* 14518 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14519 * any interesting requests and then jump to the real instruction 14520 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14521 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14522 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14523 * bail to the real handler if breakFlags==0. 14524 */ 14525 ldrb r3, [rSELF, #offThread_breakFlags] 14526 adrl lr, dvmAsmInstructionStart + (207 * 64) 14527 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14528 cmp r3, #0 14529 bxeq lr @ nothing to do - jump to real handler 14530 EXPORT_PC() 14531 mov r0, rPC @ arg0 14532 mov r1, rFP @ arg1 14533 mov r2, rSELF @ arg2 14534 b dvmCheckBefore @ (dPC,dFP,self) tail call 14535 14536/* ------------------------------ */ 14537 .balign 64 14538.L_ALT_OP_ADD_INT_LIT16: /* 0xd0 */ 14539/* File: armv5te/alt_stub.S */ 14540/* 14541 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14542 * any interesting requests and then jump to the real instruction 14543 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14544 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14545 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14546 * bail to the real handler if breakFlags==0. 14547 */ 14548 ldrb r3, [rSELF, #offThread_breakFlags] 14549 adrl lr, dvmAsmInstructionStart + (208 * 64) 14550 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14551 cmp r3, #0 14552 bxeq lr @ nothing to do - jump to real handler 14553 EXPORT_PC() 14554 mov r0, rPC @ arg0 14555 mov r1, rFP @ arg1 14556 mov r2, rSELF @ arg2 14557 b dvmCheckBefore @ (dPC,dFP,self) tail call 14558 14559/* ------------------------------ */ 14560 .balign 64 14561.L_ALT_OP_RSUB_INT: /* 0xd1 */ 14562/* File: armv5te/alt_stub.S */ 14563/* 14564 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14565 * any interesting requests and then jump to the real instruction 14566 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14567 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14568 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14569 * bail to the real handler if breakFlags==0. 14570 */ 14571 ldrb r3, [rSELF, #offThread_breakFlags] 14572 adrl lr, dvmAsmInstructionStart + (209 * 64) 14573 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14574 cmp r3, #0 14575 bxeq lr @ nothing to do - jump to real handler 14576 EXPORT_PC() 14577 mov r0, rPC @ arg0 14578 mov r1, rFP @ arg1 14579 mov r2, rSELF @ arg2 14580 b dvmCheckBefore @ (dPC,dFP,self) tail call 14581 14582/* ------------------------------ */ 14583 .balign 64 14584.L_ALT_OP_MUL_INT_LIT16: /* 0xd2 */ 14585/* File: armv5te/alt_stub.S */ 14586/* 14587 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14588 * any interesting requests and then jump to the real instruction 14589 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14590 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14591 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14592 * bail to the real handler if breakFlags==0. 14593 */ 14594 ldrb r3, [rSELF, #offThread_breakFlags] 14595 adrl lr, dvmAsmInstructionStart + (210 * 64) 14596 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14597 cmp r3, #0 14598 bxeq lr @ nothing to do - jump to real handler 14599 EXPORT_PC() 14600 mov r0, rPC @ arg0 14601 mov r1, rFP @ arg1 14602 mov r2, rSELF @ arg2 14603 b dvmCheckBefore @ (dPC,dFP,self) tail call 14604 14605/* ------------------------------ */ 14606 .balign 64 14607.L_ALT_OP_DIV_INT_LIT16: /* 0xd3 */ 14608/* File: armv5te/alt_stub.S */ 14609/* 14610 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14611 * any interesting requests and then jump to the real instruction 14612 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14613 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14614 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14615 * bail to the real handler if breakFlags==0. 14616 */ 14617 ldrb r3, [rSELF, #offThread_breakFlags] 14618 adrl lr, dvmAsmInstructionStart + (211 * 64) 14619 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14620 cmp r3, #0 14621 bxeq lr @ nothing to do - jump to real handler 14622 EXPORT_PC() 14623 mov r0, rPC @ arg0 14624 mov r1, rFP @ arg1 14625 mov r2, rSELF @ arg2 14626 b dvmCheckBefore @ (dPC,dFP,self) tail call 14627 14628/* ------------------------------ */ 14629 .balign 64 14630.L_ALT_OP_REM_INT_LIT16: /* 0xd4 */ 14631/* File: armv5te/alt_stub.S */ 14632/* 14633 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14634 * any interesting requests and then jump to the real instruction 14635 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14636 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14637 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14638 * bail to the real handler if breakFlags==0. 14639 */ 14640 ldrb r3, [rSELF, #offThread_breakFlags] 14641 adrl lr, dvmAsmInstructionStart + (212 * 64) 14642 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14643 cmp r3, #0 14644 bxeq lr @ nothing to do - jump to real handler 14645 EXPORT_PC() 14646 mov r0, rPC @ arg0 14647 mov r1, rFP @ arg1 14648 mov r2, rSELF @ arg2 14649 b dvmCheckBefore @ (dPC,dFP,self) tail call 14650 14651/* ------------------------------ */ 14652 .balign 64 14653.L_ALT_OP_AND_INT_LIT16: /* 0xd5 */ 14654/* File: armv5te/alt_stub.S */ 14655/* 14656 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14657 * any interesting requests and then jump to the real instruction 14658 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14659 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14660 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14661 * bail to the real handler if breakFlags==0. 14662 */ 14663 ldrb r3, [rSELF, #offThread_breakFlags] 14664 adrl lr, dvmAsmInstructionStart + (213 * 64) 14665 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14666 cmp r3, #0 14667 bxeq lr @ nothing to do - jump to real handler 14668 EXPORT_PC() 14669 mov r0, rPC @ arg0 14670 mov r1, rFP @ arg1 14671 mov r2, rSELF @ arg2 14672 b dvmCheckBefore @ (dPC,dFP,self) tail call 14673 14674/* ------------------------------ */ 14675 .balign 64 14676.L_ALT_OP_OR_INT_LIT16: /* 0xd6 */ 14677/* File: armv5te/alt_stub.S */ 14678/* 14679 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14680 * any interesting requests and then jump to the real instruction 14681 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14682 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14683 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14684 * bail to the real handler if breakFlags==0. 14685 */ 14686 ldrb r3, [rSELF, #offThread_breakFlags] 14687 adrl lr, dvmAsmInstructionStart + (214 * 64) 14688 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14689 cmp r3, #0 14690 bxeq lr @ nothing to do - jump to real handler 14691 EXPORT_PC() 14692 mov r0, rPC @ arg0 14693 mov r1, rFP @ arg1 14694 mov r2, rSELF @ arg2 14695 b dvmCheckBefore @ (dPC,dFP,self) tail call 14696 14697/* ------------------------------ */ 14698 .balign 64 14699.L_ALT_OP_XOR_INT_LIT16: /* 0xd7 */ 14700/* File: armv5te/alt_stub.S */ 14701/* 14702 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14703 * any interesting requests and then jump to the real instruction 14704 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14705 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14706 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14707 * bail to the real handler if breakFlags==0. 14708 */ 14709 ldrb r3, [rSELF, #offThread_breakFlags] 14710 adrl lr, dvmAsmInstructionStart + (215 * 64) 14711 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14712 cmp r3, #0 14713 bxeq lr @ nothing to do - jump to real handler 14714 EXPORT_PC() 14715 mov r0, rPC @ arg0 14716 mov r1, rFP @ arg1 14717 mov r2, rSELF @ arg2 14718 b dvmCheckBefore @ (dPC,dFP,self) tail call 14719 14720/* ------------------------------ */ 14721 .balign 64 14722.L_ALT_OP_ADD_INT_LIT8: /* 0xd8 */ 14723/* File: armv5te/alt_stub.S */ 14724/* 14725 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14726 * any interesting requests and then jump to the real instruction 14727 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14728 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14729 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14730 * bail to the real handler if breakFlags==0. 14731 */ 14732 ldrb r3, [rSELF, #offThread_breakFlags] 14733 adrl lr, dvmAsmInstructionStart + (216 * 64) 14734 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14735 cmp r3, #0 14736 bxeq lr @ nothing to do - jump to real handler 14737 EXPORT_PC() 14738 mov r0, rPC @ arg0 14739 mov r1, rFP @ arg1 14740 mov r2, rSELF @ arg2 14741 b dvmCheckBefore @ (dPC,dFP,self) tail call 14742 14743/* ------------------------------ */ 14744 .balign 64 14745.L_ALT_OP_RSUB_INT_LIT8: /* 0xd9 */ 14746/* File: armv5te/alt_stub.S */ 14747/* 14748 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14749 * any interesting requests and then jump to the real instruction 14750 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14751 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14752 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14753 * bail to the real handler if breakFlags==0. 14754 */ 14755 ldrb r3, [rSELF, #offThread_breakFlags] 14756 adrl lr, dvmAsmInstructionStart + (217 * 64) 14757 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14758 cmp r3, #0 14759 bxeq lr @ nothing to do - jump to real handler 14760 EXPORT_PC() 14761 mov r0, rPC @ arg0 14762 mov r1, rFP @ arg1 14763 mov r2, rSELF @ arg2 14764 b dvmCheckBefore @ (dPC,dFP,self) tail call 14765 14766/* ------------------------------ */ 14767 .balign 64 14768.L_ALT_OP_MUL_INT_LIT8: /* 0xda */ 14769/* File: armv5te/alt_stub.S */ 14770/* 14771 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14772 * any interesting requests and then jump to the real instruction 14773 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14774 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14775 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14776 * bail to the real handler if breakFlags==0. 14777 */ 14778 ldrb r3, [rSELF, #offThread_breakFlags] 14779 adrl lr, dvmAsmInstructionStart + (218 * 64) 14780 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14781 cmp r3, #0 14782 bxeq lr @ nothing to do - jump to real handler 14783 EXPORT_PC() 14784 mov r0, rPC @ arg0 14785 mov r1, rFP @ arg1 14786 mov r2, rSELF @ arg2 14787 b dvmCheckBefore @ (dPC,dFP,self) tail call 14788 14789/* ------------------------------ */ 14790 .balign 64 14791.L_ALT_OP_DIV_INT_LIT8: /* 0xdb */ 14792/* File: armv5te/alt_stub.S */ 14793/* 14794 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14795 * any interesting requests and then jump to the real instruction 14796 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14797 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14798 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14799 * bail to the real handler if breakFlags==0. 14800 */ 14801 ldrb r3, [rSELF, #offThread_breakFlags] 14802 adrl lr, dvmAsmInstructionStart + (219 * 64) 14803 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14804 cmp r3, #0 14805 bxeq lr @ nothing to do - jump to real handler 14806 EXPORT_PC() 14807 mov r0, rPC @ arg0 14808 mov r1, rFP @ arg1 14809 mov r2, rSELF @ arg2 14810 b dvmCheckBefore @ (dPC,dFP,self) tail call 14811 14812/* ------------------------------ */ 14813 .balign 64 14814.L_ALT_OP_REM_INT_LIT8: /* 0xdc */ 14815/* File: armv5te/alt_stub.S */ 14816/* 14817 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14818 * any interesting requests and then jump to the real instruction 14819 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14820 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14821 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14822 * bail to the real handler if breakFlags==0. 14823 */ 14824 ldrb r3, [rSELF, #offThread_breakFlags] 14825 adrl lr, dvmAsmInstructionStart + (220 * 64) 14826 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14827 cmp r3, #0 14828 bxeq lr @ nothing to do - jump to real handler 14829 EXPORT_PC() 14830 mov r0, rPC @ arg0 14831 mov r1, rFP @ arg1 14832 mov r2, rSELF @ arg2 14833 b dvmCheckBefore @ (dPC,dFP,self) tail call 14834 14835/* ------------------------------ */ 14836 .balign 64 14837.L_ALT_OP_AND_INT_LIT8: /* 0xdd */ 14838/* File: armv5te/alt_stub.S */ 14839/* 14840 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14841 * any interesting requests and then jump to the real instruction 14842 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14843 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14844 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14845 * bail to the real handler if breakFlags==0. 14846 */ 14847 ldrb r3, [rSELF, #offThread_breakFlags] 14848 adrl lr, dvmAsmInstructionStart + (221 * 64) 14849 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14850 cmp r3, #0 14851 bxeq lr @ nothing to do - jump to real handler 14852 EXPORT_PC() 14853 mov r0, rPC @ arg0 14854 mov r1, rFP @ arg1 14855 mov r2, rSELF @ arg2 14856 b dvmCheckBefore @ (dPC,dFP,self) tail call 14857 14858/* ------------------------------ */ 14859 .balign 64 14860.L_ALT_OP_OR_INT_LIT8: /* 0xde */ 14861/* File: armv5te/alt_stub.S */ 14862/* 14863 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14864 * any interesting requests and then jump to the real instruction 14865 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14866 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14867 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14868 * bail to the real handler if breakFlags==0. 14869 */ 14870 ldrb r3, [rSELF, #offThread_breakFlags] 14871 adrl lr, dvmAsmInstructionStart + (222 * 64) 14872 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14873 cmp r3, #0 14874 bxeq lr @ nothing to do - jump to real handler 14875 EXPORT_PC() 14876 mov r0, rPC @ arg0 14877 mov r1, rFP @ arg1 14878 mov r2, rSELF @ arg2 14879 b dvmCheckBefore @ (dPC,dFP,self) tail call 14880 14881/* ------------------------------ */ 14882 .balign 64 14883.L_ALT_OP_XOR_INT_LIT8: /* 0xdf */ 14884/* File: armv5te/alt_stub.S */ 14885/* 14886 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14887 * any interesting requests and then jump to the real instruction 14888 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14889 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14890 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14891 * bail to the real handler if breakFlags==0. 14892 */ 14893 ldrb r3, [rSELF, #offThread_breakFlags] 14894 adrl lr, dvmAsmInstructionStart + (223 * 64) 14895 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14896 cmp r3, #0 14897 bxeq lr @ nothing to do - jump to real handler 14898 EXPORT_PC() 14899 mov r0, rPC @ arg0 14900 mov r1, rFP @ arg1 14901 mov r2, rSELF @ arg2 14902 b dvmCheckBefore @ (dPC,dFP,self) tail call 14903 14904/* ------------------------------ */ 14905 .balign 64 14906.L_ALT_OP_SHL_INT_LIT8: /* 0xe0 */ 14907/* File: armv5te/alt_stub.S */ 14908/* 14909 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14910 * any interesting requests and then jump to the real instruction 14911 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14912 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14913 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14914 * bail to the real handler if breakFlags==0. 14915 */ 14916 ldrb r3, [rSELF, #offThread_breakFlags] 14917 adrl lr, dvmAsmInstructionStart + (224 * 64) 14918 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14919 cmp r3, #0 14920 bxeq lr @ nothing to do - jump to real handler 14921 EXPORT_PC() 14922 mov r0, rPC @ arg0 14923 mov r1, rFP @ arg1 14924 mov r2, rSELF @ arg2 14925 b dvmCheckBefore @ (dPC,dFP,self) tail call 14926 14927/* ------------------------------ */ 14928 .balign 64 14929.L_ALT_OP_SHR_INT_LIT8: /* 0xe1 */ 14930/* File: armv5te/alt_stub.S */ 14931/* 14932 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14933 * any interesting requests and then jump to the real instruction 14934 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14935 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14936 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14937 * bail to the real handler if breakFlags==0. 14938 */ 14939 ldrb r3, [rSELF, #offThread_breakFlags] 14940 adrl lr, dvmAsmInstructionStart + (225 * 64) 14941 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14942 cmp r3, #0 14943 bxeq lr @ nothing to do - jump to real handler 14944 EXPORT_PC() 14945 mov r0, rPC @ arg0 14946 mov r1, rFP @ arg1 14947 mov r2, rSELF @ arg2 14948 b dvmCheckBefore @ (dPC,dFP,self) tail call 14949 14950/* ------------------------------ */ 14951 .balign 64 14952.L_ALT_OP_USHR_INT_LIT8: /* 0xe2 */ 14953/* File: armv5te/alt_stub.S */ 14954/* 14955 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14956 * any interesting requests and then jump to the real instruction 14957 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14958 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14959 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14960 * bail to the real handler if breakFlags==0. 14961 */ 14962 ldrb r3, [rSELF, #offThread_breakFlags] 14963 adrl lr, dvmAsmInstructionStart + (226 * 64) 14964 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14965 cmp r3, #0 14966 bxeq lr @ nothing to do - jump to real handler 14967 EXPORT_PC() 14968 mov r0, rPC @ arg0 14969 mov r1, rFP @ arg1 14970 mov r2, rSELF @ arg2 14971 b dvmCheckBefore @ (dPC,dFP,self) tail call 14972 14973/* ------------------------------ */ 14974 .balign 64 14975.L_ALT_OP_IGET_VOLATILE: /* 0xe3 */ 14976/* File: armv5te/alt_stub.S */ 14977/* 14978 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 14979 * any interesting requests and then jump to the real instruction 14980 * handler. Note that the call to dvmCheckBefore is done as a tail call. 14981 * rIBASE updates won't be seen until a refresh, and we can tell we have a 14982 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 14983 * bail to the real handler if breakFlags==0. 14984 */ 14985 ldrb r3, [rSELF, #offThread_breakFlags] 14986 adrl lr, dvmAsmInstructionStart + (227 * 64) 14987 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 14988 cmp r3, #0 14989 bxeq lr @ nothing to do - jump to real handler 14990 EXPORT_PC() 14991 mov r0, rPC @ arg0 14992 mov r1, rFP @ arg1 14993 mov r2, rSELF @ arg2 14994 b dvmCheckBefore @ (dPC,dFP,self) tail call 14995 14996/* ------------------------------ */ 14997 .balign 64 14998.L_ALT_OP_IPUT_VOLATILE: /* 0xe4 */ 14999/* File: armv5te/alt_stub.S */ 15000/* 15001 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15002 * any interesting requests and then jump to the real instruction 15003 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15004 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15005 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15006 * bail to the real handler if breakFlags==0. 15007 */ 15008 ldrb r3, [rSELF, #offThread_breakFlags] 15009 adrl lr, dvmAsmInstructionStart + (228 * 64) 15010 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15011 cmp r3, #0 15012 bxeq lr @ nothing to do - jump to real handler 15013 EXPORT_PC() 15014 mov r0, rPC @ arg0 15015 mov r1, rFP @ arg1 15016 mov r2, rSELF @ arg2 15017 b dvmCheckBefore @ (dPC,dFP,self) tail call 15018 15019/* ------------------------------ */ 15020 .balign 64 15021.L_ALT_OP_SGET_VOLATILE: /* 0xe5 */ 15022/* File: armv5te/alt_stub.S */ 15023/* 15024 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15025 * any interesting requests and then jump to the real instruction 15026 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15027 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15028 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15029 * bail to the real handler if breakFlags==0. 15030 */ 15031 ldrb r3, [rSELF, #offThread_breakFlags] 15032 adrl lr, dvmAsmInstructionStart + (229 * 64) 15033 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15034 cmp r3, #0 15035 bxeq lr @ nothing to do - jump to real handler 15036 EXPORT_PC() 15037 mov r0, rPC @ arg0 15038 mov r1, rFP @ arg1 15039 mov r2, rSELF @ arg2 15040 b dvmCheckBefore @ (dPC,dFP,self) tail call 15041 15042/* ------------------------------ */ 15043 .balign 64 15044.L_ALT_OP_SPUT_VOLATILE: /* 0xe6 */ 15045/* File: armv5te/alt_stub.S */ 15046/* 15047 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15048 * any interesting requests and then jump to the real instruction 15049 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15050 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15051 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15052 * bail to the real handler if breakFlags==0. 15053 */ 15054 ldrb r3, [rSELF, #offThread_breakFlags] 15055 adrl lr, dvmAsmInstructionStart + (230 * 64) 15056 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15057 cmp r3, #0 15058 bxeq lr @ nothing to do - jump to real handler 15059 EXPORT_PC() 15060 mov r0, rPC @ arg0 15061 mov r1, rFP @ arg1 15062 mov r2, rSELF @ arg2 15063 b dvmCheckBefore @ (dPC,dFP,self) tail call 15064 15065/* ------------------------------ */ 15066 .balign 64 15067.L_ALT_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 15068/* File: armv5te/alt_stub.S */ 15069/* 15070 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15071 * any interesting requests and then jump to the real instruction 15072 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15073 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15074 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15075 * bail to the real handler if breakFlags==0. 15076 */ 15077 ldrb r3, [rSELF, #offThread_breakFlags] 15078 adrl lr, dvmAsmInstructionStart + (231 * 64) 15079 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15080 cmp r3, #0 15081 bxeq lr @ nothing to do - jump to real handler 15082 EXPORT_PC() 15083 mov r0, rPC @ arg0 15084 mov r1, rFP @ arg1 15085 mov r2, rSELF @ arg2 15086 b dvmCheckBefore @ (dPC,dFP,self) tail call 15087 15088/* ------------------------------ */ 15089 .balign 64 15090.L_ALT_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 15091/* File: armv5te/alt_stub.S */ 15092/* 15093 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15094 * any interesting requests and then jump to the real instruction 15095 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15096 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15097 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15098 * bail to the real handler if breakFlags==0. 15099 */ 15100 ldrb r3, [rSELF, #offThread_breakFlags] 15101 adrl lr, dvmAsmInstructionStart + (232 * 64) 15102 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15103 cmp r3, #0 15104 bxeq lr @ nothing to do - jump to real handler 15105 EXPORT_PC() 15106 mov r0, rPC @ arg0 15107 mov r1, rFP @ arg1 15108 mov r2, rSELF @ arg2 15109 b dvmCheckBefore @ (dPC,dFP,self) tail call 15110 15111/* ------------------------------ */ 15112 .balign 64 15113.L_ALT_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 15114/* File: armv5te/alt_stub.S */ 15115/* 15116 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15117 * any interesting requests and then jump to the real instruction 15118 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15119 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15120 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15121 * bail to the real handler if breakFlags==0. 15122 */ 15123 ldrb r3, [rSELF, #offThread_breakFlags] 15124 adrl lr, dvmAsmInstructionStart + (233 * 64) 15125 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15126 cmp r3, #0 15127 bxeq lr @ nothing to do - jump to real handler 15128 EXPORT_PC() 15129 mov r0, rPC @ arg0 15130 mov r1, rFP @ arg1 15131 mov r2, rSELF @ arg2 15132 b dvmCheckBefore @ (dPC,dFP,self) tail call 15133 15134/* ------------------------------ */ 15135 .balign 64 15136.L_ALT_OP_SGET_WIDE_VOLATILE: /* 0xea */ 15137/* File: armv5te/alt_stub.S */ 15138/* 15139 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15140 * any interesting requests and then jump to the real instruction 15141 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15142 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15143 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15144 * bail to the real handler if breakFlags==0. 15145 */ 15146 ldrb r3, [rSELF, #offThread_breakFlags] 15147 adrl lr, dvmAsmInstructionStart + (234 * 64) 15148 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15149 cmp r3, #0 15150 bxeq lr @ nothing to do - jump to real handler 15151 EXPORT_PC() 15152 mov r0, rPC @ arg0 15153 mov r1, rFP @ arg1 15154 mov r2, rSELF @ arg2 15155 b dvmCheckBefore @ (dPC,dFP,self) tail call 15156 15157/* ------------------------------ */ 15158 .balign 64 15159.L_ALT_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 15160/* File: armv5te/alt_stub.S */ 15161/* 15162 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15163 * any interesting requests and then jump to the real instruction 15164 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15165 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15166 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15167 * bail to the real handler if breakFlags==0. 15168 */ 15169 ldrb r3, [rSELF, #offThread_breakFlags] 15170 adrl lr, dvmAsmInstructionStart + (235 * 64) 15171 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15172 cmp r3, #0 15173 bxeq lr @ nothing to do - jump to real handler 15174 EXPORT_PC() 15175 mov r0, rPC @ arg0 15176 mov r1, rFP @ arg1 15177 mov r2, rSELF @ arg2 15178 b dvmCheckBefore @ (dPC,dFP,self) tail call 15179 15180/* ------------------------------ */ 15181 .balign 64 15182.L_ALT_OP_BREAKPOINT: /* 0xec */ 15183/* File: armv5te/alt_stub.S */ 15184/* 15185 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15186 * any interesting requests and then jump to the real instruction 15187 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15188 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15189 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15190 * bail to the real handler if breakFlags==0. 15191 */ 15192 ldrb r3, [rSELF, #offThread_breakFlags] 15193 adrl lr, dvmAsmInstructionStart + (236 * 64) 15194 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15195 cmp r3, #0 15196 bxeq lr @ nothing to do - jump to real handler 15197 EXPORT_PC() 15198 mov r0, rPC @ arg0 15199 mov r1, rFP @ arg1 15200 mov r2, rSELF @ arg2 15201 b dvmCheckBefore @ (dPC,dFP,self) tail call 15202 15203/* ------------------------------ */ 15204 .balign 64 15205.L_ALT_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 15206/* File: armv5te/alt_stub.S */ 15207/* 15208 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15209 * any interesting requests and then jump to the real instruction 15210 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15211 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15212 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15213 * bail to the real handler if breakFlags==0. 15214 */ 15215 ldrb r3, [rSELF, #offThread_breakFlags] 15216 adrl lr, dvmAsmInstructionStart + (237 * 64) 15217 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15218 cmp r3, #0 15219 bxeq lr @ nothing to do - jump to real handler 15220 EXPORT_PC() 15221 mov r0, rPC @ arg0 15222 mov r1, rFP @ arg1 15223 mov r2, rSELF @ arg2 15224 b dvmCheckBefore @ (dPC,dFP,self) tail call 15225 15226/* ------------------------------ */ 15227 .balign 64 15228.L_ALT_OP_EXECUTE_INLINE: /* 0xee */ 15229/* File: armv5te/alt_stub.S */ 15230/* 15231 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15232 * any interesting requests and then jump to the real instruction 15233 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15234 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15235 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15236 * bail to the real handler if breakFlags==0. 15237 */ 15238 ldrb r3, [rSELF, #offThread_breakFlags] 15239 adrl lr, dvmAsmInstructionStart + (238 * 64) 15240 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15241 cmp r3, #0 15242 bxeq lr @ nothing to do - jump to real handler 15243 EXPORT_PC() 15244 mov r0, rPC @ arg0 15245 mov r1, rFP @ arg1 15246 mov r2, rSELF @ arg2 15247 b dvmCheckBefore @ (dPC,dFP,self) tail call 15248 15249/* ------------------------------ */ 15250 .balign 64 15251.L_ALT_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 15252/* File: armv5te/alt_stub.S */ 15253/* 15254 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15255 * any interesting requests and then jump to the real instruction 15256 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15257 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15258 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15259 * bail to the real handler if breakFlags==0. 15260 */ 15261 ldrb r3, [rSELF, #offThread_breakFlags] 15262 adrl lr, dvmAsmInstructionStart + (239 * 64) 15263 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15264 cmp r3, #0 15265 bxeq lr @ nothing to do - jump to real handler 15266 EXPORT_PC() 15267 mov r0, rPC @ arg0 15268 mov r1, rFP @ arg1 15269 mov r2, rSELF @ arg2 15270 b dvmCheckBefore @ (dPC,dFP,self) tail call 15271 15272/* ------------------------------ */ 15273 .balign 64 15274.L_ALT_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */ 15275/* File: armv5te/alt_stub.S */ 15276/* 15277 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15278 * any interesting requests and then jump to the real instruction 15279 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15280 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15281 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15282 * bail to the real handler if breakFlags==0. 15283 */ 15284 ldrb r3, [rSELF, #offThread_breakFlags] 15285 adrl lr, dvmAsmInstructionStart + (240 * 64) 15286 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15287 cmp r3, #0 15288 bxeq lr @ nothing to do - jump to real handler 15289 EXPORT_PC() 15290 mov r0, rPC @ arg0 15291 mov r1, rFP @ arg1 15292 mov r2, rSELF @ arg2 15293 b dvmCheckBefore @ (dPC,dFP,self) tail call 15294 15295/* ------------------------------ */ 15296 .balign 64 15297.L_ALT_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 15298/* File: armv5te/alt_stub.S */ 15299/* 15300 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15301 * any interesting requests and then jump to the real instruction 15302 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15303 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15304 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15305 * bail to the real handler if breakFlags==0. 15306 */ 15307 ldrb r3, [rSELF, #offThread_breakFlags] 15308 adrl lr, dvmAsmInstructionStart + (241 * 64) 15309 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15310 cmp r3, #0 15311 bxeq lr @ nothing to do - jump to real handler 15312 EXPORT_PC() 15313 mov r0, rPC @ arg0 15314 mov r1, rFP @ arg1 15315 mov r2, rSELF @ arg2 15316 b dvmCheckBefore @ (dPC,dFP,self) tail call 15317 15318/* ------------------------------ */ 15319 .balign 64 15320.L_ALT_OP_IGET_QUICK: /* 0xf2 */ 15321/* File: armv5te/alt_stub.S */ 15322/* 15323 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15324 * any interesting requests and then jump to the real instruction 15325 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15326 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15327 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15328 * bail to the real handler if breakFlags==0. 15329 */ 15330 ldrb r3, [rSELF, #offThread_breakFlags] 15331 adrl lr, dvmAsmInstructionStart + (242 * 64) 15332 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15333 cmp r3, #0 15334 bxeq lr @ nothing to do - jump to real handler 15335 EXPORT_PC() 15336 mov r0, rPC @ arg0 15337 mov r1, rFP @ arg1 15338 mov r2, rSELF @ arg2 15339 b dvmCheckBefore @ (dPC,dFP,self) tail call 15340 15341/* ------------------------------ */ 15342 .balign 64 15343.L_ALT_OP_IGET_WIDE_QUICK: /* 0xf3 */ 15344/* File: armv5te/alt_stub.S */ 15345/* 15346 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15347 * any interesting requests and then jump to the real instruction 15348 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15349 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15350 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15351 * bail to the real handler if breakFlags==0. 15352 */ 15353 ldrb r3, [rSELF, #offThread_breakFlags] 15354 adrl lr, dvmAsmInstructionStart + (243 * 64) 15355 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15356 cmp r3, #0 15357 bxeq lr @ nothing to do - jump to real handler 15358 EXPORT_PC() 15359 mov r0, rPC @ arg0 15360 mov r1, rFP @ arg1 15361 mov r2, rSELF @ arg2 15362 b dvmCheckBefore @ (dPC,dFP,self) tail call 15363 15364/* ------------------------------ */ 15365 .balign 64 15366.L_ALT_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 15367/* File: armv5te/alt_stub.S */ 15368/* 15369 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15370 * any interesting requests and then jump to the real instruction 15371 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15372 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15373 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15374 * bail to the real handler if breakFlags==0. 15375 */ 15376 ldrb r3, [rSELF, #offThread_breakFlags] 15377 adrl lr, dvmAsmInstructionStart + (244 * 64) 15378 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15379 cmp r3, #0 15380 bxeq lr @ nothing to do - jump to real handler 15381 EXPORT_PC() 15382 mov r0, rPC @ arg0 15383 mov r1, rFP @ arg1 15384 mov r2, rSELF @ arg2 15385 b dvmCheckBefore @ (dPC,dFP,self) tail call 15386 15387/* ------------------------------ */ 15388 .balign 64 15389.L_ALT_OP_IPUT_QUICK: /* 0xf5 */ 15390/* File: armv5te/alt_stub.S */ 15391/* 15392 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15393 * any interesting requests and then jump to the real instruction 15394 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15395 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15396 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15397 * bail to the real handler if breakFlags==0. 15398 */ 15399 ldrb r3, [rSELF, #offThread_breakFlags] 15400 adrl lr, dvmAsmInstructionStart + (245 * 64) 15401 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15402 cmp r3, #0 15403 bxeq lr @ nothing to do - jump to real handler 15404 EXPORT_PC() 15405 mov r0, rPC @ arg0 15406 mov r1, rFP @ arg1 15407 mov r2, rSELF @ arg2 15408 b dvmCheckBefore @ (dPC,dFP,self) tail call 15409 15410/* ------------------------------ */ 15411 .balign 64 15412.L_ALT_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 15413/* File: armv5te/alt_stub.S */ 15414/* 15415 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15416 * any interesting requests and then jump to the real instruction 15417 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15418 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15419 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15420 * bail to the real handler if breakFlags==0. 15421 */ 15422 ldrb r3, [rSELF, #offThread_breakFlags] 15423 adrl lr, dvmAsmInstructionStart + (246 * 64) 15424 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15425 cmp r3, #0 15426 bxeq lr @ nothing to do - jump to real handler 15427 EXPORT_PC() 15428 mov r0, rPC @ arg0 15429 mov r1, rFP @ arg1 15430 mov r2, rSELF @ arg2 15431 b dvmCheckBefore @ (dPC,dFP,self) tail call 15432 15433/* ------------------------------ */ 15434 .balign 64 15435.L_ALT_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 15436/* File: armv5te/alt_stub.S */ 15437/* 15438 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15439 * any interesting requests and then jump to the real instruction 15440 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15441 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15442 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15443 * bail to the real handler if breakFlags==0. 15444 */ 15445 ldrb r3, [rSELF, #offThread_breakFlags] 15446 adrl lr, dvmAsmInstructionStart + (247 * 64) 15447 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15448 cmp r3, #0 15449 bxeq lr @ nothing to do - jump to real handler 15450 EXPORT_PC() 15451 mov r0, rPC @ arg0 15452 mov r1, rFP @ arg1 15453 mov r2, rSELF @ arg2 15454 b dvmCheckBefore @ (dPC,dFP,self) tail call 15455 15456/* ------------------------------ */ 15457 .balign 64 15458.L_ALT_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 15459/* File: armv5te/alt_stub.S */ 15460/* 15461 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15462 * any interesting requests and then jump to the real instruction 15463 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15464 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15465 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15466 * bail to the real handler if breakFlags==0. 15467 */ 15468 ldrb r3, [rSELF, #offThread_breakFlags] 15469 adrl lr, dvmAsmInstructionStart + (248 * 64) 15470 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15471 cmp r3, #0 15472 bxeq lr @ nothing to do - jump to real handler 15473 EXPORT_PC() 15474 mov r0, rPC @ arg0 15475 mov r1, rFP @ arg1 15476 mov r2, rSELF @ arg2 15477 b dvmCheckBefore @ (dPC,dFP,self) tail call 15478 15479/* ------------------------------ */ 15480 .balign 64 15481.L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 15482/* File: armv5te/alt_stub.S */ 15483/* 15484 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15485 * any interesting requests and then jump to the real instruction 15486 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15487 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15488 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15489 * bail to the real handler if breakFlags==0. 15490 */ 15491 ldrb r3, [rSELF, #offThread_breakFlags] 15492 adrl lr, dvmAsmInstructionStart + (249 * 64) 15493 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15494 cmp r3, #0 15495 bxeq lr @ nothing to do - jump to real handler 15496 EXPORT_PC() 15497 mov r0, rPC @ arg0 15498 mov r1, rFP @ arg1 15499 mov r2, rSELF @ arg2 15500 b dvmCheckBefore @ (dPC,dFP,self) tail call 15501 15502/* ------------------------------ */ 15503 .balign 64 15504.L_ALT_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 15505/* File: armv5te/alt_stub.S */ 15506/* 15507 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15508 * any interesting requests and then jump to the real instruction 15509 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15510 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15511 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15512 * bail to the real handler if breakFlags==0. 15513 */ 15514 ldrb r3, [rSELF, #offThread_breakFlags] 15515 adrl lr, dvmAsmInstructionStart + (250 * 64) 15516 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15517 cmp r3, #0 15518 bxeq lr @ nothing to do - jump to real handler 15519 EXPORT_PC() 15520 mov r0, rPC @ arg0 15521 mov r1, rFP @ arg1 15522 mov r2, rSELF @ arg2 15523 b dvmCheckBefore @ (dPC,dFP,self) tail call 15524 15525/* ------------------------------ */ 15526 .balign 64 15527.L_ALT_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 15528/* File: armv5te/alt_stub.S */ 15529/* 15530 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15531 * any interesting requests and then jump to the real instruction 15532 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15533 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15534 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15535 * bail to the real handler if breakFlags==0. 15536 */ 15537 ldrb r3, [rSELF, #offThread_breakFlags] 15538 adrl lr, dvmAsmInstructionStart + (251 * 64) 15539 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15540 cmp r3, #0 15541 bxeq lr @ nothing to do - jump to real handler 15542 EXPORT_PC() 15543 mov r0, rPC @ arg0 15544 mov r1, rFP @ arg1 15545 mov r2, rSELF @ arg2 15546 b dvmCheckBefore @ (dPC,dFP,self) tail call 15547 15548/* ------------------------------ */ 15549 .balign 64 15550.L_ALT_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 15551/* File: armv5te/alt_stub.S */ 15552/* 15553 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15554 * any interesting requests and then jump to the real instruction 15555 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15556 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15557 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15558 * bail to the real handler if breakFlags==0. 15559 */ 15560 ldrb r3, [rSELF, #offThread_breakFlags] 15561 adrl lr, dvmAsmInstructionStart + (252 * 64) 15562 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15563 cmp r3, #0 15564 bxeq lr @ nothing to do - jump to real handler 15565 EXPORT_PC() 15566 mov r0, rPC @ arg0 15567 mov r1, rFP @ arg1 15568 mov r2, rSELF @ arg2 15569 b dvmCheckBefore @ (dPC,dFP,self) tail call 15570 15571/* ------------------------------ */ 15572 .balign 64 15573.L_ALT_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 15574/* File: armv5te/alt_stub.S */ 15575/* 15576 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15577 * any interesting requests and then jump to the real instruction 15578 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15579 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15580 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15581 * bail to the real handler if breakFlags==0. 15582 */ 15583 ldrb r3, [rSELF, #offThread_breakFlags] 15584 adrl lr, dvmAsmInstructionStart + (253 * 64) 15585 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15586 cmp r3, #0 15587 bxeq lr @ nothing to do - jump to real handler 15588 EXPORT_PC() 15589 mov r0, rPC @ arg0 15590 mov r1, rFP @ arg1 15591 mov r2, rSELF @ arg2 15592 b dvmCheckBefore @ (dPC,dFP,self) tail call 15593 15594/* ------------------------------ */ 15595 .balign 64 15596.L_ALT_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 15597/* File: armv5te/alt_stub.S */ 15598/* 15599 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15600 * any interesting requests and then jump to the real instruction 15601 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15602 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15603 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15604 * bail to the real handler if breakFlags==0. 15605 */ 15606 ldrb r3, [rSELF, #offThread_breakFlags] 15607 adrl lr, dvmAsmInstructionStart + (254 * 64) 15608 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15609 cmp r3, #0 15610 bxeq lr @ nothing to do - jump to real handler 15611 EXPORT_PC() 15612 mov r0, rPC @ arg0 15613 mov r1, rFP @ arg1 15614 mov r2, rSELF @ arg2 15615 b dvmCheckBefore @ (dPC,dFP,self) tail call 15616 15617/* ------------------------------ */ 15618 .balign 64 15619.L_ALT_OP_UNUSED_FF: /* 0xff */ 15620/* File: armv5te/alt_stub.S */ 15621/* 15622 * Inter-instruction transfer stub. Call out to dvmCheckBefore to handle 15623 * any interesting requests and then jump to the real instruction 15624 * handler. Note that the call to dvmCheckBefore is done as a tail call. 15625 * rIBASE updates won't be seen until a refresh, and we can tell we have a 15626 * stale rIBASE if breakFlags==0. Always refresh rIBASE here, and then 15627 * bail to the real handler if breakFlags==0. 15628 */ 15629 ldrb r3, [rSELF, #offThread_breakFlags] 15630 adrl lr, dvmAsmInstructionStart + (255 * 64) 15631 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15632 cmp r3, #0 15633 bxeq lr @ nothing to do - jump to real handler 15634 EXPORT_PC() 15635 mov r0, rPC @ arg0 15636 mov r1, rFP @ arg1 15637 mov r2, rSELF @ arg2 15638 b dvmCheckBefore @ (dPC,dFP,self) tail call 15639 15640 .balign 64 15641 .size dvmAsmAltInstructionStart, .-dvmAsmAltInstructionStart 15642 .global dvmAsmAltInstructionEnd 15643dvmAsmAltInstructionEnd: 15644/* File: armv5te/footer.S */ 15645/* 15646 * =========================================================================== 15647 * Common subroutines and data 15648 * =========================================================================== 15649 */ 15650 15651 .text 15652 .align 2 15653 15654#if defined(WITH_JIT) 15655 15656#if defined(WITH_SELF_VERIFICATION) 15657/* 15658 * "longjmp" to a translation after single-stepping. Before returning 15659 * to translation, must save state for self-verification. 15660 */ 15661 .global dvmJitResumeTranslation @ (Thread* self, u4* dFP) 15662dvmJitResumeTranslation: 15663 mov rSELF, r0 @ restore self 15664 mov rPC, r1 @ restore Dalvik pc 15665 mov rFP, r2 @ restore Dalvik fp 15666 ldr r10, [rSELF,#offThread_jitResumeNPC] @ resume address 15667 mov r2, #0 15668 str r2, [rSELF,#offThread_jitResumeNPC] @ reset resume address 15669 ldr sp, [rSELF,#offThread_jitResumeNSP] @ cut back native stack 15670 b jitSVShadowRunStart @ resume as if cache hit 15671 @ expects resume addr in r10 15672 15673 .global dvmJitToInterpPunt 15674dvmJitToInterpPunt: 15675 mov r2,#kSVSPunt @ r2<- interpreter entry point 15676 mov r3, #0 15677 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15678 b jitSVShadowRunEnd @ doesn't return 15679 15680 .global dvmJitToInterpSingleStep 15681dvmJitToInterpSingleStep: 15682 mov rPC, r0 @ set up dalvik pc 15683 EXPORT_PC() 15684 str lr, [rSELF,#offThread_jitResumeNPC] 15685 str sp, [rSELF,#offThread_jitResumeNSP] 15686 str r1, [rSELF,#offThread_jitResumeDPC] 15687 mov r2,#kSVSSingleStep @ r2<- interpreter entry point 15688 b jitSVShadowRunEnd @ doesn't return 15689 15690 15691 .global dvmJitToInterpNoChainNoProfile 15692dvmJitToInterpNoChainNoProfile: 15693 mov r0,rPC @ pass our target PC 15694 mov r2,#kSVSNoProfile @ r2<- interpreter entry point 15695 mov r3, #0 @ 0 means !inJitCodeCache 15696 str r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 15697 b jitSVShadowRunEnd @ doesn't return 15698 15699 .global dvmJitToInterpTraceSelectNoChain 15700dvmJitToInterpTraceSelectNoChain: 15701 mov r0,rPC @ pass our target PC 15702 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 15703 mov r3, #0 @ 0 means !inJitCodeCache 15704 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15705 b jitSVShadowRunEnd @ doesn't return 15706 15707 .global dvmJitToInterpTraceSelect 15708dvmJitToInterpTraceSelect: 15709 ldr r0,[lr, #-1] @ pass our target PC 15710 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 15711 mov r3, #0 @ 0 means !inJitCodeCache 15712 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15713 b jitSVShadowRunEnd @ doesn't return 15714 15715 .global dvmJitToInterpBackwardBranch 15716dvmJitToInterpBackwardBranch: 15717 ldr r0,[lr, #-1] @ pass our target PC 15718 mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point 15719 mov r3, #0 @ 0 means !inJitCodeCache 15720 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15721 b jitSVShadowRunEnd @ doesn't return 15722 15723 .global dvmJitToInterpNormal 15724dvmJitToInterpNormal: 15725 ldr r0,[lr, #-1] @ pass our target PC 15726 mov r2,#kSVSNormal @ r2<- interpreter entry point 15727 mov r3, #0 @ 0 means !inJitCodeCache 15728 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15729 b jitSVShadowRunEnd @ doesn't return 15730 15731 .global dvmJitToInterpNoChain 15732dvmJitToInterpNoChain: 15733 mov r0,rPC @ pass our target PC 15734 mov r2,#kSVSNoChain @ r2<- interpreter entry point 15735 mov r3, #0 @ 0 means !inJitCodeCache 15736 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15737 b jitSVShadowRunEnd @ doesn't return 15738#else 15739 15740/* 15741 * "longjmp" to a translation after single-stepping. 15742 */ 15743 .global dvmJitResumeTranslation @ (Thread* self, u4* dFP) 15744dvmJitResumeTranslation: 15745 mov rSELF, r0 @ restore self 15746 mov rPC, r1 @ restore Dalvik pc 15747 mov rFP, r2 @ restore Dalvik fp 15748 ldr r0, [rSELF,#offThread_jitResumeNPC] 15749 mov r2, #0 15750 str r2, [rSELF,#offThread_jitResumeNPC] @ reset resume address 15751 ldr sp, [rSELF,#offThread_jitResumeNSP] @ cut back native stack 15752 bx r0 @ resume translation 15753 15754/* 15755 * Return from the translation cache to the interpreter when the compiler is 15756 * having issues translating/executing a Dalvik instruction. We have to skip 15757 * the code cache lookup otherwise it is possible to indefinitely bouce 15758 * between the interpreter and the code cache if the instruction that fails 15759 * to be compiled happens to be at a trace start. 15760 */ 15761 .global dvmJitToInterpPunt 15762dvmJitToInterpPunt: 15763 mov rPC, r0 15764#if defined(WITH_JIT_TUNING) 15765 mov r0,lr 15766 bl dvmBumpPunt; 15767#endif 15768 EXPORT_PC() 15769 mov r0, #0 15770 str r0, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 15771 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15772 FETCH_INST() 15773 GET_INST_OPCODE(ip) 15774 GOTO_OPCODE(ip) 15775 15776/* 15777 * Return to the interpreter to handle a single instruction. 15778 * We'll use the normal single-stepping mechanism via interpBreak, 15779 * but also save the native pc of the resume point in the translation 15780 * and the native sp so that we can later do the equivalent of a 15781 * longjmp() to resume. 15782 * On entry: 15783 * dPC <= Dalvik PC of instrucion to interpret 15784 * lr <= resume point in translation 15785 * r1 <= Dalvik PC of next instruction 15786 */ 15787 .global dvmJitToInterpSingleStep 15788dvmJitToInterpSingleStep: 15789 mov rPC, r0 @ set up dalvik pc 15790 EXPORT_PC() 15791 str lr, [rSELF,#offThread_jitResumeNPC] 15792 str sp, [rSELF,#offThread_jitResumeNSP] 15793 str r1, [rSELF,#offThread_jitResumeDPC] 15794 mov r1, #1 15795 str r1, [rSELF,#offThread_singleStepCount] @ just step once 15796 mov r0, rSELF 15797 mov r1, #kSubModeCountedStep 15798 bl dvmEnableSubMode @ (self, newMode) 15799 ldr rIBASE, [rSELF,#offThread_curHandlerTable] 15800 FETCH_INST() 15801 GET_INST_OPCODE(ip) 15802 GOTO_OPCODE(ip) 15803 15804/* 15805 * Return from the translation cache and immediately request 15806 * a translation for the exit target. Commonly used for callees. 15807 */ 15808 .global dvmJitToInterpTraceSelectNoChain 15809dvmJitToInterpTraceSelectNoChain: 15810#if defined(WITH_JIT_TUNING) 15811 bl dvmBumpNoChain 15812#endif 15813 mov r0,rPC 15814 mov r1,rSELF 15815 bl dvmJitGetTraceAddrThread @ (pc, self) 15816 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15817 mov r1, rPC @ arg1 of translation may need this 15818 mov lr, #0 @ in case target is HANDLER_INTERPRET 15819 cmp r0,#0 @ !0 means translation exists 15820 bxne r0 @ continue native execution if so 15821 b 2f @ branch over to use the interpreter 15822 15823/* 15824 * Return from the translation cache and immediately request 15825 * a translation for the exit target. Commonly used following 15826 * invokes. 15827 */ 15828 .global dvmJitToInterpTraceSelect 15829dvmJitToInterpTraceSelect: 15830 ldr rPC,[lr, #-1] @ get our target PC 15831 add rINST,lr,#-5 @ save start of chain branch 15832 add rINST, #-4 @ .. which is 9 bytes back 15833 mov r0,rPC 15834 mov r1,rSELF 15835 bl dvmJitGetTraceAddrThread @ (pc, self) 15836 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15837 cmp r0,#0 15838 beq 2f 15839 mov r1,rINST 15840 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 15841 mov r1, rPC @ arg1 of translation may need this 15842 mov lr, #0 @ in case target is HANDLER_INTERPRET 15843 cmp r0,#0 @ successful chain? 15844 bxne r0 @ continue native execution 15845 b toInterpreter @ didn't chain - resume with interpreter 15846 15847/* No translation, so request one if profiling isn't disabled*/ 158482: 15849 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15850 ldr r0, [rSELF, #offThread_pJitProfTable] 15851 FETCH_INST() 15852 cmp r0, #0 15853 movne r2,#kJitTSelectRequestHot @ ask for trace selection 15854 bne common_selectTrace 15855 GET_INST_OPCODE(ip) 15856 GOTO_OPCODE(ip) 15857 15858/* 15859 * Return from the translation cache to the interpreter. 15860 * The return was done with a BLX from thumb mode, and 15861 * the following 32-bit word contains the target rPC value. 15862 * Note that lr (r14) will have its low-order bit set to denote 15863 * its thumb-mode origin. 15864 * 15865 * We'll need to stash our lr origin away, recover the new 15866 * target and then check to see if there is a translation available 15867 * for our new target. If so, we do a translation chain and 15868 * go back to native execution. Otherwise, it's back to the 15869 * interpreter (after treating this entry as a potential 15870 * trace start). 15871 */ 15872 .global dvmJitToInterpNormal 15873dvmJitToInterpNormal: 15874 ldr rPC,[lr, #-1] @ get our target PC 15875 add rINST,lr,#-5 @ save start of chain branch 15876 add rINST,#-4 @ .. which is 9 bytes back 15877#if defined(WITH_JIT_TUNING) 15878 bl dvmBumpNormal 15879#endif 15880 mov r0,rPC 15881 mov r1,rSELF 15882 bl dvmJitGetTraceAddrThread @ (pc, self) 15883 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15884 cmp r0,#0 15885 beq toInterpreter @ go if not, otherwise do chain 15886 mov r1,rINST 15887 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 15888 mov r1, rPC @ arg1 of translation may need this 15889 mov lr, #0 @ in case target is HANDLER_INTERPRET 15890 cmp r0,#0 @ successful chain? 15891 bxne r0 @ continue native execution 15892 b toInterpreter @ didn't chain - resume with interpreter 15893 15894/* 15895 * Return from the translation cache to the interpreter to do method invocation. 15896 * Check if translation exists for the callee, but don't chain to it. 15897 */ 15898 .global dvmJitToInterpNoChainNoProfile 15899dvmJitToInterpNoChainNoProfile: 15900#if defined(WITH_JIT_TUNING) 15901 bl dvmBumpNoChain 15902#endif 15903 mov r0,rPC 15904 mov r1,rSELF 15905 bl dvmJitGetTraceAddrThread @ (pc, self) 15906 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15907 mov r1, rPC @ arg1 of translation may need this 15908 mov lr, #0 @ in case target is HANDLER_INTERPRET 15909 cmp r0,#0 15910 bxne r0 @ continue native execution if so 15911 EXPORT_PC() 15912 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15913 FETCH_INST() 15914 GET_INST_OPCODE(ip) @ extract opcode from rINST 15915 GOTO_OPCODE(ip) @ jump to next instruction 15916 15917/* 15918 * Return from the translation cache to the interpreter to do method invocation. 15919 * Check if translation exists for the callee, but don't chain to it. 15920 */ 15921 .global dvmJitToInterpNoChain 15922dvmJitToInterpNoChain: 15923#if defined(WITH_JIT_TUNING) 15924 bl dvmBumpNoChain 15925#endif 15926 mov r0,rPC 15927 mov r1,rSELF 15928 bl dvmJitGetTraceAddrThread @ (pc, self) 15929 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15930 mov r1, rPC @ arg1 of translation may need this 15931 mov lr, #0 @ in case target is HANDLER_INTERPRET 15932 cmp r0,#0 15933 bxne r0 @ continue native execution if so 15934#endif 15935 15936/* 15937 * No translation, restore interpreter regs and start interpreting. 15938 * rSELF & rFP were preserved in the translated code, and rPC has 15939 * already been restored by the time we get here. We'll need to set 15940 * up rIBASE & rINST, and load the address of the JitTable into r0. 15941 */ 15942toInterpreter: 15943 EXPORT_PC() 15944 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15945 FETCH_INST() 15946 ldr r0, [rSELF, #offThread_pJitProfTable] 15947 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 15948 @ NOTE: intended fallthrough 15949 15950/* 15951 * Similar to common_updateProfile, but tests for null pJitProfTable 15952 * r0 holds pJifProfTAble, rINST is loaded, rPC is current and 15953 * rIBASE has been recently refreshed. 15954 */ 15955common_testUpdateProfile: 15956 cmp r0, #0 @ JIT switched off? 15957 beq 4f @ return to interp if so 15958 15959/* 15960 * Common code to update potential trace start counter, and initiate 15961 * a trace-build if appropriate. 15962 * On entry here: 15963 * r0 <= pJitProfTable (verified non-NULL) 15964 * rPC <= Dalvik PC 15965 * rINST <= next instruction 15966 */ 15967common_updateProfile: 15968 eor r3,rPC,rPC,lsr #12 @ cheap, but fast hash function 15969 lsl r3,r3,#(32 - JIT_PROF_SIZE_LOG_2) @ shift out excess bits 15970 ldrb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter 15971 GET_INST_OPCODE(ip) 15972 subs r1,r1,#1 @ decrement counter 15973 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it 15974 GOTO_OPCODE_IFNE(ip) @ if not threshold, fallthrough otherwise */ 15975 15976 /* Looks good, reset the counter */ 15977 ldr r1, [rSELF, #offThread_jitThreshold] 15978 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter 15979 EXPORT_PC() 15980 mov r0,rPC 15981 mov r1,rSELF 15982 bl dvmJitGetTraceAddrThread @ (pc, self) 15983 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 15984 mov r1, rPC @ arg1 of translation may need this 15985 mov lr, #0 @ in case target is HANDLER_INTERPRET 15986 cmp r0,#0 15987#if !defined(WITH_SELF_VERIFICATION) 15988 bxne r0 @ jump to the translation 15989 mov r2,#kJitTSelectRequest @ ask for trace selection 15990 @ fall-through to common_selectTrace 15991#else 15992 moveq r2,#kJitTSelectRequest @ ask for trace selection 15993 beq common_selectTrace 15994 /* 15995 * At this point, we have a target translation. However, if 15996 * that translation is actually the interpret-only pseudo-translation 15997 * we want to treat it the same as no translation. 15998 */ 15999 mov r10, r0 @ save target 16000 bl dvmCompilerGetInterpretTemplate 16001 cmp r0, r10 @ special case? 16002 bne jitSVShadowRunStart @ set up self verification shadow space 16003 @ Need to clear the inJitCodeCache flag 16004 mov r3, #0 @ 0 means not in the JIT code cache 16005 str r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 16006 GET_INST_OPCODE(ip) 16007 GOTO_OPCODE(ip) 16008 /* no return */ 16009#endif 16010 16011/* 16012 * On entry: 16013 * r2 is jit state. 16014 */ 16015common_selectTrace: 16016 ldrh r0,[rSELF,#offThread_subMode] 16017 ands r0, #(kSubModeJitTraceBuild | kSubModeJitSV) 16018 bne 3f @ already doing JIT work, continue 16019 str r2,[rSELF,#offThread_jitState] 16020 mov r0, rSELF 16021/* 16022 * Call out to validate trace-building request. If successful, 16023 * rIBASE will be swapped to to send us into single-stepping trace 16024 * building mode, so we need to refresh before we continue. 16025 */ 16026 EXPORT_PC() 16027 SAVE_PC_FP_TO_SELF() @ copy of pc/fp to Thread 16028 bl dvmJitCheckTraceRequest 160293: 16030 FETCH_INST() 16031 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 160324: 16033 GET_INST_OPCODE(ip) @ extract opcode from rINST 16034 GOTO_OPCODE(ip) 16035 /* no return */ 16036#endif 16037 16038#if defined(WITH_SELF_VERIFICATION) 16039/* 16040 * Save PC and registers to shadow memory for self verification mode 16041 * before jumping to native translation. 16042 * On entry: 16043 * rPC, rFP, rSELF: the values that they should contain 16044 * r10: the address of the target translation. 16045 */ 16046jitSVShadowRunStart: 16047 mov r0,rPC @ r0<- program counter 16048 mov r1,rFP @ r1<- frame pointer 16049 mov r2,rSELF @ r2<- self (Thread) pointer 16050 mov r3,r10 @ r3<- target translation 16051 bl dvmSelfVerificationSaveState @ save registers to shadow space 16052 ldr rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space 16053 bx r10 @ jump to the translation 16054 16055/* 16056 * Restore PC, registers, and interpreter state to original values 16057 * before jumping back to the interpreter. 16058 * On entry: 16059 * r0: dPC 16060 * r2: self verification state 16061 */ 16062jitSVShadowRunEnd: 16063 mov r1,rFP @ pass ending fp 16064 mov r3,rSELF @ pass self ptr for convenience 16065 bl dvmSelfVerificationRestoreState @ restore pc and fp values 16066 LOAD_PC_FP_FROM_SELF() @ restore pc, fp 16067 ldr r1,[r0,#offShadowSpace_svState] @ get self verification state 16068 cmp r1,#0 @ check for punt condition 16069 beq 1f 16070 @ Set up SV single-stepping 16071 mov r0, rSELF 16072 mov r1, #kSubModeJitSV 16073 bl dvmEnableSubMode @ (self, subMode) 16074 mov r2,#kJitSelfVerification @ ask for self verification 16075 str r2,[rSELF,#offThread_jitState] 16076 @ intentional fallthrough 160771: @ exit to interpreter without check 16078 EXPORT_PC() 16079 ldr rIBASE, [rSELF, #offThread_curHandlerTable] 16080 FETCH_INST() 16081 GET_INST_OPCODE(ip) 16082 GOTO_OPCODE(ip) 16083#endif 16084 16085/* 16086 * The equivalent of "goto bail", this calls through the "bail handler". 16087 * It will end this interpreter activation, and return to the caller 16088 * of dvmMterpStdRun. 16089 * 16090 * State registers will be saved to the "thread" area before bailing 16091 * debugging purposes 16092 */ 16093common_gotoBail: 16094 SAVE_PC_FP_TO_SELF() @ export state to "thread" 16095 mov r0, rSELF @ r0<- self ptr 16096 b dvmMterpStdBail @ call(self, changeInterp) 16097 16098/* 16099 * The JIT's invoke method needs to remember the callsite class and 16100 * target pair. Save them here so that they are available to 16101 * dvmCheckJit following the interpretation of this invoke. 16102 */ 16103#if defined(WITH_JIT) 16104save_callsiteinfo: 16105 cmp r9, #0 16106 ldrne r9, [r9, #offObject_clazz] 16107 str r0, [rSELF, #offThread_methodToCall] 16108 str r9, [rSELF, #offThread_callsiteClass] 16109 bx lr 16110#endif 16111 16112/* 16113 * Common code for method invocation with range. 16114 * 16115 * On entry: 16116 * r0 is "Method* methodToCall", r9 is "this" 16117 */ 16118common_invokeMethodRange: 16119.LinvokeNewRange: 16120#if defined(WITH_JIT) 16121 ldrh r1, [rSELF, #offThread_subMode] 16122 ands r1, #kSubModeJitTraceBuild 16123 blne save_callsiteinfo 16124#endif 16125 @ prepare to copy args to "outs" area of current frame 16126 movs r2, rINST, lsr #8 @ r2<- AA (arg count) -- test for zero 16127 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 16128 beq .LinvokeArgsDone @ if no args, skip the rest 16129 FETCH(r1, 2) @ r1<- CCCC 16130 16131.LinvokeRangeArgs: 16132 @ r0=methodToCall, r1=CCCC, r2=count, r10=outs 16133 @ (very few methods have > 10 args; could unroll for common cases) 16134 add r3, rFP, r1, lsl #2 @ r3<- &fp[CCCC] 16135 sub r10, r10, r2, lsl #2 @ r10<- "outs" area, for call args 161361: ldr r1, [r3], #4 @ val = *fp++ 16137 subs r2, r2, #1 @ count-- 16138 str r1, [r10], #4 @ *outs++ = val 16139 bne 1b @ ...while count != 0 16140 b .LinvokeArgsDone 16141 16142/* 16143 * Common code for method invocation without range. 16144 * 16145 * On entry: 16146 * r0 is "Method* methodToCall", r9 is "this" 16147 */ 16148common_invokeMethodNoRange: 16149.LinvokeNewNoRange: 16150#if defined(WITH_JIT) 16151 ldrh r1, [rSELF, #offThread_subMode] 16152 ands r1, #kSubModeJitTraceBuild 16153 blne save_callsiteinfo 16154#endif 16155 @ prepare to copy args to "outs" area of current frame 16156 movs r2, rINST, lsr #12 @ r2<- B (arg count) -- test for zero 16157 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 16158 FETCH(r1, 2) @ r1<- GFED (load here to hide latency) 16159 beq .LinvokeArgsDone 16160 16161 @ r0=methodToCall, r1=GFED, r2=count, r10=outs 16162.LinvokeNonRange: 16163 rsb r2, r2, #5 @ r2<- 5-r2 16164 add pc, pc, r2, lsl #4 @ computed goto, 4 instrs each 16165 bl common_abort @ (skipped due to ARM prefetch) 161665: and ip, rINST, #0x0f00 @ isolate A 16167 ldr r2, [rFP, ip, lsr #6] @ r2<- vA (shift right 8, left 2) 16168 mov r0, r0 @ nop 16169 str r2, [r10, #-4]! @ *--outs = vA 161704: and ip, r1, #0xf000 @ isolate G 16171 ldr r2, [rFP, ip, lsr #10] @ r2<- vG (shift right 12, left 2) 16172 mov r0, r0 @ nop 16173 str r2, [r10, #-4]! @ *--outs = vG 161743: and ip, r1, #0x0f00 @ isolate F 16175 ldr r2, [rFP, ip, lsr #6] @ r2<- vF 16176 mov r0, r0 @ nop 16177 str r2, [r10, #-4]! @ *--outs = vF 161782: and ip, r1, #0x00f0 @ isolate E 16179 ldr r2, [rFP, ip, lsr #2] @ r2<- vE 16180 mov r0, r0 @ nop 16181 str r2, [r10, #-4]! @ *--outs = vE 161821: and ip, r1, #0x000f @ isolate D 16183 ldr r2, [rFP, ip, lsl #2] @ r2<- vD 16184 mov r0, r0 @ nop 16185 str r2, [r10, #-4]! @ *--outs = vD 161860: @ fall through to .LinvokeArgsDone 16187 16188.LinvokeArgsDone: @ r0=methodToCall 16189 ldrh r9, [r0, #offMethod_registersSize] @ r9<- methodToCall->regsSize 16190 ldrh r3, [r0, #offMethod_outsSize] @ r3<- methodToCall->outsSize 16191 ldr r2, [r0, #offMethod_insns] @ r2<- method->insns 16192 ldr rINST, [r0, #offMethod_clazz] @ rINST<- method->clazz 16193 @ find space for the new stack frame, check for overflow 16194 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area 16195 sub r1, r1, r9, lsl #2 @ r1<- newFp (old savearea - regsSize) 16196 SAVEAREA_FROM_FP(r10, r1) @ r10<- newSaveArea 16197@ bl common_dumpRegs 16198 ldr r9, [rSELF, #offThread_interpStackEnd] @ r9<- interpStackEnd 16199 sub r3, r10, r3, lsl #2 @ r3<- bottom (newsave - outsSize) 16200 cmp r3, r9 @ bottom < interpStackEnd? 16201 ldrh lr, [rSELF, #offThread_subMode] 16202 ldr r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags 16203 blo .LstackOverflow @ yes, this frame will overflow stack 16204 16205 @ set up newSaveArea 16206#ifdef EASY_GDB 16207 SAVEAREA_FROM_FP(ip, rFP) @ ip<- stack save area 16208 str ip, [r10, #offStackSaveArea_prevSave] 16209#endif 16210 str rFP, [r10, #offStackSaveArea_prevFrame] 16211 str rPC, [r10, #offStackSaveArea_savedPc] 16212#if defined(WITH_JIT) 16213 mov r9, #0 16214 str r9, [r10, #offStackSaveArea_returnAddr] 16215#endif 16216 str r0, [r10, #offStackSaveArea_method] 16217 16218 @ Profiling? 16219 cmp lr, #0 @ any special modes happening? 16220 bne 2f @ go if so 162211: 16222 tst r3, #ACC_NATIVE 16223 bne .LinvokeNative 16224 16225 /* 16226 stmfd sp!, {r0-r3} 16227 bl common_printNewline 16228 mov r0, rFP 16229 mov r1, #0 16230 bl dvmDumpFp 16231 ldmfd sp!, {r0-r3} 16232 stmfd sp!, {r0-r3} 16233 mov r0, r1 16234 mov r1, r10 16235 bl dvmDumpFp 16236 bl common_printNewline 16237 ldmfd sp!, {r0-r3} 16238 */ 16239 16240 ldrh r9, [r2] @ r9 <- load INST from new PC 16241 ldr r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex 16242 mov rPC, r2 @ publish new rPC 16243 16244 @ Update state values for the new method 16245 @ r0=methodToCall, r1=newFp, r3=newMethodClass, r9=newINST 16246 str r0, [rSELF, #offThread_method] @ self->method = methodToCall 16247 str r3, [rSELF, #offThread_methodClassDex] @ self->methodClassDex = ... 16248 mov r2, #1 16249 str r2, [rSELF, #offThread_debugIsMethodEntry] 16250#if defined(WITH_JIT) 16251 ldr r0, [rSELF, #offThread_pJitProfTable] 16252 mov rFP, r1 @ fp = newFp 16253 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 16254 mov rINST, r9 @ publish new rINST 16255 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16256 cmp r0,#0 16257 bne common_updateProfile 16258 GOTO_OPCODE(ip) @ jump to next instruction 16259#else 16260 mov rFP, r1 @ fp = newFp 16261 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 16262 mov rINST, r9 @ publish new rINST 16263 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16264 GOTO_OPCODE(ip) @ jump to next instruction 16265#endif 16266 162672: 16268 @ Profiling - record method entry. r0: methodToCall 16269 stmfd sp!, {r0-r3} @ preserve r0-r3 16270 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16271 mov r1, r0 16272 mov r0, rSELF 16273 bl dvmReportInvoke @ (self, method) 16274 ldmfd sp!, {r0-r3} @ restore r0-r3 16275 b 1b 16276 16277.LinvokeNative: 16278 @ Prep for the native call 16279 @ r0=methodToCall, r1=newFp, r10=newSaveArea 16280 ldrh lr, [rSELF, #offThread_subMode] 16281 ldr r9, [rSELF, #offThread_jniLocal_topCookie]@r9<-thread->localRef->... 16282 str r1, [rSELF, #offThread_curFrame] @ curFrame = newFp 16283 str r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top 16284 mov r2, r0 @ r2<- methodToCall 16285 mov r0, r1 @ r0<- newFp (points to args) 16286 add r1, rSELF, #offThread_retval @ r1<- &retval 16287 mov r3, rSELF @ arg3<- self 16288 16289#ifdef ASSIST_DEBUGGER 16290 /* insert fake function header to help gdb find the stack frame */ 16291 b .Lskip 16292 .type dalvik_mterp, %function 16293dalvik_mterp: 16294 .fnstart 16295 MTERP_ENTRY1 16296 MTERP_ENTRY2 16297.Lskip: 16298#endif 16299 16300 cmp lr, #0 @ any special SubModes active? 16301 bne 11f @ go handle them if so 16302 ldr ip, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 16303 blx ip 163047: 16305 16306 @ native return; r10=newSaveArea 16307 @ equivalent to dvmPopJniLocals 16308 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top 16309 ldr r1, [rSELF, #offThread_exception] @ check for exception 16310 str rFP, [rSELF, #offThread_curFrame] @ curFrame = fp 16311 cmp r1, #0 @ null? 16312 str r0, [rSELF, #offThread_jniLocal_topCookie] @ new top <- old top 16313 bne common_exceptionThrown @ no, handle exception 16314 16315 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 16316 GET_INST_OPCODE(ip) @ extract opcode from rINST 16317 GOTO_OPCODE(ip) @ jump to next instruction 16318 1631911: 16320 @ r0=newFp, r1=&retval, r2=methodToCall, r3=self, lr=subModes 16321 stmfd sp!, {r0-r3} @ save all but subModes 16322 mov r0, r2 @ r0<- methodToCall 16323 mov r1, rSELF 16324 mov r2, rFP 16325 bl dvmReportPreNativeInvoke @ (methodToCall, self, fp) 16326 ldmfd sp, {r0-r3} @ refresh. NOTE: no sp autoincrement 16327 16328 @ Call the native method 16329 ldr ip, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 16330 blx ip 16331 16332 @ Restore the pre-call arguments 16333 ldmfd sp!, {r0-r3} @ r2<- methodToCall (others unneeded) 16334 16335 @ Finish up any post-invoke subMode requirements 16336 mov r0, r2 @ r0<- methodToCall 16337 mov r1, rSELF 16338 mov r2, rFP 16339 bl dvmReportPostNativeInvoke @ (methodToCall, self, fp) 16340 b 7b @ resume 16341 16342.LstackOverflow: @ r0=methodToCall 16343 mov r1, r0 @ r1<- methodToCall 16344 mov r0, rSELF @ r0<- self 16345 bl dvmHandleStackOverflow 16346 b common_exceptionThrown 16347#ifdef ASSIST_DEBUGGER 16348 .fnend 16349 .size dalvik_mterp, .-dalvik_mterp 16350#endif 16351 16352 16353 /* 16354 * Common code for method invocation, calling through "glue code". 16355 * 16356 * TODO: now that we have range and non-range invoke handlers, this 16357 * needs to be split into two. Maybe just create entry points 16358 * that set r9 and jump here? 16359 * 16360 * On entry: 16361 * r0 is "Method* methodToCall", the method we're trying to call 16362 * r9 is "bool methodCallRange", indicating if this is a /range variant 16363 */ 16364 .if 0 16365.LinvokeOld: 16366 sub sp, sp, #8 @ space for args + pad 16367 FETCH(ip, 2) @ ip<- FEDC or CCCC 16368 mov r2, r0 @ A2<- methodToCall 16369 mov r0, rSELF @ A0<- self 16370 SAVE_PC_FP_TO_SELF() @ export state to "self" 16371 mov r1, r9 @ A1<- methodCallRange 16372 mov r3, rINST, lsr #8 @ A3<- AA 16373 str ip, [sp, #0] @ A4<- ip 16374 bl dvmMterp_invokeMethod @ call the C invokeMethod 16375 add sp, sp, #8 @ remove arg area 16376 b common_resumeAfterGlueCall @ continue to next instruction 16377 .endif 16378 16379 16380 16381/* 16382 * Common code for handling a return instruction. 16383 * 16384 * This does not return. 16385 */ 16386common_returnFromMethod: 16387.LreturnNew: 16388 ldrh lr, [rSELF, #offThread_subMode] 16389 SAVEAREA_FROM_FP(r0, rFP) 16390 ldr r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc 16391 cmp lr, #0 @ any special subMode handling needed? 16392 bne 19f 1639314: 16394 ldr rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame 16395 ldr r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)] 16396 @ r2<- method we're returning to 16397 cmp r2, #0 @ is this a break frame? 16398#if defined(WORKAROUND_CORTEX_A9_745320) 16399 /* Don't use conditional loads if the HW defect exists */ 16400 beq 15f 16401 ldr r10, [r2, #offMethod_clazz] @ r10<- method->clazz 1640215: 16403#else 16404 ldrne r10, [r2, #offMethod_clazz] @ r10<- method->clazz 16405#endif 16406 beq common_gotoBail @ break frame, bail out completely 16407 16408 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 16409 PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST 16410 str r2, [rSELF, #offThread_method]@ self->method = newSave->method 16411 ldr r1, [r10, #offClassObject_pDvmDex] @ r1<- method->clazz->pDvmDex 16412 str rFP, [rSELF, #offThread_curFrame] @ curFrame = fp 16413#if defined(WITH_JIT) 16414 ldr r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr 16415 mov rPC, r9 @ publish new rPC 16416 str r1, [rSELF, #offThread_methodClassDex] 16417 str r10, [rSELF, #offThread_inJitCodeCache] @ may return to JIT'ed land 16418 cmp r10, #0 @ caller is compiled code 16419 blxne r10 16420 GET_INST_OPCODE(ip) @ extract opcode from rINST 16421 GOTO_OPCODE(ip) @ jump to next instruction 16422#else 16423 GET_INST_OPCODE(ip) @ extract opcode from rINST 16424 mov rPC, r9 @ publish new rPC 16425 str r1, [rSELF, #offThread_methodClassDex] 16426 GOTO_OPCODE(ip) @ jump to next instruction 16427#endif 16428 1642919: 16430 @ Handle special actions 16431 @ On entry, r0: StackSaveArea 16432 ldr r1, [r0, #offStackSaveArea_prevFrame] @ r2<- prevFP 16433 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16434 str r1, [rSELF, #offThread_curFrame] @ update interpSave.curFrame 16435 mov r0, rSELF 16436 bl dvmReportReturn @ (self) 16437 SAVEAREA_FROM_FP(r0, rFP) @ restore StackSaveArea 16438 b 14b @ continue 16439 16440 /* 16441 * Return handling, calls through "glue code". 16442 */ 16443 .if 0 16444.LreturnOld: 16445 SAVE_PC_FP_TO_SELF() @ export state 16446 mov r0, rSELF @ arg to function 16447 bl dvmMterp_returnFromMethod 16448 b common_resumeAfterGlueCall 16449 .endif 16450 16451 16452/* 16453 * Somebody has thrown an exception. Handle it. 16454 * 16455 * If the exception processing code returns to us (instead of falling 16456 * out of the interpreter), continue with whatever the next instruction 16457 * now happens to be. 16458 * 16459 * This does not return. 16460 */ 16461 .global dvmMterpCommonExceptionThrown 16462dvmMterpCommonExceptionThrown: 16463common_exceptionThrown: 16464.LexceptionNew: 16465 16466 EXPORT_PC() 16467 16468 mov r0, rSELF 16469 bl dvmCheckSuspendPending 16470 16471 ldr r9, [rSELF, #offThread_exception] @ r9<- self->exception 16472 mov r1, rSELF @ r1<- self 16473 mov r0, r9 @ r0<- exception 16474 bl dvmAddTrackedAlloc @ don't let the exception be GCed 16475 ldrh r2, [rSELF, #offThread_subMode] @ get subMode flags 16476 mov r3, #0 @ r3<- NULL 16477 str r3, [rSELF, #offThread_exception] @ self->exception = NULL 16478 16479 @ Special subMode? 16480 cmp r2, #0 @ any special subMode handling needed? 16481 bne 7f @ go if so 164828: 16483 /* set up args and a local for "&fp" */ 16484 /* (str sp, [sp, #-4]! would be perfect here, but is discouraged) */ 16485 str rFP, [sp, #-4]! @ *--sp = fp 16486 mov ip, sp @ ip<- &fp 16487 mov r3, #0 @ r3<- false 16488 str ip, [sp, #-4]! @ *--sp = &fp 16489 ldr r1, [rSELF, #offThread_method] @ r1<- self->method 16490 mov r0, rSELF @ r0<- self 16491 ldr r1, [r1, #offMethod_insns] @ r1<- method->insns 16492 mov r2, r9 @ r2<- exception 16493 sub r1, rPC, r1 @ r1<- pc - method->insns 16494 mov r1, r1, asr #1 @ r1<- offset in code units 16495 16496 /* call, r0 gets catchRelPc (a code-unit offset) */ 16497 bl dvmFindCatchBlock @ call(self, relPc, exc, scan?, &fp) 16498 16499 /* fix earlier stack overflow if necessary; may trash rFP */ 16500 ldrb r1, [rSELF, #offThread_stackOverflowed] 16501 cmp r1, #0 @ did we overflow earlier? 16502 beq 1f @ no, skip ahead 16503 mov rFP, r0 @ save relPc result in rFP 16504 mov r0, rSELF @ r0<- self 16505 mov r1, r9 @ r1<- exception 16506 bl dvmCleanupStackOverflow @ call(self) 16507 mov r0, rFP @ restore result 165081: 16509 16510 /* update frame pointer and check result from dvmFindCatchBlock */ 16511 ldr rFP, [sp, #4] @ retrieve the updated rFP 16512 cmp r0, #0 @ is catchRelPc < 0? 16513 add sp, sp, #8 @ restore stack 16514 bmi .LnotCaughtLocally 16515 16516 /* adjust locals to match self->interpSave.curFrame and updated PC */ 16517 SAVEAREA_FROM_FP(r1, rFP) @ r1<- new save area 16518 ldr r1, [r1, #offStackSaveArea_method] @ r1<- new method 16519 str r1, [rSELF, #offThread_method] @ self->method = new method 16520 ldr r2, [r1, #offMethod_clazz] @ r2<- method->clazz 16521 ldr r3, [r1, #offMethod_insns] @ r3<- method->insns 16522 ldr r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex 16523 add rPC, r3, r0, asl #1 @ rPC<- method->insns + catchRelPc 16524 str r2, [rSELF, #offThread_methodClassDex] @ self->pDvmDex = meth... 16525 16526 /* release the tracked alloc on the exception */ 16527 mov r0, r9 @ r0<- exception 16528 mov r1, rSELF @ r1<- self 16529 bl dvmReleaseTrackedAlloc @ release the exception 16530 16531 /* restore the exception if the handler wants it */ 16532 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh rIBASE 16533 FETCH_INST() @ load rINST from rPC 16534 GET_INST_OPCODE(ip) @ extract opcode from rINST 16535 cmp ip, #OP_MOVE_EXCEPTION @ is it "move-exception"? 16536 streq r9, [rSELF, #offThread_exception] @ yes, restore the exception 16537 GOTO_OPCODE(ip) @ jump to next instruction 16538 16539 @ Manage debugger bookkeeping 165407: 16541 str rPC, [rSELF, #offThread_pc] @ update interpSave.pc 16542 str rFP, [rSELF, #offThread_curFrame] @ update interpSave.curFrame 16543 mov r0, rSELF @ arg0<- self 16544 mov r1, r9 @ arg1<- exception 16545 bl dvmReportExceptionThrow @ (self, exception) 16546 b 8b @ resume with normal handling 16547 16548.LnotCaughtLocally: @ r9=exception 16549 /* fix stack overflow if necessary */ 16550 ldrb r1, [rSELF, #offThread_stackOverflowed] 16551 cmp r1, #0 @ did we overflow earlier? 16552 movne r0, rSELF @ if yes: r0<- self 16553 movne r1, r9 @ if yes: r1<- exception 16554 blne dvmCleanupStackOverflow @ if yes: call(self) 16555 16556 @ may want to show "not caught locally" debug messages here 16557#if DVM_SHOW_EXCEPTION >= 2 16558 /* call __android_log_print(prio, tag, format, ...) */ 16559 /* "Exception %s from %s:%d not caught locally" */ 16560 @ dvmLineNumFromPC(method, pc - method->insns) 16561 ldr r0, [rSELF, #offThread_method] 16562 ldr r1, [r0, #offMethod_insns] 16563 sub r1, rPC, r1 16564 asr r1, r1, #1 16565 bl dvmLineNumFromPC 16566 str r0, [sp, #-4]! 16567 @ dvmGetMethodSourceFile(method) 16568 ldr r0, [rSELF, #offThread_method] 16569 bl dvmGetMethodSourceFile 16570 str r0, [sp, #-4]! 16571 @ exception->clazz->descriptor 16572 ldr r3, [r9, #offObject_clazz] 16573 ldr r3, [r3, #offClassObject_descriptor] 16574 @ 16575 ldr r2, strExceptionNotCaughtLocally 165760: add r2, pc 16577 ldr r1, strLogTag 165781: add r1, pc 16579 mov r0, #3 @ LOG_DEBUG 16580 bl __android_log_print 16581#endif 16582 str r9, [rSELF, #offThread_exception] @ restore exception 16583 mov r0, r9 @ r0<- exception 16584 mov r1, rSELF @ r1<- self 16585 bl dvmReleaseTrackedAlloc @ release the exception 16586 b common_gotoBail @ bail out 16587 16588strExceptionNotCaughtLocally: 16589 .word PCREL_REF(.LstrExceptionNotCaughtLocally,0b) 16590strLogTag: 16591 .word PCREL_REF(.LstrLogTag,1b) 16592 16593 /* 16594 * Exception handling, calls through "glue code". 16595 */ 16596 .if 0 16597.LexceptionOld: 16598 SAVE_PC_FP_TO_SELF() @ export state 16599 mov r0, rSELF @ arg to function 16600 bl dvmMterp_exceptionThrown 16601 b common_resumeAfterGlueCall 16602 .endif 16603 16604#if defined(WITH_JIT) 16605 /* 16606 * If the JIT is actively building a trace we need to make sure 16607 * that the field is fully resolved before including the current 16608 * instruction. 16609 * 16610 * On entry: 16611 * r10: &dvmDex->pResFields[field] 16612 * r0: field pointer (must preserve) 16613 */ 16614common_verifyField: 16615 ldrh r3, [rSELF, #offThread_subMode] @ r3 <- submode byte 16616 ands r3, #kSubModeJitTraceBuild 16617 bxeq lr @ Not building trace, continue 16618 ldr r1, [r10] @ r1<- reload resolved StaticField ptr 16619 cmp r1, #0 @ resolution complete? 16620 bxne lr @ yes, continue 16621 stmfd sp!, {r0-r2,lr} @ save regs 16622 mov r0, rSELF 16623 mov r1, rPC 16624 bl dvmJitEndTraceSelect @ (self,pc) end trace before this inst 16625 ldmfd sp!, {r0-r2, lr} 16626 bx lr @ return 16627#endif 16628 16629/* 16630 * After returning from a "glued" function, pull out the updated 16631 * values and start executing at the next instruction. 16632 */ 16633common_resumeAfterGlueCall: 16634 LOAD_PC_FP_FROM_SELF() @ pull rPC and rFP out of thread 16635 ldr rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh 16636 FETCH_INST() @ load rINST from rPC 16637 GET_INST_OPCODE(ip) @ extract opcode from rINST 16638 GOTO_OPCODE(ip) @ jump to next instruction 16639 16640/* 16641 * Invalid array index. Note that our calling convention is strange; we use r1 16642 * and r3 because those just happen to be the registers all our callers are 16643 * using. We move r3 before calling the C function, but r1 happens to match. 16644 * r1: index 16645 * r3: size 16646 */ 16647common_errArrayIndex: 16648 EXPORT_PC() 16649 mov r0, r3 16650 bl dvmThrowArrayIndexOutOfBoundsException 16651 b common_exceptionThrown 16652 16653/* 16654 * Integer divide or mod by zero. 16655 */ 16656common_errDivideByZero: 16657 EXPORT_PC() 16658 ldr r0, strDivideByZero 166590: add r0, pc 16660 bl dvmThrowArithmeticException 16661 b common_exceptionThrown 16662 16663strDivideByZero: 16664 .word PCREL_REF(.LstrDivideByZero,0b) 16665 16666/* 16667 * Attempt to allocate an array with a negative size. 16668 * On entry: length in r1 16669 */ 16670common_errNegativeArraySize: 16671 EXPORT_PC() 16672 mov r0, r1 @ arg0 <- len 16673 bl dvmThrowNegativeArraySizeException @ (len) 16674 b common_exceptionThrown 16675 16676/* 16677 * Invocation of a non-existent method. 16678 * On entry: method name in r1 16679 */ 16680common_errNoSuchMethod: 16681 EXPORT_PC() 16682 mov r0, r1 16683 bl dvmThrowNoSuchMethodError 16684 b common_exceptionThrown 16685 16686/* 16687 * We encountered a null object when we weren't expecting one. We 16688 * export the PC, throw a NullPointerException, and goto the exception 16689 * processing code. 16690 */ 16691common_errNullObject: 16692 EXPORT_PC() 16693 mov r0, #0 16694 bl dvmThrowNullPointerException 16695 b common_exceptionThrown 16696 16697/* 16698 * For debugging, cause an immediate fault. The source address will 16699 * be in lr (use a bl instruction to jump here). 16700 */ 16701common_abort: 16702 ldr pc, .LdeadFood 16703.LdeadFood: 16704 .word 0xdeadf00d 16705 16706/* 16707 * Spit out a "we were here", preserving all registers. (The attempt 16708 * to save ip won't work, but we need to save an even number of 16709 * registers for EABI 64-bit stack alignment.) 16710 */ 16711 .macro SQUEAK num 16712common_squeak\num: 16713 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16714 ldr r0, strSqueak\num 167150: add r0, pc 16716 mov r1, #\num 16717 bl printf 16718 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16719 bx lr 16720 16721strSqueak\num: 16722 .word PCREL_REF(.LstrSqueak,0b) 16723 .endm 16724 16725 SQUEAK 0 16726 SQUEAK 1 16727 SQUEAK 2 16728 SQUEAK 3 16729 SQUEAK 4 16730 SQUEAK 5 16731 16732/* 16733 * Spit out the number in r0, preserving registers. 16734 */ 16735common_printNum: 16736 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16737 mov r1, r0 16738 ldr r0, strSqueak 167390: add r0, pc 16740 bl printf 16741 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16742 bx lr 16743 16744strSqueak: 16745 .word PCREL_REF(.LstrSqueak,0b) 16746 16747/* 16748 * Print a newline, preserving registers. 16749 */ 16750common_printNewline: 16751 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16752 ldr r0, strNewline 167530: add r0, pc 16754 bl printf 16755 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16756 bx lr 16757 16758strNewline: 16759 .word PCREL_REF(.LstrNewline,0b) 16760 16761 /* 16762 * Print the 32-bit quantity in r0 as a hex value, preserving registers. 16763 */ 16764common_printHex: 16765 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16766 mov r1, r0 16767 ldr r0, strPrintHex 167680: add r0, pc 16769 bl printf 16770 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16771 bx lr 16772 16773strPrintHex: 16774 .word PCREL_REF(.LstrPrintHex,0b) 16775 16776/* 16777 * Print the 64-bit quantity in r0-r1, preserving registers. 16778 */ 16779common_printLong: 16780 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16781 mov r3, r1 16782 mov r2, r0 16783 ldr r0, strPrintLong 167840: add r0, pc 16785 bl printf 16786 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16787 bx lr 16788 16789strPrintLong: 16790 .word PCREL_REF(.LstrPrintLong,0b) 16791 16792/* 16793 * Print full method info. Pass the Method* in r0. Preserves regs. 16794 */ 16795common_printMethod: 16796 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16797 bl dvmMterpPrintMethod 16798 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16799 bx lr 16800 16801/* 16802 * Call a C helper function that dumps regs and possibly some 16803 * additional info. Requires the C function to be compiled in. 16804 */ 16805 .if 0 16806common_dumpRegs: 16807 stmfd sp!, {r0, r1, r2, r3, ip, lr} 16808 bl dvmMterpDumpArmRegs 16809 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 16810 bx lr 16811 .endif 16812 16813#if 0 16814/* 16815 * Experiment on VFP mode. 16816 * 16817 * uint32_t setFPSCR(uint32_t val, uint32_t mask) 16818 * 16819 * Updates the bits specified by "mask", setting them to the values in "val". 16820 */ 16821setFPSCR: 16822 and r0, r0, r1 @ make sure no stray bits are set 16823 fmrx r2, fpscr @ get VFP reg 16824 mvn r1, r1 @ bit-invert mask 16825 and r2, r2, r1 @ clear masked bits 16826 orr r2, r2, r0 @ set specified bits 16827 fmxr fpscr, r2 @ set VFP reg 16828 mov r0, r2 @ return new value 16829 bx lr 16830 16831 .align 2 16832 .global dvmConfigureFP 16833 .type dvmConfigureFP, %function 16834dvmConfigureFP: 16835 stmfd sp!, {ip, lr} 16836 /* 0x03000000 sets DN/FZ */ 16837 /* 0x00009f00 clears the six exception enable flags */ 16838 bl common_squeak0 16839 mov r0, #0x03000000 @ r0<- 0x03000000 16840 add r1, r0, #0x9f00 @ r1<- 0x03009f00 16841 bl setFPSCR 16842 ldmfd sp!, {ip, pc} 16843#endif 16844 16845 16846 16847/* 16848 * Zero-terminated ASCII string data. 16849 * 16850 * On ARM we have two choices: do like gcc does, and LDR from a .word 16851 * with the address, or use an ADR pseudo-op to get the address 16852 * directly. ADR saves 4 bytes and an indirection, but it's using a 16853 * PC-relative addressing mode and hence has a limited range, which 16854 * makes it not work well with mergeable string sections. 16855 */ 16856 .section .rodata.str1.4,"aMS",%progbits,1 16857 16858.LstrBadEntryPoint: 16859 .asciz "Bad entry point %d\n" 16860.LstrFilledNewArrayNotImpl: 16861 .asciz "filled-new-array only implemented for objects and 'int'" 16862.LstrDivideByZero: 16863 .asciz "divide by zero" 16864.LstrLogTag: 16865 .asciz "mterp" 16866.LstrExceptionNotCaughtLocally: 16867 .asciz "Exception %s from %s:%d not caught locally\n" 16868 16869.LstrNewline: 16870 .asciz "\n" 16871.LstrSqueak: 16872 .asciz "<%d>" 16873.LstrPrintHex: 16874 .asciz "<%#x>" 16875.LstrPrintLong: 16876 .asciz "<%lld>" 16877 16878