InterpAsm-armv7-a.S revision 8cb0d098d79af61546e275f633325794f4587602
1/* 2 * This file was generated automatically by gen-mterp.py for 'armv7-a'. 3 * 4 * --> DO NOT EDIT <-- 5 */ 6 7/* File: armv5te/header.S */ 8/* 9 * Copyright (C) 2008 The Android Open Source Project 10 * 11 * Licensed under the Apache License, Version 2.0 (the "License"); 12 * you may not use this file except in compliance with the License. 13 * You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, software 18 * distributed under the License is distributed on an "AS IS" BASIS, 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 * See the License for the specific language governing permissions and 21 * limitations under the License. 22 */ 23 24/* 25 * ARMv5 definitions and declarations. 26 */ 27 28/* 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_fp] 86#define SAVE_FP_TO_SELF() str rFP, [rSELF, #offThread_fp] 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 calls dvmThrowException. 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 #2]!", 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_IFEQ(_reg) addeq pc, rIBASE, _reg, lsl #6 180#define GOTO_OPCODE_IFNE(_reg) addne pc, rIBASE, _reg, lsl #6 181 182/* 183 * Get/set the 32-bit value from a Dalvik register. 184 */ 185#define GET_VREG(_reg, _vreg) ldr _reg, [rFP, _vreg, lsl #2] 186#define SET_VREG(_reg, _vreg) str _reg, [rFP, _vreg, lsl #2] 187 188#if defined(WITH_JIT) 189#define GET_JIT_PROF_TABLE(_reg) ldr _reg,[rSELF,#offThread_pJitProfTable] 190#define GET_JIT_THRESHOLD(_reg) ldr _reg,[rSELF,#offThread_jitThreshold] 191#endif 192 193/* 194 * Convert a virtual register index into an address. 195 */ 196#define VREG_INDEX_TO_ADDR(_reg, _vreg) \ 197 add _reg, rFP, _vreg, lsl #2 198 199/* 200 * This is a #include, not a %include, because we want the C pre-processor 201 * to expand the macros into assembler assignment statements. 202 */ 203#include "../common/asm-constants.h" 204 205#if defined(WITH_JIT) 206#include "../common/jit-config.h" 207#endif 208 209/* File: armv7-a/platform.S */ 210/* 211 * =========================================================================== 212 * CPU-version-specific defines 213 * =========================================================================== 214 */ 215 216#if !defined(ANDROID_SMP) 217# error "Must define ANDROID_SMP" 218#endif 219 220/* 221 * Macro for data memory barrier. 222 */ 223.macro SMP_DMB 224#if ANDROID_SMP != 0 225 dmb 226#else 227 /* not SMP */ 228#endif 229.endm 230 231/* 232 * Macro for data memory barrier (store/store variant). 233 */ 234.macro SMP_DMB_ST 235#if ANDROID_SMP != 0 236 dmb st 237#else 238 /* not SMP */ 239#endif 240.endm 241 242/* File: armv5te/entry.S */ 243/* 244 * Copyright (C) 2008 The Android Open Source Project 245 * 246 * Licensed under the Apache License, Version 2.0 (the "License"); 247 * you may not use this file except in compliance with the License. 248 * You may obtain a copy of the License at 249 * 250 * http://www.apache.org/licenses/LICENSE-2.0 251 * 252 * Unless required by applicable law or agreed to in writing, software 253 * distributed under the License is distributed on an "AS IS" BASIS, 254 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 255 * See the License for the specific language governing permissions and 256 * limitations under the License. 257 */ 258/* 259 * Interpreter entry point. 260 */ 261 262/* 263 * We don't have formal stack frames, so gdb scans upward in the code 264 * to find the start of the function (a label with the %function type), 265 * and then looks at the next few instructions to figure out what 266 * got pushed onto the stack. From this it figures out how to restore 267 * the registers, including PC, for the previous stack frame. If gdb 268 * sees a non-function label, it stops scanning, so either we need to 269 * have nothing but assembler-local labels between the entry point and 270 * the break, or we need to fake it out. 271 * 272 * When this is defined, we add some stuff to make gdb less confused. 273 */ 274#define ASSIST_DEBUGGER 1 275 276 .text 277 .align 2 278 .global dvmMterpStdRun 279 .type dvmMterpStdRun, %function 280 281/* 282 * On entry: 283 * r0 Thread* self 284 * 285 * This function returns a boolean "changeInterp" value. The return comes 286 * via a call to dvmMterpStdBail(). 287 */ 288dvmMterpStdRun: 289#define MTERP_ENTRY1 \ 290 .save {r4-r10,fp,lr}; \ 291 stmfd sp!, {r4-r10,fp,lr} @ save 9 regs 292#define MTERP_ENTRY2 \ 293 .pad #4; \ 294 sub sp, sp, #4 @ align 64 295 296 .fnstart 297 MTERP_ENTRY1 298 MTERP_ENTRY2 299 300 /* save stack pointer, add magic word for debuggerd */ 301 str sp, [r0, #offThread_bailPtr] @ save SP for eventual return 302 303 /* set up "named" registers, figure out entry point */ 304 mov rSELF, r0 @ set rSELF 305 ldr r1, [r0, #offThread_entryPoint] @ enum is 4 bytes in aapcs-EABI 306 LOAD_PC_FP_FROM_SELF() @ load rPC and rFP from "thread" 307 adr rIBASE, dvmAsmInstructionStart @ set rIBASE 308 cmp r1, #kInterpEntryInstr @ usual case? 309 bne .Lnot_instr @ no, handle it 310 311#if defined(WITH_JIT) 312.LentryInstr: 313 /* Entry is always a possible trace start */ 314 GET_JIT_PROF_TABLE(r0) 315 FETCH_INST() 316 mov r1, #0 @ prepare the value for the new state 317 str r1, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 318 cmp r0,#0 @ is profiling disabled? 319#if !defined(WITH_SELF_VERIFICATION) 320 bne common_updateProfile @ profiling is enabled 321#else 322 ldr r2, [rSELF, #offThread_shadowSpace] @ to find out the jit exit state 323 beq 1f @ profiling is disabled 324 ldr r3, [r2, #offShadowSpace_jitExitState] @ jit exit state 325 cmp r3, #kSVSTraceSelect @ hot trace following? 326 moveq r2,#kJitTSelectRequestHot @ ask for trace selection 327 beq common_selectTrace @ go build the trace 328 cmp r3, #kSVSNoProfile @ don't profile the next instruction? 329 beq 1f @ intrepret the next instruction 330 b common_updateProfile @ collect profiles 331#endif 3321: 333 GET_INST_OPCODE(ip) 334 GOTO_OPCODE(ip) 335#else 336 /* start executing the instruction at rPC */ 337 FETCH_INST() @ load rINST from rPC 338 GET_INST_OPCODE(ip) @ extract opcode from rINST 339 GOTO_OPCODE(ip) @ jump to next instruction 340#endif 341 342.Lnot_instr: 343 cmp r1, #kInterpEntryReturn @ were we returning from a method? 344 beq common_returnFromMethod 345 346.Lnot_return: 347 cmp r1, #kInterpEntryThrow @ were we throwing an exception? 348 beq common_exceptionThrown 349 350#if defined(WITH_JIT) 351.Lnot_throw: 352 ldr r10,[rSELF, #offThread_jitResumeNPC] 353 ldr r2,[rSELF, #offThread_jitResumeDPC] 354 cmp r1, #kInterpEntryResume @ resuming after Jit single-step? 355 bne .Lbad_arg 356 cmp rPC,r2 357 bne .LentryInstr @ must have branched, don't resume 358#if defined(WITH_SELF_VERIFICATION) 359 @ self->entryPoint will be set in dvmSelfVerificationSaveState 360 b jitSVShadowRunStart @ re-enter the translation after the 361 @ single-stepped instruction 362 @noreturn 363#endif 364 mov r1, #kInterpEntryInstr 365 str r1, [rSELF, #offThread_entryPoint] 366 bx r10 @ re-enter the translation 367#endif 368 369.Lbad_arg: 370 ldr r0, strBadEntryPoint 371 @ r1 holds value of entryPoint 372 bl printf 373 bl dvmAbort 374 .fnend 375 .size dvmMterpStdRun, .-dvmMterpStdRun 376 377 378 .global dvmMterpStdBail 379 .type dvmMterpStdBail, %function 380 381/* 382 * Restore the stack pointer and PC from the save point established on entry. 383 * This is essentially the same as a longjmp, but should be cheaper. The 384 * last instruction causes us to return to whoever called dvmMterpStdRun. 385 * 386 * We pushed some registers on the stack in dvmMterpStdRun, then saved 387 * SP and LR. Here we restore SP, restore the registers, and then restore 388 * LR to PC. 389 * 390 * On entry: 391 * r0 Thread* self 392 * r1 bool changeInterp 393 */ 394dvmMterpStdBail: 395 ldr sp, [r0, #offThread_bailPtr] @ sp<- saved SP 396 mov r0, r1 @ return the changeInterp value 397 add sp, sp, #4 @ un-align 64 398 ldmfd sp!, {r4-r10,fp,pc} @ restore 9 regs and return 399 400 401/* 402 * String references. 403 */ 404strBadEntryPoint: 405 .word .LstrBadEntryPoint 406 407 408 .global dvmAsmInstructionStart 409 .type dvmAsmInstructionStart, %function 410dvmAsmInstructionStart = .L_OP_NOP 411 .text 412 413/* ------------------------------ */ 414 .balign 64 415.L_OP_NOP: /* 0x00 */ 416/* File: armv5te/OP_NOP.S */ 417 FETCH_ADVANCE_INST(1) @ advance to next instr, load rINST 418 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 419 GOTO_OPCODE(ip) @ execute it 420 421#ifdef ASSIST_DEBUGGER 422 /* insert fake function header to help gdb find the stack frame */ 423 .type dalvik_inst, %function 424dalvik_inst: 425 .fnstart 426 MTERP_ENTRY1 427 MTERP_ENTRY2 428 .fnend 429#endif 430 431/* ------------------------------ */ 432 .balign 64 433.L_OP_MOVE: /* 0x01 */ 434/* File: armv6t2/OP_MOVE.S */ 435 /* for move, move-object, long-to-int */ 436 /* op vA, vB */ 437 mov r1, rINST, lsr #12 @ r1<- B from 15:12 438 ubfx r0, rINST, #8, #4 @ r0<- A from 11:8 439 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 440 GET_VREG(r2, r1) @ r2<- fp[B] 441 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 442 SET_VREG(r2, r0) @ fp[A]<- r2 443 GOTO_OPCODE(ip) @ execute next instruction 444 445/* ------------------------------ */ 446 .balign 64 447.L_OP_MOVE_FROM16: /* 0x02 */ 448/* File: armv5te/OP_MOVE_FROM16.S */ 449 /* for: move/from16, move-object/from16 */ 450 /* op vAA, vBBBB */ 451 FETCH(r1, 1) @ r1<- BBBB 452 mov r0, rINST, lsr #8 @ r0<- AA 453 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 454 GET_VREG(r2, r1) @ r2<- fp[BBBB] 455 GET_INST_OPCODE(ip) @ extract opcode from rINST 456 SET_VREG(r2, r0) @ fp[AA]<- r2 457 GOTO_OPCODE(ip) @ jump to next instruction 458 459/* ------------------------------ */ 460 .balign 64 461.L_OP_MOVE_16: /* 0x03 */ 462/* File: armv5te/OP_MOVE_16.S */ 463 /* for: move/16, move-object/16 */ 464 /* op vAAAA, vBBBB */ 465 FETCH(r1, 2) @ r1<- BBBB 466 FETCH(r0, 1) @ r0<- AAAA 467 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 468 GET_VREG(r2, r1) @ r2<- fp[BBBB] 469 GET_INST_OPCODE(ip) @ extract opcode from rINST 470 SET_VREG(r2, r0) @ fp[AAAA]<- r2 471 GOTO_OPCODE(ip) @ jump to next instruction 472 473/* ------------------------------ */ 474 .balign 64 475.L_OP_MOVE_WIDE: /* 0x04 */ 476/* File: armv6t2/OP_MOVE_WIDE.S */ 477 /* move-wide vA, vB */ 478 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 479 mov r3, rINST, lsr #12 @ r3<- B 480 ubfx r2, rINST, #8, #4 @ r2<- A 481 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 482 add r2, rFP, r2, lsl #2 @ r2<- &fp[A] 483 ldmia r3, {r0-r1} @ r0/r1<- fp[B] 484 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 485 GET_INST_OPCODE(ip) @ extract opcode from rINST 486 stmia r2, {r0-r1} @ fp[A]<- r0/r1 487 GOTO_OPCODE(ip) @ jump to next instruction 488 489/* ------------------------------ */ 490 .balign 64 491.L_OP_MOVE_WIDE_FROM16: /* 0x05 */ 492/* File: armv5te/OP_MOVE_WIDE_FROM16.S */ 493 /* move-wide/from16 vAA, vBBBB */ 494 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 495 FETCH(r3, 1) @ r3<- BBBB 496 mov r2, rINST, lsr #8 @ r2<- AA 497 add r3, rFP, r3, lsl #2 @ r3<- &fp[BBBB] 498 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 499 ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB] 500 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 501 GET_INST_OPCODE(ip) @ extract opcode from rINST 502 stmia r2, {r0-r1} @ fp[AA]<- r0/r1 503 GOTO_OPCODE(ip) @ jump to next instruction 504 505/* ------------------------------ */ 506 .balign 64 507.L_OP_MOVE_WIDE_16: /* 0x06 */ 508/* File: armv5te/OP_MOVE_WIDE_16.S */ 509 /* move-wide/16 vAAAA, vBBBB */ 510 /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */ 511 FETCH(r3, 2) @ r3<- BBBB 512 FETCH(r2, 1) @ r2<- AAAA 513 add r3, rFP, r3, lsl #2 @ r3<- &fp[BBBB] 514 add r2, rFP, r2, lsl #2 @ r2<- &fp[AAAA] 515 ldmia r3, {r0-r1} @ r0/r1<- fp[BBBB] 516 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 517 GET_INST_OPCODE(ip) @ extract opcode from rINST 518 stmia r2, {r0-r1} @ fp[AAAA]<- r0/r1 519 GOTO_OPCODE(ip) @ jump to next instruction 520 521/* ------------------------------ */ 522 .balign 64 523.L_OP_MOVE_OBJECT: /* 0x07 */ 524/* File: armv5te/OP_MOVE_OBJECT.S */ 525/* File: armv5te/OP_MOVE.S */ 526 /* for move, move-object, long-to-int */ 527 /* op vA, vB */ 528 mov r1, rINST, lsr #12 @ r1<- B from 15:12 529 mov r0, rINST, lsr #8 @ r0<- A from 11:8 530 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 531 GET_VREG(r2, r1) @ r2<- fp[B] 532 and r0, r0, #15 533 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 534 SET_VREG(r2, r0) @ fp[A]<- r2 535 GOTO_OPCODE(ip) @ execute next instruction 536 537 538/* ------------------------------ */ 539 .balign 64 540.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */ 541/* File: armv5te/OP_MOVE_OBJECT_FROM16.S */ 542/* File: armv5te/OP_MOVE_FROM16.S */ 543 /* for: move/from16, move-object/from16 */ 544 /* op vAA, vBBBB */ 545 FETCH(r1, 1) @ r1<- BBBB 546 mov r0, rINST, lsr #8 @ r0<- AA 547 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 548 GET_VREG(r2, r1) @ r2<- fp[BBBB] 549 GET_INST_OPCODE(ip) @ extract opcode from rINST 550 SET_VREG(r2, r0) @ fp[AA]<- r2 551 GOTO_OPCODE(ip) @ jump to next instruction 552 553 554/* ------------------------------ */ 555 .balign 64 556.L_OP_MOVE_OBJECT_16: /* 0x09 */ 557/* File: armv5te/OP_MOVE_OBJECT_16.S */ 558/* File: armv5te/OP_MOVE_16.S */ 559 /* for: move/16, move-object/16 */ 560 /* op vAAAA, vBBBB */ 561 FETCH(r1, 2) @ r1<- BBBB 562 FETCH(r0, 1) @ r0<- AAAA 563 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 564 GET_VREG(r2, r1) @ r2<- fp[BBBB] 565 GET_INST_OPCODE(ip) @ extract opcode from rINST 566 SET_VREG(r2, r0) @ fp[AAAA]<- r2 567 GOTO_OPCODE(ip) @ jump to next instruction 568 569 570/* ------------------------------ */ 571 .balign 64 572.L_OP_MOVE_RESULT: /* 0x0a */ 573/* File: armv5te/OP_MOVE_RESULT.S */ 574 /* for: move-result, move-result-object */ 575 /* op vAA */ 576 mov r2, rINST, lsr #8 @ r2<- AA 577 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 578 ldr r0, [rSELF, #offThread_retval] @ r0<- self->retval.i 579 GET_INST_OPCODE(ip) @ extract opcode from rINST 580 SET_VREG(r0, r2) @ fp[AA]<- r0 581 GOTO_OPCODE(ip) @ jump to next instruction 582 583/* ------------------------------ */ 584 .balign 64 585.L_OP_MOVE_RESULT_WIDE: /* 0x0b */ 586/* File: armv5te/OP_MOVE_RESULT_WIDE.S */ 587 /* move-result-wide vAA */ 588 mov r2, rINST, lsr #8 @ r2<- AA 589 add r3, rSELF, #offThread_retval @ r3<- &self->retval 590 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 591 ldmia r3, {r0-r1} @ r0/r1<- retval.j 592 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 593 GET_INST_OPCODE(ip) @ extract opcode from rINST 594 stmia r2, {r0-r1} @ fp[AA]<- r0/r1 595 GOTO_OPCODE(ip) @ jump to next instruction 596 597/* ------------------------------ */ 598 .balign 64 599.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */ 600/* File: armv5te/OP_MOVE_RESULT_OBJECT.S */ 601/* File: armv5te/OP_MOVE_RESULT.S */ 602 /* for: move-result, move-result-object */ 603 /* op vAA */ 604 mov r2, rINST, lsr #8 @ r2<- AA 605 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 606 ldr r0, [rSELF, #offThread_retval] @ r0<- self->retval.i 607 GET_INST_OPCODE(ip) @ extract opcode from rINST 608 SET_VREG(r0, r2) @ fp[AA]<- r0 609 GOTO_OPCODE(ip) @ jump to next instruction 610 611 612/* ------------------------------ */ 613 .balign 64 614.L_OP_MOVE_EXCEPTION: /* 0x0d */ 615/* File: armv5te/OP_MOVE_EXCEPTION.S */ 616 /* move-exception vAA */ 617 mov r2, rINST, lsr #8 @ r2<- AA 618 ldr r3, [rSELF, #offThread_exception] @ r3<- dvmGetException bypass 619 mov r1, #0 @ r1<- 0 620 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 621 SET_VREG(r3, r2) @ fp[AA]<- exception obj 622 GET_INST_OPCODE(ip) @ extract opcode from rINST 623 str r1, [rSELF, #offThread_exception] @ dvmClearException bypass 624 GOTO_OPCODE(ip) @ jump to next instruction 625 626/* ------------------------------ */ 627 .balign 64 628.L_OP_RETURN_VOID: /* 0x0e */ 629/* File: armv5te/OP_RETURN_VOID.S */ 630 b common_returnFromMethod 631 632/* ------------------------------ */ 633 .balign 64 634.L_OP_RETURN: /* 0x0f */ 635/* File: armv5te/OP_RETURN.S */ 636 /* 637 * Return a 32-bit value. Copies the return value into the "thread" 638 * structure, then jumps to the return handler. 639 * 640 * for: return, return-object 641 */ 642 /* op vAA */ 643 mov r2, rINST, lsr #8 @ r2<- AA 644 GET_VREG(r0, r2) @ r0<- vAA 645 str r0, [rSELF, #offThread_retval] @ retval.i <- vAA 646 b common_returnFromMethod 647 648/* ------------------------------ */ 649 .balign 64 650.L_OP_RETURN_WIDE: /* 0x10 */ 651/* File: armv5te/OP_RETURN_WIDE.S */ 652 /* 653 * Return a 64-bit value. Copies the return value into the "thread" 654 * structure, then jumps to the return handler. 655 */ 656 /* return-wide vAA */ 657 mov r2, rINST, lsr #8 @ r2<- AA 658 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 659 add r3, rSELF, #offThread_retval @ r3<- &self->retval 660 ldmia r2, {r0-r1} @ r0/r1 <- vAA/vAA+1 661 stmia r3, {r0-r1} @ retval<- r0/r1 662 b common_returnFromMethod 663 664/* ------------------------------ */ 665 .balign 64 666.L_OP_RETURN_OBJECT: /* 0x11 */ 667/* File: armv5te/OP_RETURN_OBJECT.S */ 668/* File: armv5te/OP_RETURN.S */ 669 /* 670 * Return a 32-bit value. Copies the return value into the "thread" 671 * structure, then jumps to the return handler. 672 * 673 * for: return, return-object 674 */ 675 /* op vAA */ 676 mov r2, rINST, lsr #8 @ r2<- AA 677 GET_VREG(r0, r2) @ r0<- vAA 678 str r0, [rSELF, #offThread_retval] @ retval.i <- vAA 679 b common_returnFromMethod 680 681 682/* ------------------------------ */ 683 .balign 64 684.L_OP_CONST_4: /* 0x12 */ 685/* File: armv6t2/OP_CONST_4.S */ 686 /* const/4 vA, #+B */ 687 mov r1, rINST, lsl #16 @ r1<- Bxxx0000 688 ubfx r0, rINST, #8, #4 @ r0<- A 689 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 690 mov r1, r1, asr #28 @ r1<- sssssssB (sign-extended) 691 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 692 SET_VREG(r1, r0) @ fp[A]<- r1 693 GOTO_OPCODE(ip) @ execute next instruction 694 695/* ------------------------------ */ 696 .balign 64 697.L_OP_CONST_16: /* 0x13 */ 698/* File: armv5te/OP_CONST_16.S */ 699 /* const/16 vAA, #+BBBB */ 700 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 701 mov r3, rINST, lsr #8 @ r3<- AA 702 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 703 SET_VREG(r0, r3) @ vAA<- r0 704 GET_INST_OPCODE(ip) @ extract opcode from rINST 705 GOTO_OPCODE(ip) @ jump to next instruction 706 707/* ------------------------------ */ 708 .balign 64 709.L_OP_CONST: /* 0x14 */ 710/* File: armv5te/OP_CONST.S */ 711 /* const vAA, #+BBBBbbbb */ 712 mov r3, rINST, lsr #8 @ r3<- AA 713 FETCH(r0, 1) @ r0<- bbbb (low) 714 FETCH(r1, 2) @ r1<- BBBB (high) 715 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 716 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 717 GET_INST_OPCODE(ip) @ extract opcode from rINST 718 SET_VREG(r0, r3) @ vAA<- r0 719 GOTO_OPCODE(ip) @ jump to next instruction 720 721/* ------------------------------ */ 722 .balign 64 723.L_OP_CONST_HIGH16: /* 0x15 */ 724/* File: armv5te/OP_CONST_HIGH16.S */ 725 /* const/high16 vAA, #+BBBB0000 */ 726 FETCH(r0, 1) @ r0<- 0000BBBB (zero-extended) 727 mov r3, rINST, lsr #8 @ r3<- AA 728 mov r0, r0, lsl #16 @ r0<- BBBB0000 729 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 730 SET_VREG(r0, r3) @ vAA<- r0 731 GET_INST_OPCODE(ip) @ extract opcode from rINST 732 GOTO_OPCODE(ip) @ jump to next instruction 733 734/* ------------------------------ */ 735 .balign 64 736.L_OP_CONST_WIDE_16: /* 0x16 */ 737/* File: armv5te/OP_CONST_WIDE_16.S */ 738 /* const-wide/16 vAA, #+BBBB */ 739 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 740 mov r3, rINST, lsr #8 @ r3<- AA 741 mov r1, r0, asr #31 @ r1<- ssssssss 742 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 743 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 744 GET_INST_OPCODE(ip) @ extract opcode from rINST 745 stmia r3, {r0-r1} @ vAA<- r0/r1 746 GOTO_OPCODE(ip) @ jump to next instruction 747 748/* ------------------------------ */ 749 .balign 64 750.L_OP_CONST_WIDE_32: /* 0x17 */ 751/* File: armv5te/OP_CONST_WIDE_32.S */ 752 /* const-wide/32 vAA, #+BBBBbbbb */ 753 FETCH(r0, 1) @ r0<- 0000bbbb (low) 754 mov r3, rINST, lsr #8 @ r3<- AA 755 FETCH_S(r2, 2) @ r2<- ssssBBBB (high) 756 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 757 orr r0, r0, r2, lsl #16 @ r0<- BBBBbbbb 758 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 759 mov r1, r0, asr #31 @ r1<- ssssssss 760 GET_INST_OPCODE(ip) @ extract opcode from rINST 761 stmia r3, {r0-r1} @ vAA<- r0/r1 762 GOTO_OPCODE(ip) @ jump to next instruction 763 764/* ------------------------------ */ 765 .balign 64 766.L_OP_CONST_WIDE: /* 0x18 */ 767/* File: armv5te/OP_CONST_WIDE.S */ 768 /* const-wide vAA, #+HHHHhhhhBBBBbbbb */ 769 FETCH(r0, 1) @ r0<- bbbb (low) 770 FETCH(r1, 2) @ r1<- BBBB (low middle) 771 FETCH(r2, 3) @ r2<- hhhh (high middle) 772 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb (low word) 773 FETCH(r3, 4) @ r3<- HHHH (high) 774 mov r9, rINST, lsr #8 @ r9<- AA 775 orr r1, r2, r3, lsl #16 @ r1<- HHHHhhhh (high word) 776 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 777 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 778 GET_INST_OPCODE(ip) @ extract opcode from rINST 779 stmia r9, {r0-r1} @ vAA<- r0/r1 780 GOTO_OPCODE(ip) @ jump to next instruction 781 782/* ------------------------------ */ 783 .balign 64 784.L_OP_CONST_WIDE_HIGH16: /* 0x19 */ 785/* File: armv5te/OP_CONST_WIDE_HIGH16.S */ 786 /* const-wide/high16 vAA, #+BBBB000000000000 */ 787 FETCH(r1, 1) @ r1<- 0000BBBB (zero-extended) 788 mov r3, rINST, lsr #8 @ r3<- AA 789 mov r0, #0 @ r0<- 00000000 790 mov r1, r1, lsl #16 @ r1<- BBBB0000 791 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 792 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 793 GET_INST_OPCODE(ip) @ extract opcode from rINST 794 stmia r3, {r0-r1} @ vAA<- r0/r1 795 GOTO_OPCODE(ip) @ jump to next instruction 796 797/* ------------------------------ */ 798 .balign 64 799.L_OP_CONST_STRING: /* 0x1a */ 800/* File: armv5te/OP_CONST_STRING.S */ 801 /* const/string vAA, String@BBBB */ 802 FETCH(r1, 1) @ r1<- BBBB 803 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 804 mov r9, rINST, lsr #8 @ r9<- AA 805 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 806 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 807 cmp r0, #0 @ not yet resolved? 808 beq .LOP_CONST_STRING_resolve 809 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 810 GET_INST_OPCODE(ip) @ extract opcode from rINST 811 SET_VREG(r0, r9) @ vAA<- r0 812 GOTO_OPCODE(ip) @ jump to next instruction 813 814/* ------------------------------ */ 815 .balign 64 816.L_OP_CONST_STRING_JUMBO: /* 0x1b */ 817/* File: armv5te/OP_CONST_STRING_JUMBO.S */ 818 /* const/string vAA, String@BBBBBBBB */ 819 FETCH(r0, 1) @ r0<- bbbb (low) 820 FETCH(r1, 2) @ r1<- BBBB (high) 821 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 822 mov r9, rINST, lsr #8 @ r9<- AA 823 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 824 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 825 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 826 cmp r0, #0 827 beq .LOP_CONST_STRING_JUMBO_resolve 828 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 829 GET_INST_OPCODE(ip) @ extract opcode from rINST 830 SET_VREG(r0, r9) @ vAA<- r0 831 GOTO_OPCODE(ip) @ jump to next instruction 832 833/* ------------------------------ */ 834 .balign 64 835.L_OP_CONST_CLASS: /* 0x1c */ 836/* File: armv5te/OP_CONST_CLASS.S */ 837 /* const/class vAA, Class@BBBB */ 838 FETCH(r1, 1) @ r1<- BBBB 839 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- self->methodClassDex 840 mov r9, rINST, lsr #8 @ r9<- AA 841 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- dvmDex->pResClasses 842 ldr r0, [r2, r1, lsl #2] @ r0<- pResClasses[BBBB] 843 cmp r0, #0 @ not yet resolved? 844 beq .LOP_CONST_CLASS_resolve 845 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 846 GET_INST_OPCODE(ip) @ extract opcode from rINST 847 SET_VREG(r0, r9) @ vAA<- r0 848 GOTO_OPCODE(ip) @ jump to next instruction 849 850/* ------------------------------ */ 851 .balign 64 852.L_OP_MONITOR_ENTER: /* 0x1d */ 853/* File: armv5te/OP_MONITOR_ENTER.S */ 854 /* 855 * Synchronize on an object. 856 */ 857 /* monitor-enter vAA */ 858 mov r2, rINST, lsr #8 @ r2<- AA 859 GET_VREG(r1, r2) @ r1<- vAA (object) 860 mov r0, rSELF @ r0<- self 861 cmp r1, #0 @ null object? 862 EXPORT_PC() @ need for precise GC 863 beq common_errNullObject @ null object, throw an exception 864 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 865 bl dvmLockObject @ call(self, obj) 866 GET_INST_OPCODE(ip) @ extract opcode from rINST 867 GOTO_OPCODE(ip) @ jump to next instruction 868 869/* ------------------------------ */ 870 .balign 64 871.L_OP_MONITOR_EXIT: /* 0x1e */ 872/* File: armv5te/OP_MONITOR_EXIT.S */ 873 /* 874 * Unlock an object. 875 * 876 * Exceptions that occur when unlocking a monitor need to appear as 877 * if they happened at the following instruction. See the Dalvik 878 * instruction spec. 879 */ 880 /* monitor-exit vAA */ 881 mov r2, rINST, lsr #8 @ r2<- AA 882 EXPORT_PC() @ before fetch: export the PC 883 GET_VREG(r1, r2) @ r1<- vAA (object) 884 cmp r1, #0 @ null object? 885 beq 1f @ yes 886 mov r0, rSELF @ r0<- self 887 bl dvmUnlockObject @ r0<- success for unlock(self, obj) 888 cmp r0, #0 @ failed? 889 FETCH_ADVANCE_INST(1) @ before throw: advance rPC, load rINST 890 beq common_exceptionThrown @ yes, exception is pending 891 GET_INST_OPCODE(ip) @ extract opcode from rINST 892 GOTO_OPCODE(ip) @ jump to next instruction 8931: 894 FETCH_ADVANCE_INST(1) @ advance before throw 895 b common_errNullObject 896 897/* ------------------------------ */ 898 .balign 64 899.L_OP_CHECK_CAST: /* 0x1f */ 900/* File: armv5te/OP_CHECK_CAST.S */ 901 /* 902 * Check to see if a cast from one class to another is allowed. 903 */ 904 /* check-cast vAA, class@BBBB */ 905 mov r3, rINST, lsr #8 @ r3<- AA 906 FETCH(r2, 1) @ r2<- BBBB 907 GET_VREG(r9, r3) @ r9<- object 908 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- pDvmDex 909 cmp r9, #0 @ is object null? 910 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 911 beq .LOP_CHECK_CAST_okay @ null obj, cast always succeeds 912 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 913 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 914 cmp r1, #0 @ have we resolved this before? 915 beq .LOP_CHECK_CAST_resolve @ not resolved, do it now 916.LOP_CHECK_CAST_resolved: 917 cmp r0, r1 @ same class (trivial success)? 918 bne .LOP_CHECK_CAST_fullcheck @ no, do full check 919.LOP_CHECK_CAST_okay: 920 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 921 GET_INST_OPCODE(ip) @ extract opcode from rINST 922 GOTO_OPCODE(ip) @ jump to next instruction 923 924/* ------------------------------ */ 925 .balign 64 926.L_OP_INSTANCE_OF: /* 0x20 */ 927/* File: armv5te/OP_INSTANCE_OF.S */ 928 /* 929 * Check to see if an object reference is an instance of a class. 930 * 931 * Most common situation is a non-null object, being compared against 932 * an already-resolved class. 933 */ 934 /* instance-of vA, vB, class@CCCC */ 935 mov r3, rINST, lsr #12 @ r3<- B 936 mov r9, rINST, lsr #8 @ r9<- A+ 937 GET_VREG(r0, r3) @ r0<- vB (object) 938 and r9, r9, #15 @ r9<- A 939 cmp r0, #0 @ is object null? 940 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- pDvmDex 941 beq .LOP_INSTANCE_OF_store @ null obj, not an instance, store r0 942 FETCH(r3, 1) @ r3<- CCCC 943 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 944 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 945 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 946 cmp r1, #0 @ have we resolved this before? 947 beq .LOP_INSTANCE_OF_resolve @ not resolved, do it now 948.LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class 949 cmp r0, r1 @ same class (trivial success)? 950 beq .LOP_INSTANCE_OF_trivial @ yes, trivial finish 951 b .LOP_INSTANCE_OF_fullcheck @ no, do full check 952 953/* ------------------------------ */ 954 .balign 64 955.L_OP_ARRAY_LENGTH: /* 0x21 */ 956/* File: armv6t2/OP_ARRAY_LENGTH.S */ 957 /* 958 * Return the length of an array. 959 */ 960 mov r1, rINST, lsr #12 @ r1<- B 961 ubfx r2, rINST, #8, #4 @ r2<- A 962 GET_VREG(r0, r1) @ r0<- vB (object ref) 963 cmp r0, #0 @ is object null? 964 beq common_errNullObject @ yup, fail 965 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 966 ldr r3, [r0, #offArrayObject_length] @ r3<- array length 967 GET_INST_OPCODE(ip) @ extract opcode from rINST 968 SET_VREG(r3, r2) @ vB<- length 969 GOTO_OPCODE(ip) @ jump to next instruction 970 971/* ------------------------------ */ 972 .balign 64 973.L_OP_NEW_INSTANCE: /* 0x22 */ 974/* File: armv5te/OP_NEW_INSTANCE.S */ 975 /* 976 * Create a new instance of a class. 977 */ 978 /* new-instance vAA, class@BBBB */ 979 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 980 FETCH(r1, 1) @ r1<- BBBB 981 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 982 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 983 EXPORT_PC() @ req'd for init, resolve, alloc 984 cmp r0, #0 @ already resolved? 985 beq .LOP_NEW_INSTANCE_resolve @ no, resolve it now 986.LOP_NEW_INSTANCE_resolved: @ r0=class 987 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 988 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 989 bne .LOP_NEW_INSTANCE_needinit @ no, init class now 990.LOP_NEW_INSTANCE_initialized: @ r0=class 991 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 992 bl dvmAllocObject @ r0<- new object 993 b .LOP_NEW_INSTANCE_finish @ continue 994 995/* ------------------------------ */ 996 .balign 64 997.L_OP_NEW_ARRAY: /* 0x23 */ 998/* File: armv5te/OP_NEW_ARRAY.S */ 999 /* 1000 * Allocate an array of objects, specified with the array class 1001 * and a count. 1002 * 1003 * The verifier guarantees that this is an array class, so we don't 1004 * check for it here. 1005 */ 1006 /* new-array vA, vB, class@CCCC */ 1007 mov r0, rINST, lsr #12 @ r0<- B 1008 FETCH(r2, 1) @ r2<- CCCC 1009 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 1010 GET_VREG(r1, r0) @ r1<- vB (array length) 1011 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1012 cmp r1, #0 @ check length 1013 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 1014 bmi common_errNegativeArraySize @ negative length, bail - len in r1 1015 cmp r0, #0 @ already resolved? 1016 EXPORT_PC() @ req'd for resolve, alloc 1017 bne .LOP_NEW_ARRAY_finish @ resolved, continue 1018 b .LOP_NEW_ARRAY_resolve @ do resolve now 1019 1020/* ------------------------------ */ 1021 .balign 64 1022.L_OP_FILLED_NEW_ARRAY: /* 0x24 */ 1023/* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1024 /* 1025 * Create a new array with elements filled from registers. 1026 * 1027 * for: filled-new-array, filled-new-array/range 1028 */ 1029 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1030 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1031 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 1032 FETCH(r1, 1) @ r1<- BBBB 1033 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1034 EXPORT_PC() @ need for resolve and alloc 1035 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1036 mov r10, rINST, lsr #8 @ r10<- AA or BA 1037 cmp r0, #0 @ already resolved? 1038 bne .LOP_FILLED_NEW_ARRAY_continue @ yes, continue on 10398: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 1040 mov r2, #0 @ r2<- false 1041 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1042 bl dvmResolveClass @ r0<- call(clazz, ref) 1043 cmp r0, #0 @ got null? 1044 beq common_exceptionThrown @ yes, handle exception 1045 b .LOP_FILLED_NEW_ARRAY_continue 1046 1047/* ------------------------------ */ 1048 .balign 64 1049.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 1050/* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */ 1051/* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1052 /* 1053 * Create a new array with elements filled from registers. 1054 * 1055 * for: filled-new-array, filled-new-array/range 1056 */ 1057 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1058 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1059 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 1060 FETCH(r1, 1) @ r1<- BBBB 1061 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1062 EXPORT_PC() @ need for resolve and alloc 1063 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1064 mov r10, rINST, lsr #8 @ r10<- AA or BA 1065 cmp r0, #0 @ already resolved? 1066 bne .LOP_FILLED_NEW_ARRAY_RANGE_continue @ yes, continue on 10678: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 1068 mov r2, #0 @ r2<- false 1069 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1070 bl dvmResolveClass @ r0<- call(clazz, ref) 1071 cmp r0, #0 @ got null? 1072 beq common_exceptionThrown @ yes, handle exception 1073 b .LOP_FILLED_NEW_ARRAY_RANGE_continue 1074 1075 1076/* ------------------------------ */ 1077 .balign 64 1078.L_OP_FILL_ARRAY_DATA: /* 0x26 */ 1079/* File: armv5te/OP_FILL_ARRAY_DATA.S */ 1080 /* fill-array-data vAA, +BBBBBBBB */ 1081 FETCH(r0, 1) @ r0<- bbbb (lo) 1082 FETCH(r1, 2) @ r1<- BBBB (hi) 1083 mov r3, rINST, lsr #8 @ r3<- AA 1084 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 1085 GET_VREG(r0, r3) @ r0<- vAA (array object) 1086 add r1, rPC, r1, lsl #1 @ r1<- PC + BBBBbbbb*2 (array data off.) 1087 EXPORT_PC(); 1088 bl dvmInterpHandleFillArrayData@ fill the array with predefined data 1089 cmp r0, #0 @ 0 means an exception is thrown 1090 beq common_exceptionThrown @ has exception 1091 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 1092 GET_INST_OPCODE(ip) @ extract opcode from rINST 1093 GOTO_OPCODE(ip) @ jump to next instruction 1094 1095/* ------------------------------ */ 1096 .balign 64 1097.L_OP_THROW: /* 0x27 */ 1098/* File: armv5te/OP_THROW.S */ 1099 /* 1100 * Throw an exception object in the current thread. 1101 */ 1102 /* throw vAA */ 1103 mov r2, rINST, lsr #8 @ r2<- AA 1104 GET_VREG(r1, r2) @ r1<- vAA (exception object) 1105 EXPORT_PC() @ exception handler can throw 1106 cmp r1, #0 @ null object? 1107 beq common_errNullObject @ yes, throw an NPE instead 1108 @ bypass dvmSetException, just store it 1109 str r1, [rSELF, #offThread_exception] @ thread->exception<- obj 1110 b common_exceptionThrown 1111 1112/* ------------------------------ */ 1113 .balign 64 1114.L_OP_GOTO: /* 0x28 */ 1115/* File: armv5te/OP_GOTO.S */ 1116 /* 1117 * Unconditional branch, 8-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 /* goto +AA */ 1123 mov r0, rINST, lsl #16 @ r0<- AAxx0000 1124 movs r9, r0, asr #24 @ r9<- ssssssAA (sign-extended) 1125 mov r9, r9, lsl #1 @ r9<- byte offset 1126 bmi common_backwardBranch @ backward branch, do periodic checks 1127#if defined(WITH_JIT) 1128 GET_JIT_PROF_TABLE(r0) 1129 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1130 cmp r0,#0 1131 bne common_updateProfile 1132 GET_INST_OPCODE(ip) @ extract opcode from rINST 1133 GOTO_OPCODE(ip) @ jump to next instruction 1134#else 1135 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1136 GET_INST_OPCODE(ip) @ extract opcode from rINST 1137 GOTO_OPCODE(ip) @ jump to next instruction 1138#endif 1139 1140/* ------------------------------ */ 1141 .balign 64 1142.L_OP_GOTO_16: /* 0x29 */ 1143/* File: armv5te/OP_GOTO_16.S */ 1144 /* 1145 * Unconditional branch, 16-bit offset. 1146 * 1147 * The branch distance is a signed code-unit offset, which we need to 1148 * double to get a byte offset. 1149 */ 1150 /* goto/16 +AAAA */ 1151 FETCH_S(r0, 1) @ r0<- ssssAAAA (sign-extended) 1152 movs r9, r0, asl #1 @ r9<- byte offset, check sign 1153 bmi common_backwardBranch @ backward branch, do periodic checks 1154#if defined(WITH_JIT) 1155 GET_JIT_PROF_TABLE(r0) 1156 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1157 cmp r0,#0 1158 bne common_updateProfile 1159 GET_INST_OPCODE(ip) @ extract opcode from rINST 1160 GOTO_OPCODE(ip) @ jump to next instruction 1161#else 1162 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1163 GET_INST_OPCODE(ip) @ extract opcode from rINST 1164 GOTO_OPCODE(ip) @ jump to next instruction 1165#endif 1166 1167/* ------------------------------ */ 1168 .balign 64 1169.L_OP_GOTO_32: /* 0x2a */ 1170/* File: armv5te/OP_GOTO_32.S */ 1171 /* 1172 * Unconditional branch, 32-bit offset. 1173 * 1174 * The branch distance is a signed code-unit offset, which we need to 1175 * double to get a byte offset. 1176 * 1177 * Unlike most opcodes, this one is allowed to branch to itself, so 1178 * our "backward branch" test must be "<=0" instead of "<0". The ORRS 1179 * instruction doesn't affect the V flag, so we need to clear it 1180 * explicitly. 1181 */ 1182 /* goto/32 +AAAAAAAA */ 1183 FETCH(r0, 1) @ r0<- aaaa (lo) 1184 FETCH(r1, 2) @ r1<- AAAA (hi) 1185 cmp ip, ip @ (clear V flag during stall) 1186 orrs r0, r0, r1, lsl #16 @ r0<- AAAAaaaa, check sign 1187 mov r9, r0, asl #1 @ r9<- byte offset 1188 ble common_backwardBranch @ backward branch, do periodic checks 1189#if defined(WITH_JIT) 1190 GET_JIT_PROF_TABLE(r0) 1191 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1192 cmp r0,#0 1193 bne common_updateProfile 1194 GET_INST_OPCODE(ip) @ extract opcode from rINST 1195 GOTO_OPCODE(ip) @ jump to next instruction 1196#else 1197 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1198 GET_INST_OPCODE(ip) @ extract opcode from rINST 1199 GOTO_OPCODE(ip) @ jump to next instruction 1200#endif 1201 1202/* ------------------------------ */ 1203 .balign 64 1204.L_OP_PACKED_SWITCH: /* 0x2b */ 1205/* File: armv5te/OP_PACKED_SWITCH.S */ 1206 /* 1207 * Handle a packed-switch or sparse-switch instruction. In both cases 1208 * we decode it and hand it off to a helper function. 1209 * 1210 * We don't really expect backward branches in a switch statement, but 1211 * they're perfectly legal, so we check for them here. 1212 * 1213 * for: packed-switch, sparse-switch 1214 */ 1215 /* op vAA, +BBBB */ 1216 FETCH(r0, 1) @ r0<- bbbb (lo) 1217 FETCH(r1, 2) @ r1<- BBBB (hi) 1218 mov r3, rINST, lsr #8 @ r3<- AA 1219 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1220 GET_VREG(r1, r3) @ r1<- vAA 1221 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1222 bl dvmInterpHandlePackedSwitch @ r0<- code-unit branch offset 1223 movs r9, r0, asl #1 @ r9<- branch byte offset, check sign 1224 bmi common_backwardBranch @ backward branch, do periodic checks 1225 beq common_backwardBranch @ (want to use BLE but V is unknown) 1226#if defined(WITH_JIT) 1227 GET_JIT_PROF_TABLE(r0) 1228 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1229 cmp r0,#0 1230 bne common_updateProfile 1231 GET_INST_OPCODE(ip) @ extract opcode from rINST 1232 GOTO_OPCODE(ip) @ jump to next instruction 1233#else 1234 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1235 GET_INST_OPCODE(ip) @ extract opcode from rINST 1236 GOTO_OPCODE(ip) @ jump to next instruction 1237#endif 1238 1239/* ------------------------------ */ 1240 .balign 64 1241.L_OP_SPARSE_SWITCH: /* 0x2c */ 1242/* File: armv5te/OP_SPARSE_SWITCH.S */ 1243/* File: armv5te/OP_PACKED_SWITCH.S */ 1244 /* 1245 * Handle a packed-switch or sparse-switch instruction. In both cases 1246 * we decode it and hand it off to a helper function. 1247 * 1248 * We don't really expect backward branches in a switch statement, but 1249 * they're perfectly legal, so we check for them here. 1250 * 1251 * for: packed-switch, sparse-switch 1252 */ 1253 /* op vAA, +BBBB */ 1254 FETCH(r0, 1) @ r0<- bbbb (lo) 1255 FETCH(r1, 2) @ r1<- BBBB (hi) 1256 mov r3, rINST, lsr #8 @ r3<- AA 1257 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1258 GET_VREG(r1, r3) @ r1<- vAA 1259 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1260 bl dvmInterpHandleSparseSwitch @ r0<- code-unit branch offset 1261 movs r9, r0, asl #1 @ r9<- branch byte offset, check sign 1262 bmi common_backwardBranch @ backward branch, do periodic checks 1263 beq common_backwardBranch @ (want to use BLE but V is unknown) 1264#if defined(WITH_JIT) 1265 GET_JIT_PROF_TABLE(r0) 1266 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1267 cmp r0,#0 1268 bne common_updateProfile 1269 GET_INST_OPCODE(ip) @ extract opcode from rINST 1270 GOTO_OPCODE(ip) @ jump to next instruction 1271#else 1272 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1273 GET_INST_OPCODE(ip) @ extract opcode from rINST 1274 GOTO_OPCODE(ip) @ jump to next instruction 1275#endif 1276 1277 1278/* ------------------------------ */ 1279 .balign 64 1280.L_OP_CMPL_FLOAT: /* 0x2d */ 1281/* File: arm-vfp/OP_CMPL_FLOAT.S */ 1282 /* 1283 * Compare two floating-point values. Puts 0, 1, or -1 into the 1284 * destination register based on the results of the comparison. 1285 * 1286 * int compare(x, y) { 1287 * if (x == y) { 1288 * return 0; 1289 * } else if (x > y) { 1290 * return 1; 1291 * } else if (x < y) { 1292 * return -1; 1293 * } else { 1294 * return -1; 1295 * } 1296 * } 1297 */ 1298 /* op vAA, vBB, vCC */ 1299 FETCH(r0, 1) @ r0<- CCBB 1300 mov r9, rINST, lsr #8 @ r9<- AA 1301 and r2, r0, #255 @ r2<- BB 1302 mov r3, r0, lsr #8 @ r3<- CC 1303 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1304 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1305 flds s0, [r2] @ s0<- vBB 1306 flds s1, [r3] @ s1<- vCC 1307 fcmpes s0, s1 @ compare (vBB, vCC) 1308 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1309 mvn r0, #0 @ r0<- -1 (default) 1310 GET_INST_OPCODE(ip) @ extract opcode from rINST 1311 fmstat @ export status flags 1312 movgt r0, #1 @ (greater than) r1<- 1 1313 moveq r0, #0 @ (equal) r1<- 0 1314 b .LOP_CMPL_FLOAT_finish @ argh 1315 1316 1317/* ------------------------------ */ 1318 .balign 64 1319.L_OP_CMPG_FLOAT: /* 0x2e */ 1320/* File: arm-vfp/OP_CMPG_FLOAT.S */ 1321 /* 1322 * Compare two floating-point values. Puts 0, 1, or -1 into the 1323 * destination register based on the results of the comparison. 1324 * 1325 * int compare(x, y) { 1326 * if (x == y) { 1327 * return 0; 1328 * } else if (x < y) { 1329 * return -1; 1330 * } else if (x > y) { 1331 * return 1; 1332 * } else { 1333 * return 1; 1334 * } 1335 * } 1336 */ 1337 /* op vAA, vBB, vCC */ 1338 FETCH(r0, 1) @ r0<- CCBB 1339 mov r9, rINST, lsr #8 @ r9<- AA 1340 and r2, r0, #255 @ r2<- BB 1341 mov r3, r0, lsr #8 @ r3<- CC 1342 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1343 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1344 flds s0, [r2] @ s0<- vBB 1345 flds s1, [r3] @ s1<- vCC 1346 fcmpes s0, s1 @ compare (vBB, vCC) 1347 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1348 mov r0, #1 @ r0<- 1 (default) 1349 GET_INST_OPCODE(ip) @ extract opcode from rINST 1350 fmstat @ export status flags 1351 mvnmi r0, #0 @ (less than) r1<- -1 1352 moveq r0, #0 @ (equal) r1<- 0 1353 b .LOP_CMPG_FLOAT_finish @ argh 1354 1355 1356/* ------------------------------ */ 1357 .balign 64 1358.L_OP_CMPL_DOUBLE: /* 0x2f */ 1359/* File: arm-vfp/OP_CMPL_DOUBLE.S */ 1360 /* 1361 * Compare two floating-point values. Puts 0, 1, or -1 into the 1362 * destination register based on the results of the comparison. 1363 * 1364 * int compare(x, y) { 1365 * if (x == y) { 1366 * return 0; 1367 * } else if (x > y) { 1368 * return 1; 1369 * } else if (x < y) { 1370 * return -1; 1371 * } else { 1372 * return -1; 1373 * } 1374 * } 1375 */ 1376 /* op vAA, vBB, vCC */ 1377 FETCH(r0, 1) @ r0<- CCBB 1378 mov r9, rINST, lsr #8 @ r9<- AA 1379 and r2, r0, #255 @ r2<- BB 1380 mov r3, r0, lsr #8 @ r3<- CC 1381 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1382 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1383 fldd d0, [r2] @ d0<- vBB 1384 fldd d1, [r3] @ d1<- vCC 1385 fcmped d0, d1 @ compare (vBB, vCC) 1386 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1387 mvn r0, #0 @ r0<- -1 (default) 1388 GET_INST_OPCODE(ip) @ extract opcode from rINST 1389 fmstat @ export status flags 1390 movgt r0, #1 @ (greater than) r1<- 1 1391 moveq r0, #0 @ (equal) r1<- 0 1392 b .LOP_CMPL_DOUBLE_finish @ argh 1393 1394 1395/* ------------------------------ */ 1396 .balign 64 1397.L_OP_CMPG_DOUBLE: /* 0x30 */ 1398/* File: arm-vfp/OP_CMPG_DOUBLE.S */ 1399 /* 1400 * Compare two floating-point values. Puts 0, 1, or -1 into the 1401 * destination register based on the results of the comparison. 1402 * 1403 * int compare(x, y) { 1404 * if (x == y) { 1405 * return 0; 1406 * } else if (x < y) { 1407 * return -1; 1408 * } else if (x > y) { 1409 * return 1; 1410 * } else { 1411 * return 1; 1412 * } 1413 * } 1414 */ 1415 /* op vAA, vBB, vCC */ 1416 FETCH(r0, 1) @ r0<- CCBB 1417 mov r9, rINST, lsr #8 @ r9<- AA 1418 and r2, r0, #255 @ r2<- BB 1419 mov r3, r0, lsr #8 @ r3<- CC 1420 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1421 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1422 fldd d0, [r2] @ d0<- vBB 1423 fldd d1, [r3] @ d1<- vCC 1424 fcmped d0, d1 @ compare (vBB, vCC) 1425 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1426 mov r0, #1 @ r0<- 1 (default) 1427 GET_INST_OPCODE(ip) @ extract opcode from rINST 1428 fmstat @ export status flags 1429 mvnmi r0, #0 @ (less than) r1<- -1 1430 moveq r0, #0 @ (equal) r1<- 0 1431 b .LOP_CMPG_DOUBLE_finish @ argh 1432 1433 1434/* ------------------------------ */ 1435 .balign 64 1436.L_OP_CMP_LONG: /* 0x31 */ 1437/* File: armv5te/OP_CMP_LONG.S */ 1438 /* 1439 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 1440 * register based on the results of the comparison. 1441 * 1442 * We load the full values with LDM, but in practice many values could 1443 * be resolved by only looking at the high word. This could be made 1444 * faster or slower by splitting the LDM into a pair of LDRs. 1445 * 1446 * If we just wanted to set condition flags, we could do this: 1447 * subs ip, r0, r2 1448 * sbcs ip, r1, r3 1449 * subeqs ip, r0, r2 1450 * Leaving { <0, 0, >0 } in ip. However, we have to set it to a specific 1451 * integer value, which we can do with 2 conditional mov/mvn instructions 1452 * (set 1, set -1; if they're equal we already have 0 in ip), giving 1453 * us a constant 5-cycle path plus a branch at the end to the 1454 * instruction epilogue code. The multi-compare approach below needs 1455 * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch 1456 * in the worst case (the 64-bit values are equal). 1457 */ 1458 /* cmp-long vAA, vBB, vCC */ 1459 FETCH(r0, 1) @ r0<- CCBB 1460 mov r9, rINST, lsr #8 @ r9<- AA 1461 and r2, r0, #255 @ r2<- BB 1462 mov r3, r0, lsr #8 @ r3<- CC 1463 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 1464 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 1465 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 1466 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 1467 cmp r1, r3 @ compare (vBB+1, vCC+1) 1468 blt .LOP_CMP_LONG_less @ signed compare on high part 1469 bgt .LOP_CMP_LONG_greater 1470 subs r1, r0, r2 @ r1<- r0 - r2 1471 bhi .LOP_CMP_LONG_greater @ unsigned compare on low part 1472 bne .LOP_CMP_LONG_less 1473 b .LOP_CMP_LONG_finish @ equal; r1 already holds 0 1474 1475/* ------------------------------ */ 1476 .balign 64 1477.L_OP_IF_EQ: /* 0x32 */ 1478/* File: armv6t2/OP_IF_EQ.S */ 1479/* File: armv6t2/bincmp.S */ 1480 /* 1481 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1482 * fragment that specifies the *reverse* comparison to perform, e.g. 1483 * for "if-le" you would use "gt". 1484 * 1485 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1486 */ 1487 /* if-cmp vA, vB, +CCCC */ 1488 mov r1, rINST, lsr #12 @ r1<- B 1489 ubfx r0, rINST, #8, #4 @ r0<- A 1490 GET_VREG(r3, r1) @ r3<- vB 1491 GET_VREG(r2, r0) @ r2<- vA 1492 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1493 cmp r2, r3 @ compare (vA, vB) 1494 bne 1f @ branch to 1 if comparison failed 1495 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1496 movs r9, r9, asl #1 @ convert to bytes, check sign 1497 bmi common_backwardBranch @ yes, do periodic checks 14981: 1499#if defined(WITH_JIT) 1500 GET_JIT_PROF_TABLE(r0) 1501 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1502 b common_testUpdateProfile 1503#else 1504 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1505 GET_INST_OPCODE(ip) @ extract opcode from rINST 1506 GOTO_OPCODE(ip) @ jump to next instruction 1507#endif 1508 1509 1510/* ------------------------------ */ 1511 .balign 64 1512.L_OP_IF_NE: /* 0x33 */ 1513/* File: armv6t2/OP_IF_NE.S */ 1514/* File: armv6t2/bincmp.S */ 1515 /* 1516 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1517 * fragment that specifies the *reverse* comparison to perform, e.g. 1518 * for "if-le" you would use "gt". 1519 * 1520 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1521 */ 1522 /* if-cmp vA, vB, +CCCC */ 1523 mov r1, rINST, lsr #12 @ r1<- B 1524 ubfx r0, rINST, #8, #4 @ r0<- A 1525 GET_VREG(r3, r1) @ r3<- vB 1526 GET_VREG(r2, r0) @ r2<- vA 1527 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1528 cmp r2, r3 @ compare (vA, vB) 1529 beq 1f @ branch to 1 if comparison failed 1530 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1531 movs r9, r9, asl #1 @ convert to bytes, check sign 1532 bmi common_backwardBranch @ yes, do periodic checks 15331: 1534#if defined(WITH_JIT) 1535 GET_JIT_PROF_TABLE(r0) 1536 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1537 b common_testUpdateProfile 1538#else 1539 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1540 GET_INST_OPCODE(ip) @ extract opcode from rINST 1541 GOTO_OPCODE(ip) @ jump to next instruction 1542#endif 1543 1544 1545/* ------------------------------ */ 1546 .balign 64 1547.L_OP_IF_LT: /* 0x34 */ 1548/* File: armv6t2/OP_IF_LT.S */ 1549/* File: armv6t2/bincmp.S */ 1550 /* 1551 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1552 * fragment that specifies the *reverse* comparison to perform, e.g. 1553 * for "if-le" you would use "gt". 1554 * 1555 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1556 */ 1557 /* if-cmp vA, vB, +CCCC */ 1558 mov r1, rINST, lsr #12 @ r1<- B 1559 ubfx r0, rINST, #8, #4 @ r0<- A 1560 GET_VREG(r3, r1) @ r3<- vB 1561 GET_VREG(r2, r0) @ r2<- vA 1562 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1563 cmp r2, r3 @ compare (vA, vB) 1564 bge 1f @ branch to 1 if comparison failed 1565 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1566 movs r9, r9, asl #1 @ convert to bytes, check sign 1567 bmi common_backwardBranch @ yes, do periodic checks 15681: 1569#if defined(WITH_JIT) 1570 GET_JIT_PROF_TABLE(r0) 1571 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1572 b common_testUpdateProfile 1573#else 1574 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1575 GET_INST_OPCODE(ip) @ extract opcode from rINST 1576 GOTO_OPCODE(ip) @ jump to next instruction 1577#endif 1578 1579 1580/* ------------------------------ */ 1581 .balign 64 1582.L_OP_IF_GE: /* 0x35 */ 1583/* File: armv6t2/OP_IF_GE.S */ 1584/* File: armv6t2/bincmp.S */ 1585 /* 1586 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1587 * fragment that specifies the *reverse* comparison to perform, e.g. 1588 * for "if-le" you would use "gt". 1589 * 1590 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1591 */ 1592 /* if-cmp vA, vB, +CCCC */ 1593 mov r1, rINST, lsr #12 @ r1<- B 1594 ubfx r0, rINST, #8, #4 @ r0<- A 1595 GET_VREG(r3, r1) @ r3<- vB 1596 GET_VREG(r2, r0) @ r2<- vA 1597 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1598 cmp r2, r3 @ compare (vA, vB) 1599 blt 1f @ branch to 1 if comparison failed 1600 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1601 movs r9, r9, asl #1 @ convert to bytes, check sign 1602 bmi common_backwardBranch @ yes, do periodic checks 16031: 1604#if defined(WITH_JIT) 1605 GET_JIT_PROF_TABLE(r0) 1606 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1607 b common_testUpdateProfile 1608#else 1609 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1610 GET_INST_OPCODE(ip) @ extract opcode from rINST 1611 GOTO_OPCODE(ip) @ jump to next instruction 1612#endif 1613 1614 1615/* ------------------------------ */ 1616 .balign 64 1617.L_OP_IF_GT: /* 0x36 */ 1618/* File: armv6t2/OP_IF_GT.S */ 1619/* File: armv6t2/bincmp.S */ 1620 /* 1621 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1622 * fragment that specifies the *reverse* comparison to perform, e.g. 1623 * for "if-le" you would use "gt". 1624 * 1625 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1626 */ 1627 /* if-cmp vA, vB, +CCCC */ 1628 mov r1, rINST, lsr #12 @ r1<- B 1629 ubfx r0, rINST, #8, #4 @ r0<- A 1630 GET_VREG(r3, r1) @ r3<- vB 1631 GET_VREG(r2, r0) @ r2<- vA 1632 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1633 cmp r2, r3 @ compare (vA, vB) 1634 ble 1f @ branch to 1 if comparison failed 1635 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1636 movs r9, r9, asl #1 @ convert to bytes, check sign 1637 bmi common_backwardBranch @ yes, do periodic checks 16381: 1639#if defined(WITH_JIT) 1640 GET_JIT_PROF_TABLE(r0) 1641 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1642 b common_testUpdateProfile 1643#else 1644 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1645 GET_INST_OPCODE(ip) @ extract opcode from rINST 1646 GOTO_OPCODE(ip) @ jump to next instruction 1647#endif 1648 1649 1650/* ------------------------------ */ 1651 .balign 64 1652.L_OP_IF_LE: /* 0x37 */ 1653/* File: armv6t2/OP_IF_LE.S */ 1654/* File: armv6t2/bincmp.S */ 1655 /* 1656 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1657 * fragment that specifies the *reverse* comparison to perform, e.g. 1658 * for "if-le" you would use "gt". 1659 * 1660 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1661 */ 1662 /* if-cmp vA, vB, +CCCC */ 1663 mov r1, rINST, lsr #12 @ r1<- B 1664 ubfx r0, rINST, #8, #4 @ r0<- A 1665 GET_VREG(r3, r1) @ r3<- vB 1666 GET_VREG(r2, r0) @ r2<- vA 1667 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1668 cmp r2, r3 @ compare (vA, vB) 1669 bgt 1f @ branch to 1 if comparison failed 1670 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1671 movs r9, r9, asl #1 @ convert to bytes, check sign 1672 bmi common_backwardBranch @ yes, do periodic checks 16731: 1674#if defined(WITH_JIT) 1675 GET_JIT_PROF_TABLE(r0) 1676 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1677 b common_testUpdateProfile 1678#else 1679 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1680 GET_INST_OPCODE(ip) @ extract opcode from rINST 1681 GOTO_OPCODE(ip) @ jump to next instruction 1682#endif 1683 1684 1685/* ------------------------------ */ 1686 .balign 64 1687.L_OP_IF_EQZ: /* 0x38 */ 1688/* File: armv5te/OP_IF_EQZ.S */ 1689/* File: armv5te/zcmp.S */ 1690 /* 1691 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1692 * fragment that specifies the *reverse* comparison to perform, e.g. 1693 * for "if-le" you would use "gt". 1694 * 1695 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1696 */ 1697 /* if-cmp vAA, +BBBB */ 1698 mov r0, rINST, lsr #8 @ r0<- AA 1699 GET_VREG(r2, r0) @ r2<- vAA 1700 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1701 cmp r2, #0 @ compare (vA, 0) 1702 bne 1f @ branch to 1 if comparison failed 1703 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1704 movs r9, r9, asl #1 @ convert to bytes, check sign 1705 bmi common_backwardBranch @ backward branch, do periodic checks 17061: 1707#if defined(WITH_JIT) 1708 GET_JIT_PROF_TABLE(r0) 1709 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1710 cmp r0,#0 1711 bne common_updateProfile 1712 GET_INST_OPCODE(ip) @ extract opcode from rINST 1713 GOTO_OPCODE(ip) @ jump to next instruction 1714#else 1715 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1716 GET_INST_OPCODE(ip) @ extract opcode from rINST 1717 GOTO_OPCODE(ip) @ jump to next instruction 1718#endif 1719 1720 1721/* ------------------------------ */ 1722 .balign 64 1723.L_OP_IF_NEZ: /* 0x39 */ 1724/* File: armv5te/OP_IF_NEZ.S */ 1725/* File: armv5te/zcmp.S */ 1726 /* 1727 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1728 * fragment that specifies the *reverse* comparison to perform, e.g. 1729 * for "if-le" you would use "gt". 1730 * 1731 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1732 */ 1733 /* if-cmp vAA, +BBBB */ 1734 mov r0, rINST, lsr #8 @ r0<- AA 1735 GET_VREG(r2, r0) @ r2<- vAA 1736 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1737 cmp r2, #0 @ compare (vA, 0) 1738 beq 1f @ branch to 1 if comparison failed 1739 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1740 movs r9, r9, asl #1 @ convert to bytes, check sign 1741 bmi common_backwardBranch @ backward branch, do periodic checks 17421: 1743#if defined(WITH_JIT) 1744 GET_JIT_PROF_TABLE(r0) 1745 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1746 cmp r0,#0 1747 bne common_updateProfile 1748 GET_INST_OPCODE(ip) @ extract opcode from rINST 1749 GOTO_OPCODE(ip) @ jump to next instruction 1750#else 1751 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1752 GET_INST_OPCODE(ip) @ extract opcode from rINST 1753 GOTO_OPCODE(ip) @ jump to next instruction 1754#endif 1755 1756 1757/* ------------------------------ */ 1758 .balign 64 1759.L_OP_IF_LTZ: /* 0x3a */ 1760/* File: armv5te/OP_IF_LTZ.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 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1773 cmp r2, #0 @ compare (vA, 0) 1774 bge 1f @ branch to 1 if comparison failed 1775 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1776 movs r9, r9, asl #1 @ convert to bytes, check sign 1777 bmi common_backwardBranch @ backward branch, do periodic checks 17781: 1779#if defined(WITH_JIT) 1780 GET_JIT_PROF_TABLE(r0) 1781 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1782 cmp r0,#0 1783 bne common_updateProfile 1784 GET_INST_OPCODE(ip) @ extract opcode from rINST 1785 GOTO_OPCODE(ip) @ jump to next instruction 1786#else 1787 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1788 GET_INST_OPCODE(ip) @ extract opcode from rINST 1789 GOTO_OPCODE(ip) @ jump to next instruction 1790#endif 1791 1792 1793/* ------------------------------ */ 1794 .balign 64 1795.L_OP_IF_GEZ: /* 0x3b */ 1796/* File: armv5te/OP_IF_GEZ.S */ 1797/* File: armv5te/zcmp.S */ 1798 /* 1799 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1800 * fragment that specifies the *reverse* comparison to perform, e.g. 1801 * for "if-le" you would use "gt". 1802 * 1803 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1804 */ 1805 /* if-cmp vAA, +BBBB */ 1806 mov r0, rINST, lsr #8 @ r0<- AA 1807 GET_VREG(r2, r0) @ r2<- vAA 1808 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1809 cmp r2, #0 @ compare (vA, 0) 1810 blt 1f @ branch to 1 if comparison failed 1811 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1812 movs r9, r9, asl #1 @ convert to bytes, check sign 1813 bmi common_backwardBranch @ backward branch, do periodic checks 18141: 1815#if defined(WITH_JIT) 1816 GET_JIT_PROF_TABLE(r0) 1817 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1818 cmp r0,#0 1819 bne common_updateProfile 1820 GET_INST_OPCODE(ip) @ extract opcode from rINST 1821 GOTO_OPCODE(ip) @ jump to next instruction 1822#else 1823 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1824 GET_INST_OPCODE(ip) @ extract opcode from rINST 1825 GOTO_OPCODE(ip) @ jump to next instruction 1826#endif 1827 1828 1829/* ------------------------------ */ 1830 .balign 64 1831.L_OP_IF_GTZ: /* 0x3c */ 1832/* File: armv5te/OP_IF_GTZ.S */ 1833/* File: armv5te/zcmp.S */ 1834 /* 1835 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1836 * fragment that specifies the *reverse* comparison to perform, e.g. 1837 * for "if-le" you would use "gt". 1838 * 1839 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1840 */ 1841 /* if-cmp vAA, +BBBB */ 1842 mov r0, rINST, lsr #8 @ r0<- AA 1843 GET_VREG(r2, r0) @ r2<- vAA 1844 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1845 cmp r2, #0 @ compare (vA, 0) 1846 ble 1f @ branch to 1 if comparison failed 1847 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1848 movs r9, r9, asl #1 @ convert to bytes, check sign 1849 bmi common_backwardBranch @ backward branch, do periodic checks 18501: 1851#if defined(WITH_JIT) 1852 GET_JIT_PROF_TABLE(r0) 1853 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1854 cmp r0,#0 1855 bne common_updateProfile 1856 GET_INST_OPCODE(ip) @ extract opcode from rINST 1857 GOTO_OPCODE(ip) @ jump to next instruction 1858#else 1859 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1860 GET_INST_OPCODE(ip) @ extract opcode from rINST 1861 GOTO_OPCODE(ip) @ jump to next instruction 1862#endif 1863 1864 1865/* ------------------------------ */ 1866 .balign 64 1867.L_OP_IF_LEZ: /* 0x3d */ 1868/* File: armv5te/OP_IF_LEZ.S */ 1869/* File: armv5te/zcmp.S */ 1870 /* 1871 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1872 * fragment that specifies the *reverse* comparison to perform, e.g. 1873 * for "if-le" you would use "gt". 1874 * 1875 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1876 */ 1877 /* if-cmp vAA, +BBBB */ 1878 mov r0, rINST, lsr #8 @ r0<- AA 1879 GET_VREG(r2, r0) @ r2<- vAA 1880 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1881 cmp r2, #0 @ compare (vA, 0) 1882 bgt 1f @ branch to 1 if comparison failed 1883 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1884 movs r9, r9, asl #1 @ convert to bytes, check sign 1885 bmi common_backwardBranch @ backward branch, do periodic checks 18861: 1887#if defined(WITH_JIT) 1888 GET_JIT_PROF_TABLE(r0) 1889 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1890 cmp r0,#0 1891 bne common_updateProfile 1892 GET_INST_OPCODE(ip) @ extract opcode from rINST 1893 GOTO_OPCODE(ip) @ jump to next instruction 1894#else 1895 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1896 GET_INST_OPCODE(ip) @ extract opcode from rINST 1897 GOTO_OPCODE(ip) @ jump to next instruction 1898#endif 1899 1900 1901/* ------------------------------ */ 1902 .balign 64 1903.L_OP_UNUSED_3E: /* 0x3e */ 1904/* File: armv5te/OP_UNUSED_3E.S */ 1905/* File: armv5te/unused.S */ 1906 bl common_abort 1907 1908 1909/* ------------------------------ */ 1910 .balign 64 1911.L_OP_UNUSED_3F: /* 0x3f */ 1912/* File: armv5te/OP_UNUSED_3F.S */ 1913/* File: armv5te/unused.S */ 1914 bl common_abort 1915 1916 1917/* ------------------------------ */ 1918 .balign 64 1919.L_OP_UNUSED_40: /* 0x40 */ 1920/* File: armv5te/OP_UNUSED_40.S */ 1921/* File: armv5te/unused.S */ 1922 bl common_abort 1923 1924 1925/* ------------------------------ */ 1926 .balign 64 1927.L_OP_UNUSED_41: /* 0x41 */ 1928/* File: armv5te/OP_UNUSED_41.S */ 1929/* File: armv5te/unused.S */ 1930 bl common_abort 1931 1932 1933/* ------------------------------ */ 1934 .balign 64 1935.L_OP_UNUSED_42: /* 0x42 */ 1936/* File: armv5te/OP_UNUSED_42.S */ 1937/* File: armv5te/unused.S */ 1938 bl common_abort 1939 1940 1941/* ------------------------------ */ 1942 .balign 64 1943.L_OP_UNUSED_43: /* 0x43 */ 1944/* File: armv5te/OP_UNUSED_43.S */ 1945/* File: armv5te/unused.S */ 1946 bl common_abort 1947 1948 1949/* ------------------------------ */ 1950 .balign 64 1951.L_OP_AGET: /* 0x44 */ 1952/* File: armv5te/OP_AGET.S */ 1953 /* 1954 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1955 * 1956 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1957 * instructions. We use a pair of FETCH_Bs instead. 1958 * 1959 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1960 */ 1961 /* op vAA, vBB, vCC */ 1962 FETCH_B(r2, 1, 0) @ r2<- BB 1963 mov r9, rINST, lsr #8 @ r9<- AA 1964 FETCH_B(r3, 1, 1) @ r3<- CC 1965 GET_VREG(r0, r2) @ r0<- vBB (array object) 1966 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1967 cmp r0, #0 @ null array object? 1968 beq common_errNullObject @ yes, bail 1969 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1970 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1971 cmp r1, r3 @ compare unsigned index, length 1972 bcs common_errArrayIndex @ index >= length, bail 1973 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1974 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1975 GET_INST_OPCODE(ip) @ extract opcode from rINST 1976 SET_VREG(r2, r9) @ vAA<- r2 1977 GOTO_OPCODE(ip) @ jump to next instruction 1978 1979/* ------------------------------ */ 1980 .balign 64 1981.L_OP_AGET_WIDE: /* 0x45 */ 1982/* File: armv5te/OP_AGET_WIDE.S */ 1983 /* 1984 * Array get, 64 bits. vAA <- vBB[vCC]. 1985 * 1986 * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD. 1987 */ 1988 /* aget-wide vAA, vBB, vCC */ 1989 FETCH(r0, 1) @ r0<- CCBB 1990 mov r9, rINST, lsr #8 @ r9<- AA 1991 and r2, r0, #255 @ r2<- BB 1992 mov r3, r0, lsr #8 @ r3<- CC 1993 GET_VREG(r0, r2) @ r0<- vBB (array object) 1994 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1995 cmp r0, #0 @ null array object? 1996 beq common_errNullObject @ yes, bail 1997 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1998 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 1999 cmp r1, r3 @ compare unsigned index, length 2000 bcc .LOP_AGET_WIDE_finish @ okay, continue below 2001 b common_errArrayIndex @ index >= length, bail 2002 @ May want to swap the order of these two branches depending on how the 2003 @ branch prediction (if any) handles conditional forward branches vs. 2004 @ unconditional forward branches. 2005 2006/* ------------------------------ */ 2007 .balign 64 2008.L_OP_AGET_OBJECT: /* 0x46 */ 2009/* File: armv5te/OP_AGET_OBJECT.S */ 2010/* File: armv5te/OP_AGET.S */ 2011 /* 2012 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2013 * 2014 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2015 * instructions. We use a pair of FETCH_Bs instead. 2016 * 2017 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2018 */ 2019 /* op vAA, vBB, vCC */ 2020 FETCH_B(r2, 1, 0) @ r2<- BB 2021 mov r9, rINST, lsr #8 @ r9<- AA 2022 FETCH_B(r3, 1, 1) @ r3<- CC 2023 GET_VREG(r0, r2) @ r0<- vBB (array object) 2024 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2025 cmp r0, #0 @ null array object? 2026 beq common_errNullObject @ yes, bail 2027 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2028 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2029 cmp r1, r3 @ compare unsigned index, length 2030 bcs common_errArrayIndex @ index >= length, bail 2031 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2032 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2033 GET_INST_OPCODE(ip) @ extract opcode from rINST 2034 SET_VREG(r2, r9) @ vAA<- r2 2035 GOTO_OPCODE(ip) @ jump to next instruction 2036 2037 2038/* ------------------------------ */ 2039 .balign 64 2040.L_OP_AGET_BOOLEAN: /* 0x47 */ 2041/* File: armv5te/OP_AGET_BOOLEAN.S */ 2042/* File: armv5te/OP_AGET.S */ 2043 /* 2044 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2045 * 2046 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2047 * instructions. We use a pair of FETCH_Bs instead. 2048 * 2049 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2050 */ 2051 /* op vAA, vBB, vCC */ 2052 FETCH_B(r2, 1, 0) @ r2<- BB 2053 mov r9, rINST, lsr #8 @ r9<- AA 2054 FETCH_B(r3, 1, 1) @ r3<- CC 2055 GET_VREG(r0, r2) @ r0<- vBB (array object) 2056 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2057 cmp r0, #0 @ null array object? 2058 beq common_errNullObject @ yes, bail 2059 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2060 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2061 cmp r1, r3 @ compare unsigned index, length 2062 bcs common_errArrayIndex @ index >= length, bail 2063 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2064 ldrb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2065 GET_INST_OPCODE(ip) @ extract opcode from rINST 2066 SET_VREG(r2, r9) @ vAA<- r2 2067 GOTO_OPCODE(ip) @ jump to next instruction 2068 2069 2070/* ------------------------------ */ 2071 .balign 64 2072.L_OP_AGET_BYTE: /* 0x48 */ 2073/* File: armv5te/OP_AGET_BYTE.S */ 2074/* File: armv5te/OP_AGET.S */ 2075 /* 2076 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2077 * 2078 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2079 * instructions. We use a pair of FETCH_Bs instead. 2080 * 2081 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2082 */ 2083 /* op vAA, vBB, vCC */ 2084 FETCH_B(r2, 1, 0) @ r2<- BB 2085 mov r9, rINST, lsr #8 @ r9<- AA 2086 FETCH_B(r3, 1, 1) @ r3<- CC 2087 GET_VREG(r0, r2) @ r0<- vBB (array object) 2088 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2089 cmp r0, #0 @ null array object? 2090 beq common_errNullObject @ yes, bail 2091 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2092 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2093 cmp r1, r3 @ compare unsigned index, length 2094 bcs common_errArrayIndex @ index >= length, bail 2095 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2096 ldrsb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2097 GET_INST_OPCODE(ip) @ extract opcode from rINST 2098 SET_VREG(r2, r9) @ vAA<- r2 2099 GOTO_OPCODE(ip) @ jump to next instruction 2100 2101 2102/* ------------------------------ */ 2103 .balign 64 2104.L_OP_AGET_CHAR: /* 0x49 */ 2105/* File: armv5te/OP_AGET_CHAR.S */ 2106/* File: armv5te/OP_AGET.S */ 2107 /* 2108 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2109 * 2110 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2111 * instructions. We use a pair of FETCH_Bs instead. 2112 * 2113 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2114 */ 2115 /* op vAA, vBB, vCC */ 2116 FETCH_B(r2, 1, 0) @ r2<- BB 2117 mov r9, rINST, lsr #8 @ r9<- AA 2118 FETCH_B(r3, 1, 1) @ r3<- CC 2119 GET_VREG(r0, r2) @ r0<- vBB (array object) 2120 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2121 cmp r0, #0 @ null array object? 2122 beq common_errNullObject @ yes, bail 2123 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2124 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2125 cmp r1, r3 @ compare unsigned index, length 2126 bcs common_errArrayIndex @ index >= length, bail 2127 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2128 ldrh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2129 GET_INST_OPCODE(ip) @ extract opcode from rINST 2130 SET_VREG(r2, r9) @ vAA<- r2 2131 GOTO_OPCODE(ip) @ jump to next instruction 2132 2133 2134/* ------------------------------ */ 2135 .balign 64 2136.L_OP_AGET_SHORT: /* 0x4a */ 2137/* File: armv5te/OP_AGET_SHORT.S */ 2138/* File: armv5te/OP_AGET.S */ 2139 /* 2140 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2141 * 2142 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2143 * instructions. We use a pair of FETCH_Bs instead. 2144 * 2145 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2146 */ 2147 /* op vAA, vBB, vCC */ 2148 FETCH_B(r2, 1, 0) @ r2<- BB 2149 mov r9, rINST, lsr #8 @ r9<- AA 2150 FETCH_B(r3, 1, 1) @ r3<- CC 2151 GET_VREG(r0, r2) @ r0<- vBB (array object) 2152 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2153 cmp r0, #0 @ null array object? 2154 beq common_errNullObject @ yes, bail 2155 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2156 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2157 cmp r1, r3 @ compare unsigned index, length 2158 bcs common_errArrayIndex @ index >= length, bail 2159 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2160 ldrsh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2161 GET_INST_OPCODE(ip) @ extract opcode from rINST 2162 SET_VREG(r2, r9) @ vAA<- r2 2163 GOTO_OPCODE(ip) @ jump to next instruction 2164 2165 2166/* ------------------------------ */ 2167 .balign 64 2168.L_OP_APUT: /* 0x4b */ 2169/* File: armv5te/OP_APUT.S */ 2170 /* 2171 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2172 * 2173 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2174 * instructions. We use a pair of FETCH_Bs instead. 2175 * 2176 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2177 */ 2178 /* op vAA, vBB, vCC */ 2179 FETCH_B(r2, 1, 0) @ r2<- BB 2180 mov r9, rINST, lsr #8 @ r9<- AA 2181 FETCH_B(r3, 1, 1) @ r3<- CC 2182 GET_VREG(r0, r2) @ r0<- vBB (array object) 2183 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2184 cmp r0, #0 @ null array object? 2185 beq common_errNullObject @ yes, bail 2186 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2187 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2188 cmp r1, r3 @ compare unsigned index, length 2189 bcs common_errArrayIndex @ index >= length, bail 2190 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2191 GET_VREG(r2, r9) @ r2<- vAA 2192 GET_INST_OPCODE(ip) @ extract opcode from rINST 2193 str r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2194 GOTO_OPCODE(ip) @ jump to next instruction 2195 2196/* ------------------------------ */ 2197 .balign 64 2198.L_OP_APUT_WIDE: /* 0x4c */ 2199/* File: armv5te/OP_APUT_WIDE.S */ 2200 /* 2201 * Array put, 64 bits. vBB[vCC] <- vAA. 2202 * 2203 * Arrays of long/double are 64-bit aligned, so it's okay to use STRD. 2204 */ 2205 /* aput-wide vAA, vBB, vCC */ 2206 FETCH(r0, 1) @ r0<- CCBB 2207 mov r9, rINST, lsr #8 @ r9<- AA 2208 and r2, r0, #255 @ r2<- BB 2209 mov r3, r0, lsr #8 @ r3<- CC 2210 GET_VREG(r0, r2) @ r0<- vBB (array object) 2211 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2212 cmp r0, #0 @ null array object? 2213 beq common_errNullObject @ yes, bail 2214 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2215 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2216 cmp r1, r3 @ compare unsigned index, length 2217 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2218 bcc .LOP_APUT_WIDE_finish @ okay, continue below 2219 b common_errArrayIndex @ index >= length, bail 2220 @ May want to swap the order of these two branches depending on how the 2221 @ branch prediction (if any) handles conditional forward branches vs. 2222 @ unconditional forward branches. 2223 2224/* ------------------------------ */ 2225 .balign 64 2226.L_OP_APUT_OBJECT: /* 0x4d */ 2227/* File: armv5te/OP_APUT_OBJECT.S */ 2228 /* 2229 * Store an object into an array. vBB[vCC] <- vAA. 2230 */ 2231 /* op vAA, vBB, vCC */ 2232 FETCH(r0, 1) @ r0<- CCBB 2233 mov r9, rINST, lsr #8 @ r9<- AA 2234 and r2, r0, #255 @ r2<- BB 2235 mov r3, r0, lsr #8 @ r3<- CC 2236 GET_VREG(rINST, r2) @ rINST<- vBB (array object) 2237 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2238 cmp rINST, #0 @ null array object? 2239 GET_VREG(r9, r9) @ r9<- vAA 2240 beq common_errNullObject @ yes, bail 2241 ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length 2242 add r10, rINST, r1, lsl #2 @ r10<- arrayObj + index*width 2243 cmp r1, r3 @ compare unsigned index, length 2244 bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on 2245 b common_errArrayIndex @ index >= length, bail 2246 2247 2248/* ------------------------------ */ 2249 .balign 64 2250.L_OP_APUT_BOOLEAN: /* 0x4e */ 2251/* File: armv5te/OP_APUT_BOOLEAN.S */ 2252/* File: armv5te/OP_APUT.S */ 2253 /* 2254 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2255 * 2256 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2257 * instructions. We use a pair of FETCH_Bs instead. 2258 * 2259 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2260 */ 2261 /* op vAA, vBB, vCC */ 2262 FETCH_B(r2, 1, 0) @ r2<- BB 2263 mov r9, rINST, lsr #8 @ r9<- AA 2264 FETCH_B(r3, 1, 1) @ r3<- CC 2265 GET_VREG(r0, r2) @ r0<- vBB (array object) 2266 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2267 cmp r0, #0 @ null array object? 2268 beq common_errNullObject @ yes, bail 2269 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2270 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2271 cmp r1, r3 @ compare unsigned index, length 2272 bcs common_errArrayIndex @ index >= length, bail 2273 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2274 GET_VREG(r2, r9) @ r2<- vAA 2275 GET_INST_OPCODE(ip) @ extract opcode from rINST 2276 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2277 GOTO_OPCODE(ip) @ jump to next instruction 2278 2279 2280/* ------------------------------ */ 2281 .balign 64 2282.L_OP_APUT_BYTE: /* 0x4f */ 2283/* File: armv5te/OP_APUT_BYTE.S */ 2284/* File: armv5te/OP_APUT.S */ 2285 /* 2286 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2287 * 2288 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2289 * instructions. We use a pair of FETCH_Bs instead. 2290 * 2291 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2292 */ 2293 /* op vAA, vBB, vCC */ 2294 FETCH_B(r2, 1, 0) @ r2<- BB 2295 mov r9, rINST, lsr #8 @ r9<- AA 2296 FETCH_B(r3, 1, 1) @ r3<- CC 2297 GET_VREG(r0, r2) @ r0<- vBB (array object) 2298 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2299 cmp r0, #0 @ null array object? 2300 beq common_errNullObject @ yes, bail 2301 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2302 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2303 cmp r1, r3 @ compare unsigned index, length 2304 bcs common_errArrayIndex @ index >= length, bail 2305 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2306 GET_VREG(r2, r9) @ r2<- vAA 2307 GET_INST_OPCODE(ip) @ extract opcode from rINST 2308 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2309 GOTO_OPCODE(ip) @ jump to next instruction 2310 2311 2312/* ------------------------------ */ 2313 .balign 64 2314.L_OP_APUT_CHAR: /* 0x50 */ 2315/* File: armv5te/OP_APUT_CHAR.S */ 2316/* File: armv5te/OP_APUT.S */ 2317 /* 2318 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2319 * 2320 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2321 * instructions. We use a pair of FETCH_Bs instead. 2322 * 2323 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2324 */ 2325 /* op vAA, vBB, vCC */ 2326 FETCH_B(r2, 1, 0) @ r2<- BB 2327 mov r9, rINST, lsr #8 @ r9<- AA 2328 FETCH_B(r3, 1, 1) @ r3<- CC 2329 GET_VREG(r0, r2) @ r0<- vBB (array object) 2330 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2331 cmp r0, #0 @ null array object? 2332 beq common_errNullObject @ yes, bail 2333 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2334 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2335 cmp r1, r3 @ compare unsigned index, length 2336 bcs common_errArrayIndex @ index >= length, bail 2337 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2338 GET_VREG(r2, r9) @ r2<- vAA 2339 GET_INST_OPCODE(ip) @ extract opcode from rINST 2340 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2341 GOTO_OPCODE(ip) @ jump to next instruction 2342 2343 2344/* ------------------------------ */ 2345 .balign 64 2346.L_OP_APUT_SHORT: /* 0x51 */ 2347/* File: armv5te/OP_APUT_SHORT.S */ 2348/* File: armv5te/OP_APUT.S */ 2349 /* 2350 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2351 * 2352 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2353 * instructions. We use a pair of FETCH_Bs instead. 2354 * 2355 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2356 */ 2357 /* op vAA, vBB, vCC */ 2358 FETCH_B(r2, 1, 0) @ r2<- BB 2359 mov r9, rINST, lsr #8 @ r9<- AA 2360 FETCH_B(r3, 1, 1) @ r3<- CC 2361 GET_VREG(r0, r2) @ r0<- vBB (array object) 2362 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2363 cmp r0, #0 @ null array object? 2364 beq common_errNullObject @ yes, bail 2365 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2366 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2367 cmp r1, r3 @ compare unsigned index, length 2368 bcs common_errArrayIndex @ index >= length, bail 2369 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2370 GET_VREG(r2, r9) @ r2<- vAA 2371 GET_INST_OPCODE(ip) @ extract opcode from rINST 2372 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2373 GOTO_OPCODE(ip) @ jump to next instruction 2374 2375 2376/* ------------------------------ */ 2377 .balign 64 2378.L_OP_IGET: /* 0x52 */ 2379/* File: armv6t2/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_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_finish 2400 b common_exceptionThrown 2401 2402/* ------------------------------ */ 2403 .balign 64 2404.L_OP_IGET_WIDE: /* 0x53 */ 2405/* File: armv6t2/OP_IGET_WIDE.S */ 2406 /* 2407 * Wide 32-bit instance field get. 2408 */ 2409 /* iget-wide vA, vB, field@CCCC */ 2410 mov r0, rINST, lsr #12 @ r0<- B 2411 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2412 FETCH(r1, 1) @ r1<- field ref CCCC 2413 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2414 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2415 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2416 cmp r0, #0 @ is resolved entry null? 2417 bne .LOP_IGET_WIDE_finish @ no, already resolved 24188: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2419 EXPORT_PC() @ resolve() could throw 2420 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2421 bl dvmResolveInstField @ r0<- resolved InstField ptr 2422 cmp r0, #0 2423 bne .LOP_IGET_WIDE_finish 2424 b common_exceptionThrown 2425 2426/* ------------------------------ */ 2427 .balign 64 2428.L_OP_IGET_OBJECT: /* 0x54 */ 2429/* File: armv5te/OP_IGET_OBJECT.S */ 2430/* File: armv5te/OP_IGET.S */ 2431 /* 2432 * General 32-bit instance field get. 2433 * 2434 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2435 */ 2436 /* op vA, vB, field@CCCC */ 2437 mov r0, rINST, lsr #12 @ r0<- B 2438 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2439 FETCH(r1, 1) @ r1<- field ref CCCC 2440 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2441 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2442 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2443 cmp r0, #0 @ is resolved entry null? 2444 bne .LOP_IGET_OBJECT_finish @ no, already resolved 24458: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2446 EXPORT_PC() @ resolve() could throw 2447 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2448 bl dvmResolveInstField @ r0<- resolved InstField ptr 2449 cmp r0, #0 2450 bne .LOP_IGET_OBJECT_finish 2451 b common_exceptionThrown 2452 2453 2454/* ------------------------------ */ 2455 .balign 64 2456.L_OP_IGET_BOOLEAN: /* 0x55 */ 2457/* File: armv5te/OP_IGET_BOOLEAN.S */ 2458@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" } 2459/* File: armv5te/OP_IGET.S */ 2460 /* 2461 * General 32-bit instance field get. 2462 * 2463 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2464 */ 2465 /* op vA, vB, field@CCCC */ 2466 mov r0, rINST, lsr #12 @ r0<- B 2467 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2468 FETCH(r1, 1) @ r1<- field ref CCCC 2469 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2470 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2471 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2472 cmp r0, #0 @ is resolved entry null? 2473 bne .LOP_IGET_BOOLEAN_finish @ no, already resolved 24748: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2475 EXPORT_PC() @ resolve() could throw 2476 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2477 bl dvmResolveInstField @ r0<- resolved InstField ptr 2478 cmp r0, #0 2479 bne .LOP_IGET_BOOLEAN_finish 2480 b common_exceptionThrown 2481 2482 2483/* ------------------------------ */ 2484 .balign 64 2485.L_OP_IGET_BYTE: /* 0x56 */ 2486/* File: armv5te/OP_IGET_BYTE.S */ 2487@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" } 2488/* File: armv5te/OP_IGET.S */ 2489 /* 2490 * General 32-bit instance field get. 2491 * 2492 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2493 */ 2494 /* op vA, vB, field@CCCC */ 2495 mov r0, rINST, lsr #12 @ r0<- B 2496 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2497 FETCH(r1, 1) @ r1<- field ref CCCC 2498 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2499 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2500 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2501 cmp r0, #0 @ is resolved entry null? 2502 bne .LOP_IGET_BYTE_finish @ no, already resolved 25038: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2504 EXPORT_PC() @ resolve() could throw 2505 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2506 bl dvmResolveInstField @ r0<- resolved InstField ptr 2507 cmp r0, #0 2508 bne .LOP_IGET_BYTE_finish 2509 b common_exceptionThrown 2510 2511 2512/* ------------------------------ */ 2513 .balign 64 2514.L_OP_IGET_CHAR: /* 0x57 */ 2515/* File: armv5te/OP_IGET_CHAR.S */ 2516@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" } 2517/* File: armv5te/OP_IGET.S */ 2518 /* 2519 * General 32-bit instance field get. 2520 * 2521 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2522 */ 2523 /* op vA, vB, field@CCCC */ 2524 mov r0, rINST, lsr #12 @ r0<- B 2525 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2526 FETCH(r1, 1) @ r1<- field ref CCCC 2527 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2528 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2529 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2530 cmp r0, #0 @ is resolved entry null? 2531 bne .LOP_IGET_CHAR_finish @ no, already resolved 25328: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2533 EXPORT_PC() @ resolve() could throw 2534 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2535 bl dvmResolveInstField @ r0<- resolved InstField ptr 2536 cmp r0, #0 2537 bne .LOP_IGET_CHAR_finish 2538 b common_exceptionThrown 2539 2540 2541/* ------------------------------ */ 2542 .balign 64 2543.L_OP_IGET_SHORT: /* 0x58 */ 2544/* File: armv5te/OP_IGET_SHORT.S */ 2545@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" } 2546/* File: armv5te/OP_IGET.S */ 2547 /* 2548 * General 32-bit instance field get. 2549 * 2550 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2551 */ 2552 /* op vA, vB, field@CCCC */ 2553 mov r0, rINST, lsr #12 @ r0<- B 2554 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2555 FETCH(r1, 1) @ r1<- field ref CCCC 2556 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2557 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2558 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2559 cmp r0, #0 @ is resolved entry null? 2560 bne .LOP_IGET_SHORT_finish @ no, already resolved 25618: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2562 EXPORT_PC() @ resolve() could throw 2563 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2564 bl dvmResolveInstField @ r0<- resolved InstField ptr 2565 cmp r0, #0 2566 bne .LOP_IGET_SHORT_finish 2567 b common_exceptionThrown 2568 2569 2570/* ------------------------------ */ 2571 .balign 64 2572.L_OP_IPUT: /* 0x59 */ 2573/* File: armv6t2/OP_IPUT.S */ 2574 /* 2575 * General 32-bit instance field put. 2576 * 2577 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2578 */ 2579 /* op vA, vB, field@CCCC */ 2580 mov r0, rINST, lsr #12 @ r0<- B 2581 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2582 FETCH(r1, 1) @ r1<- field ref CCCC 2583 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2584 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2585 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2586 cmp r0, #0 @ is resolved entry null? 2587 bne .LOP_IPUT_finish @ no, already resolved 25888: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2589 EXPORT_PC() @ resolve() could throw 2590 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2591 bl dvmResolveInstField @ r0<- resolved InstField ptr 2592 cmp r0, #0 @ success? 2593 bne .LOP_IPUT_finish @ yes, finish up 2594 b common_exceptionThrown 2595 2596/* ------------------------------ */ 2597 .balign 64 2598.L_OP_IPUT_WIDE: /* 0x5a */ 2599/* File: armv6t2/OP_IPUT_WIDE.S */ 2600 /* iput-wide vA, vB, field@CCCC */ 2601 mov r0, rINST, lsr #12 @ r0<- B 2602 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2603 FETCH(r1, 1) @ r1<- field ref CCCC 2604 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2605 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2606 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2607 cmp r0, #0 @ is resolved entry null? 2608 bne .LOP_IPUT_WIDE_finish @ no, already resolved 26098: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2610 EXPORT_PC() @ resolve() could throw 2611 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2612 bl dvmResolveInstField @ r0<- resolved InstField ptr 2613 cmp r0, #0 @ success? 2614 bne .LOP_IPUT_WIDE_finish @ yes, finish up 2615 b common_exceptionThrown 2616 2617/* ------------------------------ */ 2618 .balign 64 2619.L_OP_IPUT_OBJECT: /* 0x5b */ 2620/* File: armv5te/OP_IPUT_OBJECT.S */ 2621 /* 2622 * 32-bit instance field put. 2623 * 2624 * for: iput-object, iput-object-volatile 2625 */ 2626 /* op vA, vB, field@CCCC */ 2627 mov r0, rINST, lsr #12 @ r0<- B 2628 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2629 FETCH(r1, 1) @ r1<- field ref CCCC 2630 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2631 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2632 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2633 cmp r0, #0 @ is resolved entry null? 2634 bne .LOP_IPUT_OBJECT_finish @ no, already resolved 26358: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2636 EXPORT_PC() @ resolve() could throw 2637 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2638 bl dvmResolveInstField @ r0<- resolved InstField ptr 2639 cmp r0, #0 @ success? 2640 bne .LOP_IPUT_OBJECT_finish @ yes, finish up 2641 b common_exceptionThrown 2642 2643/* ------------------------------ */ 2644 .balign 64 2645.L_OP_IPUT_BOOLEAN: /* 0x5c */ 2646/* File: armv5te/OP_IPUT_BOOLEAN.S */ 2647@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" } 2648/* File: armv5te/OP_IPUT.S */ 2649 /* 2650 * General 32-bit instance field put. 2651 * 2652 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2653 */ 2654 /* op vA, vB, field@CCCC */ 2655 mov r0, rINST, lsr #12 @ r0<- B 2656 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2657 FETCH(r1, 1) @ r1<- field ref CCCC 2658 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2659 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2660 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2661 cmp r0, #0 @ is resolved entry null? 2662 bne .LOP_IPUT_BOOLEAN_finish @ no, already resolved 26638: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2664 EXPORT_PC() @ resolve() could throw 2665 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2666 bl dvmResolveInstField @ r0<- resolved InstField ptr 2667 cmp r0, #0 @ success? 2668 bne .LOP_IPUT_BOOLEAN_finish @ yes, finish up 2669 b common_exceptionThrown 2670 2671 2672/* ------------------------------ */ 2673 .balign 64 2674.L_OP_IPUT_BYTE: /* 0x5d */ 2675/* File: armv5te/OP_IPUT_BYTE.S */ 2676@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" } 2677/* File: armv5te/OP_IPUT.S */ 2678 /* 2679 * General 32-bit instance field put. 2680 * 2681 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2682 */ 2683 /* op vA, vB, field@CCCC */ 2684 mov r0, rINST, lsr #12 @ r0<- B 2685 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2686 FETCH(r1, 1) @ r1<- field ref CCCC 2687 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2688 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2689 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2690 cmp r0, #0 @ is resolved entry null? 2691 bne .LOP_IPUT_BYTE_finish @ no, already resolved 26928: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2693 EXPORT_PC() @ resolve() could throw 2694 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2695 bl dvmResolveInstField @ r0<- resolved InstField ptr 2696 cmp r0, #0 @ success? 2697 bne .LOP_IPUT_BYTE_finish @ yes, finish up 2698 b common_exceptionThrown 2699 2700 2701/* ------------------------------ */ 2702 .balign 64 2703.L_OP_IPUT_CHAR: /* 0x5e */ 2704/* File: armv5te/OP_IPUT_CHAR.S */ 2705@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" } 2706/* File: armv5te/OP_IPUT.S */ 2707 /* 2708 * General 32-bit instance field put. 2709 * 2710 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2711 */ 2712 /* op vA, vB, field@CCCC */ 2713 mov r0, rINST, lsr #12 @ r0<- B 2714 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2715 FETCH(r1, 1) @ r1<- field ref CCCC 2716 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2717 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2718 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2719 cmp r0, #0 @ is resolved entry null? 2720 bne .LOP_IPUT_CHAR_finish @ no, already resolved 27218: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2722 EXPORT_PC() @ resolve() could throw 2723 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2724 bl dvmResolveInstField @ r0<- resolved InstField ptr 2725 cmp r0, #0 @ success? 2726 bne .LOP_IPUT_CHAR_finish @ yes, finish up 2727 b common_exceptionThrown 2728 2729 2730/* ------------------------------ */ 2731 .balign 64 2732.L_OP_IPUT_SHORT: /* 0x5f */ 2733/* File: armv5te/OP_IPUT_SHORT.S */ 2734@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" } 2735/* File: armv5te/OP_IPUT.S */ 2736 /* 2737 * General 32-bit instance field put. 2738 * 2739 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2740 */ 2741 /* op vA, vB, field@CCCC */ 2742 mov r0, rINST, lsr #12 @ r0<- B 2743 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 2744 FETCH(r1, 1) @ r1<- field ref CCCC 2745 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2746 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2747 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2748 cmp r0, #0 @ is resolved entry null? 2749 bne .LOP_IPUT_SHORT_finish @ no, already resolved 27508: ldr r2, [rSELF, #offThread_method] @ r2<- current method 2751 EXPORT_PC() @ resolve() could throw 2752 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2753 bl dvmResolveInstField @ r0<- resolved InstField ptr 2754 cmp r0, #0 @ success? 2755 bne .LOP_IPUT_SHORT_finish @ yes, finish up 2756 b common_exceptionThrown 2757 2758 2759/* ------------------------------ */ 2760 .balign 64 2761.L_OP_SGET: /* 0x60 */ 2762/* File: armv5te/OP_SGET.S */ 2763 /* 2764 * General 32-bit SGET handler. 2765 * 2766 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2767 */ 2768 /* op vAA, field@BBBB */ 2769 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2770 FETCH(r1, 1) @ r1<- field ref BBBB 2771 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2772 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2773 cmp r0, #0 @ is resolved entry null? 2774 beq .LOP_SGET_resolve @ yes, do resolve 2775.LOP_SGET_finish: @ field ptr in r0 2776 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2777 @ no-op @ acquiring load 2778 mov r2, rINST, lsr #8 @ r2<- AA 2779 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2780 SET_VREG(r1, r2) @ fp[AA]<- r1 2781 GET_INST_OPCODE(ip) @ extract opcode from rINST 2782 GOTO_OPCODE(ip) @ jump to next instruction 2783 2784/* ------------------------------ */ 2785 .balign 64 2786.L_OP_SGET_WIDE: /* 0x61 */ 2787/* File: armv5te/OP_SGET_WIDE.S */ 2788 /* 2789 * 64-bit SGET handler. 2790 */ 2791 /* sget-wide vAA, field@BBBB */ 2792 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2793 FETCH(r1, 1) @ r1<- field ref BBBB 2794 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2795 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2796 cmp r0, #0 @ is resolved entry null? 2797 beq .LOP_SGET_WIDE_resolve @ yes, do resolve 2798.LOP_SGET_WIDE_finish: 2799 mov r9, rINST, lsr #8 @ r9<- AA 2800 .if 0 2801 add r0, r0, #offStaticField_value @ r0<- pointer to data 2802 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 2803 .else 2804 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 2805 .endif 2806 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2807 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2808 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 2809 GET_INST_OPCODE(ip) @ extract opcode from rINST 2810 GOTO_OPCODE(ip) @ jump to next instruction 2811 2812/* ------------------------------ */ 2813 .balign 64 2814.L_OP_SGET_OBJECT: /* 0x62 */ 2815/* File: armv5te/OP_SGET_OBJECT.S */ 2816/* File: armv5te/OP_SGET.S */ 2817 /* 2818 * General 32-bit SGET handler. 2819 * 2820 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2821 */ 2822 /* op vAA, field@BBBB */ 2823 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2824 FETCH(r1, 1) @ r1<- field ref BBBB 2825 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2826 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2827 cmp r0, #0 @ is resolved entry null? 2828 beq .LOP_SGET_OBJECT_resolve @ yes, do resolve 2829.LOP_SGET_OBJECT_finish: @ field ptr in r0 2830 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2831 @ no-op @ acquiring load 2832 mov r2, rINST, lsr #8 @ r2<- AA 2833 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2834 SET_VREG(r1, r2) @ fp[AA]<- r1 2835 GET_INST_OPCODE(ip) @ extract opcode from rINST 2836 GOTO_OPCODE(ip) @ jump to next instruction 2837 2838 2839/* ------------------------------ */ 2840 .balign 64 2841.L_OP_SGET_BOOLEAN: /* 0x63 */ 2842/* File: armv5te/OP_SGET_BOOLEAN.S */ 2843/* File: armv5te/OP_SGET.S */ 2844 /* 2845 * General 32-bit SGET handler. 2846 * 2847 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2848 */ 2849 /* op vAA, field@BBBB */ 2850 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2851 FETCH(r1, 1) @ r1<- field ref BBBB 2852 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2853 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2854 cmp r0, #0 @ is resolved entry null? 2855 beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve 2856.LOP_SGET_BOOLEAN_finish: @ field ptr in r0 2857 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2858 @ no-op @ acquiring load 2859 mov r2, rINST, lsr #8 @ r2<- AA 2860 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2861 SET_VREG(r1, r2) @ fp[AA]<- r1 2862 GET_INST_OPCODE(ip) @ extract opcode from rINST 2863 GOTO_OPCODE(ip) @ jump to next instruction 2864 2865 2866/* ------------------------------ */ 2867 .balign 64 2868.L_OP_SGET_BYTE: /* 0x64 */ 2869/* File: armv5te/OP_SGET_BYTE.S */ 2870/* File: armv5te/OP_SGET.S */ 2871 /* 2872 * General 32-bit SGET handler. 2873 * 2874 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-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 r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2880 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2881 cmp r0, #0 @ is resolved entry null? 2882 beq .LOP_SGET_BYTE_resolve @ yes, do resolve 2883.LOP_SGET_BYTE_finish: @ field ptr in r0 2884 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2885 @ no-op @ acquiring load 2886 mov r2, rINST, lsr #8 @ r2<- AA 2887 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2888 SET_VREG(r1, r2) @ fp[AA]<- r1 2889 GET_INST_OPCODE(ip) @ extract opcode from rINST 2890 GOTO_OPCODE(ip) @ jump to next instruction 2891 2892 2893/* ------------------------------ */ 2894 .balign 64 2895.L_OP_SGET_CHAR: /* 0x65 */ 2896/* File: armv5te/OP_SGET_CHAR.S */ 2897/* File: armv5te/OP_SGET.S */ 2898 /* 2899 * General 32-bit SGET handler. 2900 * 2901 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2902 */ 2903 /* op vAA, field@BBBB */ 2904 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2905 FETCH(r1, 1) @ r1<- field ref BBBB 2906 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2907 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2908 cmp r0, #0 @ is resolved entry null? 2909 beq .LOP_SGET_CHAR_resolve @ yes, do resolve 2910.LOP_SGET_CHAR_finish: @ field ptr in r0 2911 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2912 @ no-op @ acquiring load 2913 mov r2, rINST, lsr #8 @ r2<- AA 2914 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2915 SET_VREG(r1, r2) @ fp[AA]<- r1 2916 GET_INST_OPCODE(ip) @ extract opcode from rINST 2917 GOTO_OPCODE(ip) @ jump to next instruction 2918 2919 2920/* ------------------------------ */ 2921 .balign 64 2922.L_OP_SGET_SHORT: /* 0x66 */ 2923/* File: armv5te/OP_SGET_SHORT.S */ 2924/* File: armv5te/OP_SGET.S */ 2925 /* 2926 * General 32-bit SGET handler. 2927 * 2928 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2929 */ 2930 /* op vAA, field@BBBB */ 2931 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2932 FETCH(r1, 1) @ r1<- field ref BBBB 2933 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2934 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2935 cmp r0, #0 @ is resolved entry null? 2936 beq .LOP_SGET_SHORT_resolve @ yes, do resolve 2937.LOP_SGET_SHORT_finish: @ field ptr in r0 2938 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2939 @ no-op @ acquiring load 2940 mov r2, rINST, lsr #8 @ r2<- AA 2941 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2942 SET_VREG(r1, r2) @ fp[AA]<- r1 2943 GET_INST_OPCODE(ip) @ extract opcode from rINST 2944 GOTO_OPCODE(ip) @ jump to next instruction 2945 2946 2947/* ------------------------------ */ 2948 .balign 64 2949.L_OP_SPUT: /* 0x67 */ 2950/* File: armv5te/OP_SPUT.S */ 2951 /* 2952 * General 32-bit SPUT handler. 2953 * 2954 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2955 */ 2956 /* op vAA, field@BBBB */ 2957 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 2958 FETCH(r1, 1) @ r1<- field ref BBBB 2959 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2960 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2961 cmp r0, #0 @ is resolved entry null? 2962 beq .LOP_SPUT_resolve @ yes, do resolve 2963.LOP_SPUT_finish: @ field ptr in r0 2964 mov r2, rINST, lsr #8 @ r2<- AA 2965 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2966 GET_VREG(r1, r2) @ r1<- fp[AA] 2967 GET_INST_OPCODE(ip) @ extract opcode from rINST 2968 @ no-op @ releasing store 2969 str r1, [r0, #offStaticField_value] @ field<- vAA 2970 GOTO_OPCODE(ip) @ jump to next instruction 2971 2972/* ------------------------------ */ 2973 .balign 64 2974.L_OP_SPUT_WIDE: /* 0x68 */ 2975/* File: armv5te/OP_SPUT_WIDE.S */ 2976 /* 2977 * 64-bit SPUT handler. 2978 */ 2979 /* sput-wide vAA, field@BBBB */ 2980 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- DvmDex 2981 FETCH(r1, 1) @ r1<- field ref BBBB 2982 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 2983 mov r9, rINST, lsr #8 @ r9<- AA 2984 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 2985 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2986 cmp r2, #0 @ is resolved entry null? 2987 beq .LOP_SPUT_WIDE_resolve @ yes, do resolve 2988.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9 2989 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2990 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 2991 GET_INST_OPCODE(r10) @ extract opcode from rINST 2992 .if 0 2993 add r2, r2, #offStaticField_value @ r2<- pointer to data 2994 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 2995 .else 2996 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 2997 .endif 2998 GOTO_OPCODE(r10) @ jump to next instruction 2999 3000/* ------------------------------ */ 3001 .balign 64 3002.L_OP_SPUT_OBJECT: /* 0x69 */ 3003/* File: armv5te/OP_SPUT_OBJECT.S */ 3004 /* 3005 * 32-bit SPUT handler for objects 3006 * 3007 * for: sput-object, sput-object-volatile 3008 */ 3009 /* op vAA, field@BBBB */ 3010 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3011 FETCH(r1, 1) @ r1<- field ref BBBB 3012 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3013 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3014 cmp r0, #0 @ is resolved entry null? 3015 bne .LOP_SPUT_OBJECT_finish @ no, continue 3016 ldr r9, [rSELF, #offThread_method] @ r9<- current method 3017 EXPORT_PC() @ resolve() could throw, so export now 3018 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 3019 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 3020 cmp r0, #0 @ success? 3021 bne .LOP_SPUT_OBJECT_finish @ yes, finish 3022 b common_exceptionThrown @ no, handle exception 3023 3024 3025/* ------------------------------ */ 3026 .balign 64 3027.L_OP_SPUT_BOOLEAN: /* 0x6a */ 3028/* File: armv5te/OP_SPUT_BOOLEAN.S */ 3029/* File: armv5te/OP_SPUT.S */ 3030 /* 3031 * General 32-bit SPUT handler. 3032 * 3033 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3034 */ 3035 /* op vAA, field@BBBB */ 3036 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3037 FETCH(r1, 1) @ r1<- field ref BBBB 3038 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3039 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3040 cmp r0, #0 @ is resolved entry null? 3041 beq .LOP_SPUT_BOOLEAN_resolve @ yes, do resolve 3042.LOP_SPUT_BOOLEAN_finish: @ field ptr in r0 3043 mov r2, rINST, lsr #8 @ r2<- AA 3044 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3045 GET_VREG(r1, r2) @ r1<- fp[AA] 3046 GET_INST_OPCODE(ip) @ extract opcode from rINST 3047 @ no-op @ releasing store 3048 str r1, [r0, #offStaticField_value] @ field<- vAA 3049 GOTO_OPCODE(ip) @ jump to next instruction 3050 3051 3052/* ------------------------------ */ 3053 .balign 64 3054.L_OP_SPUT_BYTE: /* 0x6b */ 3055/* File: armv5te/OP_SPUT_BYTE.S */ 3056/* File: armv5te/OP_SPUT.S */ 3057 /* 3058 * General 32-bit SPUT handler. 3059 * 3060 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3061 */ 3062 /* op vAA, field@BBBB */ 3063 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3064 FETCH(r1, 1) @ r1<- field ref BBBB 3065 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3066 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3067 cmp r0, #0 @ is resolved entry null? 3068 beq .LOP_SPUT_BYTE_resolve @ yes, do resolve 3069.LOP_SPUT_BYTE_finish: @ field ptr in r0 3070 mov r2, rINST, lsr #8 @ r2<- AA 3071 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3072 GET_VREG(r1, r2) @ r1<- fp[AA] 3073 GET_INST_OPCODE(ip) @ extract opcode from rINST 3074 @ no-op @ releasing store 3075 str r1, [r0, #offStaticField_value] @ field<- vAA 3076 GOTO_OPCODE(ip) @ jump to next instruction 3077 3078 3079/* ------------------------------ */ 3080 .balign 64 3081.L_OP_SPUT_CHAR: /* 0x6c */ 3082/* File: armv5te/OP_SPUT_CHAR.S */ 3083/* File: armv5te/OP_SPUT.S */ 3084 /* 3085 * General 32-bit SPUT handler. 3086 * 3087 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3088 */ 3089 /* op vAA, field@BBBB */ 3090 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3091 FETCH(r1, 1) @ r1<- field ref BBBB 3092 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3093 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3094 cmp r0, #0 @ is resolved entry null? 3095 beq .LOP_SPUT_CHAR_resolve @ yes, do resolve 3096.LOP_SPUT_CHAR_finish: @ field ptr in r0 3097 mov r2, rINST, lsr #8 @ r2<- AA 3098 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3099 GET_VREG(r1, r2) @ r1<- fp[AA] 3100 GET_INST_OPCODE(ip) @ extract opcode from rINST 3101 @ no-op @ releasing store 3102 str r1, [r0, #offStaticField_value] @ field<- vAA 3103 GOTO_OPCODE(ip) @ jump to next instruction 3104 3105 3106/* ------------------------------ */ 3107 .balign 64 3108.L_OP_SPUT_SHORT: /* 0x6d */ 3109/* File: armv5te/OP_SPUT_SHORT.S */ 3110/* File: armv5te/OP_SPUT.S */ 3111 /* 3112 * General 32-bit SPUT handler. 3113 * 3114 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3115 */ 3116 /* op vAA, field@BBBB */ 3117 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 3118 FETCH(r1, 1) @ r1<- field ref BBBB 3119 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3120 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3121 cmp r0, #0 @ is resolved entry null? 3122 beq .LOP_SPUT_SHORT_resolve @ yes, do resolve 3123.LOP_SPUT_SHORT_finish: @ field ptr in r0 3124 mov r2, rINST, lsr #8 @ r2<- AA 3125 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3126 GET_VREG(r1, r2) @ r1<- fp[AA] 3127 GET_INST_OPCODE(ip) @ extract opcode from rINST 3128 @ no-op @ releasing store 3129 str r1, [r0, #offStaticField_value] @ field<- vAA 3130 GOTO_OPCODE(ip) @ jump to next instruction 3131 3132 3133/* ------------------------------ */ 3134 .balign 64 3135.L_OP_INVOKE_VIRTUAL: /* 0x6e */ 3136/* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3137 /* 3138 * Handle a virtual method call. 3139 * 3140 * for: invoke-virtual, invoke-virtual/range 3141 */ 3142 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3143 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3144 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3145 FETCH(r1, 1) @ r1<- BBBB 3146 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3147 FETCH(r10, 2) @ r10<- GFED or CCCC 3148 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3149 .if (!0) 3150 and r10, r10, #15 @ r10<- D (or stays CCCC) 3151 .endif 3152 cmp r0, #0 @ already resolved? 3153 EXPORT_PC() @ must export for invoke 3154 bne .LOP_INVOKE_VIRTUAL_continue @ yes, continue on 3155 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3156 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3157 mov r2, #METHOD_VIRTUAL @ resolver method type 3158 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3159 cmp r0, #0 @ got null? 3160 bne .LOP_INVOKE_VIRTUAL_continue @ no, continue 3161 b common_exceptionThrown @ yes, handle exception 3162 3163/* ------------------------------ */ 3164 .balign 64 3165.L_OP_INVOKE_SUPER: /* 0x6f */ 3166/* File: armv5te/OP_INVOKE_SUPER.S */ 3167 /* 3168 * Handle a "super" method call. 3169 * 3170 * for: invoke-super, invoke-super/range 3171 */ 3172 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3173 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3174 FETCH(r10, 2) @ r10<- GFED or CCCC 3175 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3176 .if (!0) 3177 and r10, r10, #15 @ r10<- D (or stays CCCC) 3178 .endif 3179 FETCH(r1, 1) @ r1<- BBBB 3180 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3181 GET_VREG(r2, r10) @ r2<- "this" ptr 3182 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3183 cmp r2, #0 @ null "this"? 3184 ldr r9, [rSELF, #offThread_method] @ r9<- current method 3185 beq common_errNullObject @ null "this", throw exception 3186 cmp r0, #0 @ already resolved? 3187 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 3188 EXPORT_PC() @ must export for invoke 3189 bne .LOP_INVOKE_SUPER_continue @ resolved, continue on 3190 b .LOP_INVOKE_SUPER_resolve @ do resolve now 3191 3192/* ------------------------------ */ 3193 .balign 64 3194.L_OP_INVOKE_DIRECT: /* 0x70 */ 3195/* File: armv5te/OP_INVOKE_DIRECT.S */ 3196 /* 3197 * Handle a direct method call. 3198 * 3199 * (We could defer the "is 'this' pointer null" test to the common 3200 * method invocation code, and use a flag to indicate that static 3201 * calls don't count. If we do this as part of copying the arguments 3202 * out we could avoiding loading the first arg twice.) 3203 * 3204 * for: invoke-direct, invoke-direct/range 3205 */ 3206 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3207 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3208 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3209 FETCH(r1, 1) @ r1<- BBBB 3210 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3211 FETCH(r10, 2) @ r10<- GFED or CCCC 3212 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3213 .if (!0) 3214 and r10, r10, #15 @ r10<- D (or stays CCCC) 3215 .endif 3216 cmp r0, #0 @ already resolved? 3217 EXPORT_PC() @ must export for invoke 3218 GET_VREG(r2, r10) @ r2<- "this" ptr 3219 beq .LOP_INVOKE_DIRECT_resolve @ not resolved, do it now 3220.LOP_INVOKE_DIRECT_finish: 3221 cmp r2, #0 @ null "this" ref? 3222 bne common_invokeMethodNoRange @ no, continue on 3223 b common_errNullObject @ yes, throw exception 3224 3225/* ------------------------------ */ 3226 .balign 64 3227.L_OP_INVOKE_STATIC: /* 0x71 */ 3228/* File: armv5te/OP_INVOKE_STATIC.S */ 3229 /* 3230 * Handle a static method call. 3231 * 3232 * for: invoke-static, invoke-static/range 3233 */ 3234 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3235 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3236 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3237 FETCH(r1, 1) @ r1<- BBBB 3238 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3239 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3240 cmp r0, #0 @ already resolved? 3241 EXPORT_PC() @ must export for invoke 3242 bne common_invokeMethodNoRange @ yes, continue on 32430: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3244 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3245 mov r2, #METHOD_STATIC @ resolver method type 3246 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3247 cmp r0, #0 @ got null? 3248 bne common_invokeMethodNoRange @ no, continue 3249 b common_exceptionThrown @ yes, handle exception 3250 3251/* ------------------------------ */ 3252 .balign 64 3253.L_OP_INVOKE_INTERFACE: /* 0x72 */ 3254/* File: armv5te/OP_INVOKE_INTERFACE.S */ 3255 /* 3256 * Handle an interface method call. 3257 * 3258 * for: invoke-interface, invoke-interface/range 3259 */ 3260 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3261 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3262 FETCH(r2, 2) @ r2<- FEDC or CCCC 3263 FETCH(r1, 1) @ r1<- BBBB 3264 .if (!0) 3265 and r2, r2, #15 @ r2<- C (or stays CCCC) 3266 .endif 3267 EXPORT_PC() @ must export for invoke 3268 GET_VREG(r0, r2) @ r0<- first arg ("this") 3269 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- methodClassDex 3270 cmp r0, #0 @ null obj? 3271 ldr r2, [rSELF, #offThread_method] @ r2<- method 3272 beq common_errNullObject @ yes, fail 3273 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 3274 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3275 cmp r0, #0 @ failed? 3276 beq common_exceptionThrown @ yes, handle exception 3277 b common_invokeMethodNoRange @ jump to common handler 3278 3279/* ------------------------------ */ 3280 .balign 64 3281.L_OP_UNUSED_73: /* 0x73 */ 3282/* File: armv5te/OP_UNUSED_73.S */ 3283/* File: armv5te/unused.S */ 3284 bl common_abort 3285 3286 3287/* ------------------------------ */ 3288 .balign 64 3289.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 3290/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */ 3291/* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3292 /* 3293 * Handle a virtual method call. 3294 * 3295 * for: invoke-virtual, invoke-virtual/range 3296 */ 3297 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3298 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3299 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3300 FETCH(r1, 1) @ r1<- BBBB 3301 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3302 FETCH(r10, 2) @ r10<- GFED or CCCC 3303 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3304 .if (!1) 3305 and r10, r10, #15 @ r10<- D (or stays CCCC) 3306 .endif 3307 cmp r0, #0 @ already resolved? 3308 EXPORT_PC() @ must export for invoke 3309 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ yes, continue on 3310 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3311 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3312 mov r2, #METHOD_VIRTUAL @ resolver method type 3313 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3314 cmp r0, #0 @ got null? 3315 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ no, continue 3316 b common_exceptionThrown @ yes, handle exception 3317 3318 3319/* ------------------------------ */ 3320 .balign 64 3321.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 3322/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */ 3323/* File: armv5te/OP_INVOKE_SUPER.S */ 3324 /* 3325 * Handle a "super" method call. 3326 * 3327 * for: invoke-super, invoke-super/range 3328 */ 3329 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3330 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3331 FETCH(r10, 2) @ r10<- GFED or CCCC 3332 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3333 .if (!1) 3334 and r10, r10, #15 @ r10<- D (or stays CCCC) 3335 .endif 3336 FETCH(r1, 1) @ r1<- BBBB 3337 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3338 GET_VREG(r2, r10) @ r2<- "this" ptr 3339 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3340 cmp r2, #0 @ null "this"? 3341 ldr r9, [rSELF, #offThread_method] @ r9<- current method 3342 beq common_errNullObject @ null "this", throw exception 3343 cmp r0, #0 @ already resolved? 3344 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 3345 EXPORT_PC() @ must export for invoke 3346 bne .LOP_INVOKE_SUPER_RANGE_continue @ resolved, continue on 3347 b .LOP_INVOKE_SUPER_RANGE_resolve @ do resolve now 3348 3349 3350/* ------------------------------ */ 3351 .balign 64 3352.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 3353/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */ 3354/* File: armv5te/OP_INVOKE_DIRECT.S */ 3355 /* 3356 * Handle a direct method call. 3357 * 3358 * (We could defer the "is 'this' pointer null" test to the common 3359 * method invocation code, and use a flag to indicate that static 3360 * calls don't count. If we do this as part of copying the arguments 3361 * out we could avoiding loading the first arg twice.) 3362 * 3363 * for: invoke-direct, invoke-direct/range 3364 */ 3365 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3366 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3367 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3368 FETCH(r1, 1) @ r1<- BBBB 3369 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3370 FETCH(r10, 2) @ r10<- GFED or CCCC 3371 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3372 .if (!1) 3373 and r10, r10, #15 @ r10<- D (or stays CCCC) 3374 .endif 3375 cmp r0, #0 @ already resolved? 3376 EXPORT_PC() @ must export for invoke 3377 GET_VREG(r2, r10) @ r2<- "this" ptr 3378 beq .LOP_INVOKE_DIRECT_RANGE_resolve @ not resolved, do it now 3379.LOP_INVOKE_DIRECT_RANGE_finish: 3380 cmp r2, #0 @ null "this" ref? 3381 bne common_invokeMethodRange @ no, continue on 3382 b common_errNullObject @ yes, throw exception 3383 3384 3385/* ------------------------------ */ 3386 .balign 64 3387.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 3388/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */ 3389/* File: armv5te/OP_INVOKE_STATIC.S */ 3390 /* 3391 * Handle a static method call. 3392 * 3393 * for: invoke-static, invoke-static/range 3394 */ 3395 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3396 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3397 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 3398 FETCH(r1, 1) @ r1<- BBBB 3399 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3400 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3401 cmp r0, #0 @ already resolved? 3402 EXPORT_PC() @ must export for invoke 3403 bne common_invokeMethodRange @ yes, continue on 34040: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 3405 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3406 mov r2, #METHOD_STATIC @ resolver method type 3407 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3408 cmp r0, #0 @ got null? 3409 bne common_invokeMethodRange @ no, continue 3410 b common_exceptionThrown @ yes, handle exception 3411 3412 3413/* ------------------------------ */ 3414 .balign 64 3415.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 3416/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */ 3417/* File: armv5te/OP_INVOKE_INTERFACE.S */ 3418 /* 3419 * Handle an interface method call. 3420 * 3421 * for: invoke-interface, invoke-interface/range 3422 */ 3423 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3424 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3425 FETCH(r2, 2) @ r2<- FEDC or CCCC 3426 FETCH(r1, 1) @ r1<- BBBB 3427 .if (!1) 3428 and r2, r2, #15 @ r2<- C (or stays CCCC) 3429 .endif 3430 EXPORT_PC() @ must export for invoke 3431 GET_VREG(r0, r2) @ r0<- first arg ("this") 3432 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- methodClassDex 3433 cmp r0, #0 @ null obj? 3434 ldr r2, [rSELF, #offThread_method] @ r2<- method 3435 beq common_errNullObject @ yes, fail 3436 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 3437 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3438 cmp r0, #0 @ failed? 3439 beq common_exceptionThrown @ yes, handle exception 3440 b common_invokeMethodRange @ jump to common handler 3441 3442 3443/* ------------------------------ */ 3444 .balign 64 3445.L_OP_UNUSED_79: /* 0x79 */ 3446/* File: armv5te/OP_UNUSED_79.S */ 3447/* File: armv5te/unused.S */ 3448 bl common_abort 3449 3450 3451/* ------------------------------ */ 3452 .balign 64 3453.L_OP_UNUSED_7A: /* 0x7a */ 3454/* File: armv5te/OP_UNUSED_7A.S */ 3455/* File: armv5te/unused.S */ 3456 bl common_abort 3457 3458 3459/* ------------------------------ */ 3460 .balign 64 3461.L_OP_NEG_INT: /* 0x7b */ 3462/* File: armv6t2/OP_NEG_INT.S */ 3463/* File: armv6t2/unop.S */ 3464 /* 3465 * Generic 32-bit unary operation. Provide an "instr" line that 3466 * specifies an instruction that performs "result = op r0". 3467 * This could be an ARM instruction or a function call. 3468 * 3469 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3470 * int-to-byte, int-to-char, int-to-short 3471 */ 3472 /* unop vA, vB */ 3473 mov r3, rINST, lsr #12 @ r3<- B 3474 ubfx r9, rINST, #8, #4 @ r9<- A 3475 GET_VREG(r0, r3) @ r0<- vB 3476 @ optional op; may set condition codes 3477 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3478 rsb r0, r0, #0 @ r0<- op, r0-r3 changed 3479 GET_INST_OPCODE(ip) @ extract opcode from rINST 3480 SET_VREG(r0, r9) @ vAA<- r0 3481 GOTO_OPCODE(ip) @ jump to next instruction 3482 /* 8-9 instructions */ 3483 3484 3485/* ------------------------------ */ 3486 .balign 64 3487.L_OP_NOT_INT: /* 0x7c */ 3488/* File: armv6t2/OP_NOT_INT.S */ 3489/* File: armv6t2/unop.S */ 3490 /* 3491 * Generic 32-bit unary operation. Provide an "instr" line that 3492 * specifies an instruction that performs "result = op r0". 3493 * This could be an ARM instruction or a function call. 3494 * 3495 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3496 * int-to-byte, int-to-char, int-to-short 3497 */ 3498 /* unop vA, vB */ 3499 mov r3, rINST, lsr #12 @ r3<- B 3500 ubfx r9, rINST, #8, #4 @ r9<- A 3501 GET_VREG(r0, r3) @ r0<- vB 3502 @ optional op; may set condition codes 3503 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3504 mvn r0, r0 @ r0<- op, r0-r3 changed 3505 GET_INST_OPCODE(ip) @ extract opcode from rINST 3506 SET_VREG(r0, r9) @ vAA<- r0 3507 GOTO_OPCODE(ip) @ jump to next instruction 3508 /* 8-9 instructions */ 3509 3510 3511/* ------------------------------ */ 3512 .balign 64 3513.L_OP_NEG_LONG: /* 0x7d */ 3514/* File: armv6t2/OP_NEG_LONG.S */ 3515/* File: armv6t2/unopWide.S */ 3516 /* 3517 * Generic 64-bit unary operation. Provide an "instr" line that 3518 * specifies an instruction that performs "result = op r0/r1". 3519 * This could be an ARM instruction or a function call. 3520 * 3521 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3522 */ 3523 /* unop vA, vB */ 3524 mov r3, rINST, lsr #12 @ r3<- B 3525 ubfx r9, rINST, #8, #4 @ r9<- A 3526 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3527 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3528 ldmia r3, {r0-r1} @ r0/r1<- vAA 3529 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3530 rsbs r0, r0, #0 @ optional op; may set condition codes 3531 rsc r1, r1, #0 @ r0/r1<- op, r2-r3 changed 3532 GET_INST_OPCODE(ip) @ extract opcode from rINST 3533 stmia r9, {r0-r1} @ vAA<- r0/r1 3534 GOTO_OPCODE(ip) @ jump to next instruction 3535 /* 10-11 instructions */ 3536 3537 3538/* ------------------------------ */ 3539 .balign 64 3540.L_OP_NOT_LONG: /* 0x7e */ 3541/* File: armv6t2/OP_NOT_LONG.S */ 3542/* File: armv6t2/unopWide.S */ 3543 /* 3544 * Generic 64-bit unary operation. Provide an "instr" line that 3545 * specifies an instruction that performs "result = op r0/r1". 3546 * This could be an ARM instruction or a function call. 3547 * 3548 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3549 */ 3550 /* unop vA, vB */ 3551 mov r3, rINST, lsr #12 @ r3<- B 3552 ubfx r9, rINST, #8, #4 @ r9<- A 3553 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3554 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3555 ldmia r3, {r0-r1} @ r0/r1<- vAA 3556 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3557 mvn r0, r0 @ optional op; may set condition codes 3558 mvn r1, r1 @ r0/r1<- op, r2-r3 changed 3559 GET_INST_OPCODE(ip) @ extract opcode from rINST 3560 stmia r9, {r0-r1} @ vAA<- r0/r1 3561 GOTO_OPCODE(ip) @ jump to next instruction 3562 /* 10-11 instructions */ 3563 3564 3565/* ------------------------------ */ 3566 .balign 64 3567.L_OP_NEG_FLOAT: /* 0x7f */ 3568/* File: armv6t2/OP_NEG_FLOAT.S */ 3569/* File: armv6t2/unop.S */ 3570 /* 3571 * Generic 32-bit unary operation. Provide an "instr" line that 3572 * specifies an instruction that performs "result = op r0". 3573 * This could be an ARM instruction or a function call. 3574 * 3575 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3576 * int-to-byte, int-to-char, int-to-short 3577 */ 3578 /* unop vA, vB */ 3579 mov r3, rINST, lsr #12 @ r3<- B 3580 ubfx r9, rINST, #8, #4 @ r9<- A 3581 GET_VREG(r0, r3) @ r0<- vB 3582 @ optional op; may set condition codes 3583 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3584 add r0, r0, #0x80000000 @ r0<- op, r0-r3 changed 3585 GET_INST_OPCODE(ip) @ extract opcode from rINST 3586 SET_VREG(r0, r9) @ vAA<- r0 3587 GOTO_OPCODE(ip) @ jump to next instruction 3588 /* 8-9 instructions */ 3589 3590 3591/* ------------------------------ */ 3592 .balign 64 3593.L_OP_NEG_DOUBLE: /* 0x80 */ 3594/* File: armv6t2/OP_NEG_DOUBLE.S */ 3595/* File: armv6t2/unopWide.S */ 3596 /* 3597 * Generic 64-bit unary operation. Provide an "instr" line that 3598 * specifies an instruction that performs "result = op r0/r1". 3599 * This could be an ARM instruction or a function call. 3600 * 3601 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3602 */ 3603 /* unop vA, vB */ 3604 mov r3, rINST, lsr #12 @ r3<- B 3605 ubfx r9, rINST, #8, #4 @ r9<- A 3606 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3607 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3608 ldmia r3, {r0-r1} @ r0/r1<- vAA 3609 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3610 @ optional op; may set condition codes 3611 add r1, r1, #0x80000000 @ r0/r1<- op, r2-r3 changed 3612 GET_INST_OPCODE(ip) @ extract opcode from rINST 3613 stmia r9, {r0-r1} @ vAA<- r0/r1 3614 GOTO_OPCODE(ip) @ jump to next instruction 3615 /* 10-11 instructions */ 3616 3617 3618/* ------------------------------ */ 3619 .balign 64 3620.L_OP_INT_TO_LONG: /* 0x81 */ 3621/* File: armv6t2/OP_INT_TO_LONG.S */ 3622/* File: armv6t2/unopWider.S */ 3623 /* 3624 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3625 * that specifies an instruction that performs "result = op r0", where 3626 * "result" is a 64-bit quantity in r0/r1. 3627 * 3628 * For: int-to-long, int-to-double, float-to-long, float-to-double 3629 */ 3630 /* unop vA, vB */ 3631 mov r3, rINST, lsr #12 @ r3<- B 3632 ubfx r9, rINST, #8, #4 @ r9<- A 3633 GET_VREG(r0, r3) @ r0<- vB 3634 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3635 @ optional op; may set condition codes 3636 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3637 mov r1, r0, asr #31 @ r0<- op, r0-r3 changed 3638 GET_INST_OPCODE(ip) @ extract opcode from rINST 3639 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3640 GOTO_OPCODE(ip) @ jump to next instruction 3641 /* 9-10 instructions */ 3642 3643 3644/* ------------------------------ */ 3645 .balign 64 3646.L_OP_INT_TO_FLOAT: /* 0x82 */ 3647/* File: arm-vfp/OP_INT_TO_FLOAT.S */ 3648/* File: arm-vfp/funop.S */ 3649 /* 3650 * Generic 32-bit unary floating-point operation. Provide an "instr" 3651 * line that specifies an instruction that performs "s1 = op s0". 3652 * 3653 * for: int-to-float, float-to-int 3654 */ 3655 /* unop vA, vB */ 3656 mov r3, rINST, lsr #12 @ r3<- B 3657 mov r9, rINST, lsr #8 @ r9<- A+ 3658 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3659 flds s0, [r3] @ s0<- vB 3660 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3661 and r9, r9, #15 @ r9<- A 3662 fsitos s1, s0 @ s1<- op 3663 GET_INST_OPCODE(ip) @ extract opcode from rINST 3664 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3665 fsts s1, [r9] @ vA<- s1 3666 GOTO_OPCODE(ip) @ jump to next instruction 3667 3668 3669/* ------------------------------ */ 3670 .balign 64 3671.L_OP_INT_TO_DOUBLE: /* 0x83 */ 3672/* File: arm-vfp/OP_INT_TO_DOUBLE.S */ 3673/* File: arm-vfp/funopWider.S */ 3674 /* 3675 * Generic 32bit-to-64bit floating point unary operation. Provide an 3676 * "instr" line that specifies an instruction that performs "d0 = op s0". 3677 * 3678 * For: int-to-double, float-to-double 3679 */ 3680 /* unop vA, vB */ 3681 mov r3, rINST, lsr #12 @ r3<- B 3682 mov r9, rINST, lsr #8 @ r9<- A+ 3683 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3684 flds s0, [r3] @ s0<- vB 3685 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3686 and r9, r9, #15 @ r9<- A 3687 fsitod d0, s0 @ d0<- op 3688 GET_INST_OPCODE(ip) @ extract opcode from rINST 3689 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3690 fstd d0, [r9] @ vA<- d0 3691 GOTO_OPCODE(ip) @ jump to next instruction 3692 3693 3694/* ------------------------------ */ 3695 .balign 64 3696.L_OP_LONG_TO_INT: /* 0x84 */ 3697/* File: armv5te/OP_LONG_TO_INT.S */ 3698/* we ignore the high word, making this equivalent to a 32-bit reg move */ 3699/* File: armv5te/OP_MOVE.S */ 3700 /* for move, move-object, long-to-int */ 3701 /* op vA, vB */ 3702 mov r1, rINST, lsr #12 @ r1<- B from 15:12 3703 mov r0, rINST, lsr #8 @ r0<- A from 11:8 3704 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3705 GET_VREG(r2, r1) @ r2<- fp[B] 3706 and r0, r0, #15 3707 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 3708 SET_VREG(r2, r0) @ fp[A]<- r2 3709 GOTO_OPCODE(ip) @ execute next instruction 3710 3711 3712/* ------------------------------ */ 3713 .balign 64 3714.L_OP_LONG_TO_FLOAT: /* 0x85 */ 3715/* File: armv6t2/OP_LONG_TO_FLOAT.S */ 3716/* File: armv6t2/unopNarrower.S */ 3717 /* 3718 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 3719 * that specifies an instruction that performs "result = op r0/r1", where 3720 * "result" is a 32-bit quantity in r0. 3721 * 3722 * For: long-to-float, double-to-int, double-to-float 3723 * 3724 * (This would work for long-to-int, but that instruction is actually 3725 * an exact match for OP_MOVE.) 3726 */ 3727 /* unop vA, vB */ 3728 mov r3, rINST, lsr #12 @ r3<- B 3729 ubfx r9, rINST, #8, #4 @ r9<- A 3730 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3731 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 3732 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3733 @ optional op; may set condition codes 3734 bl __aeabi_l2f @ r0<- op, r0-r3 changed 3735 GET_INST_OPCODE(ip) @ extract opcode from rINST 3736 SET_VREG(r0, r9) @ vA<- r0 3737 GOTO_OPCODE(ip) @ jump to next instruction 3738 /* 9-10 instructions */ 3739 3740 3741/* ------------------------------ */ 3742 .balign 64 3743.L_OP_LONG_TO_DOUBLE: /* 0x86 */ 3744/* File: armv6t2/OP_LONG_TO_DOUBLE.S */ 3745/* File: armv6t2/unopWide.S */ 3746 /* 3747 * Generic 64-bit unary operation. Provide an "instr" line that 3748 * specifies an instruction that performs "result = op r0/r1". 3749 * This could be an ARM instruction or a function call. 3750 * 3751 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3752 */ 3753 /* unop vA, vB */ 3754 mov r3, rINST, lsr #12 @ r3<- B 3755 ubfx r9, rINST, #8, #4 @ r9<- A 3756 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3757 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3758 ldmia r3, {r0-r1} @ r0/r1<- vAA 3759 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3760 @ optional op; may set condition codes 3761 bl __aeabi_l2d @ r0/r1<- op, r2-r3 changed 3762 GET_INST_OPCODE(ip) @ extract opcode from rINST 3763 stmia r9, {r0-r1} @ vAA<- r0/r1 3764 GOTO_OPCODE(ip) @ jump to next instruction 3765 /* 10-11 instructions */ 3766 3767 3768/* ------------------------------ */ 3769 .balign 64 3770.L_OP_FLOAT_TO_INT: /* 0x87 */ 3771/* File: arm-vfp/OP_FLOAT_TO_INT.S */ 3772/* File: arm-vfp/funop.S */ 3773 /* 3774 * Generic 32-bit unary floating-point operation. Provide an "instr" 3775 * line that specifies an instruction that performs "s1 = op s0". 3776 * 3777 * for: int-to-float, float-to-int 3778 */ 3779 /* unop vA, vB */ 3780 mov r3, rINST, lsr #12 @ r3<- B 3781 mov r9, rINST, lsr #8 @ r9<- A+ 3782 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3783 flds s0, [r3] @ s0<- vB 3784 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3785 and r9, r9, #15 @ r9<- A 3786 ftosizs s1, s0 @ s1<- op 3787 GET_INST_OPCODE(ip) @ extract opcode from rINST 3788 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3789 fsts s1, [r9] @ vA<- s1 3790 GOTO_OPCODE(ip) @ jump to next instruction 3791 3792 3793/* ------------------------------ */ 3794 .balign 64 3795.L_OP_FLOAT_TO_LONG: /* 0x88 */ 3796/* File: armv6t2/OP_FLOAT_TO_LONG.S */ 3797@include "armv6t2/unopWider.S" {"instr":"bl __aeabi_f2lz"} 3798/* File: armv6t2/unopWider.S */ 3799 /* 3800 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3801 * that specifies an instruction that performs "result = op r0", where 3802 * "result" is a 64-bit quantity in r0/r1. 3803 * 3804 * For: int-to-long, int-to-double, float-to-long, float-to-double 3805 */ 3806 /* unop vA, vB */ 3807 mov r3, rINST, lsr #12 @ r3<- B 3808 ubfx r9, rINST, #8, #4 @ r9<- A 3809 GET_VREG(r0, r3) @ r0<- vB 3810 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3811 @ optional op; may set condition codes 3812 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3813 bl f2l_doconv @ r0<- op, r0-r3 changed 3814 GET_INST_OPCODE(ip) @ extract opcode from rINST 3815 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3816 GOTO_OPCODE(ip) @ jump to next instruction 3817 /* 9-10 instructions */ 3818 3819 3820 3821/* ------------------------------ */ 3822 .balign 64 3823.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 3824/* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */ 3825/* File: arm-vfp/funopWider.S */ 3826 /* 3827 * Generic 32bit-to-64bit floating point unary operation. Provide an 3828 * "instr" line that specifies an instruction that performs "d0 = op s0". 3829 * 3830 * For: int-to-double, float-to-double 3831 */ 3832 /* unop vA, vB */ 3833 mov r3, rINST, lsr #12 @ r3<- B 3834 mov r9, rINST, lsr #8 @ r9<- A+ 3835 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3836 flds s0, [r3] @ s0<- vB 3837 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3838 and r9, r9, #15 @ r9<- A 3839 fcvtds d0, s0 @ d0<- op 3840 GET_INST_OPCODE(ip) @ extract opcode from rINST 3841 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3842 fstd d0, [r9] @ vA<- d0 3843 GOTO_OPCODE(ip) @ jump to next instruction 3844 3845 3846/* ------------------------------ */ 3847 .balign 64 3848.L_OP_DOUBLE_TO_INT: /* 0x8a */ 3849/* File: arm-vfp/OP_DOUBLE_TO_INT.S */ 3850/* File: arm-vfp/funopNarrower.S */ 3851 /* 3852 * Generic 64bit-to-32bit unary floating point operation. Provide an 3853 * "instr" line that specifies an instruction that performs "s0 = op d0". 3854 * 3855 * For: double-to-int, double-to-float 3856 */ 3857 /* unop vA, vB */ 3858 mov r3, rINST, lsr #12 @ r3<- B 3859 mov r9, rINST, lsr #8 @ r9<- A+ 3860 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3861 fldd d0, [r3] @ d0<- vB 3862 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3863 and r9, r9, #15 @ r9<- A 3864 ftosizd s0, d0 @ s0<- op 3865 GET_INST_OPCODE(ip) @ extract opcode from rINST 3866 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3867 fsts s0, [r9] @ vA<- s0 3868 GOTO_OPCODE(ip) @ jump to next instruction 3869 3870 3871/* ------------------------------ */ 3872 .balign 64 3873.L_OP_DOUBLE_TO_LONG: /* 0x8b */ 3874/* File: armv6t2/OP_DOUBLE_TO_LONG.S */ 3875@include "armv6t2/unopWide.S" {"instr":"bl __aeabi_d2lz"} 3876/* File: armv6t2/unopWide.S */ 3877 /* 3878 * Generic 64-bit unary operation. Provide an "instr" line that 3879 * specifies an instruction that performs "result = op r0/r1". 3880 * This could be an ARM instruction or a function call. 3881 * 3882 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3883 */ 3884 /* unop vA, vB */ 3885 mov r3, rINST, lsr #12 @ r3<- B 3886 ubfx r9, rINST, #8, #4 @ r9<- A 3887 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3888 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3889 ldmia r3, {r0-r1} @ r0/r1<- vAA 3890 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3891 @ optional op; may set condition codes 3892 bl d2l_doconv @ r0/r1<- op, r2-r3 changed 3893 GET_INST_OPCODE(ip) @ extract opcode from rINST 3894 stmia r9, {r0-r1} @ vAA<- r0/r1 3895 GOTO_OPCODE(ip) @ jump to next instruction 3896 /* 10-11 instructions */ 3897 3898 3899 3900/* ------------------------------ */ 3901 .balign 64 3902.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 3903/* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */ 3904/* File: arm-vfp/funopNarrower.S */ 3905 /* 3906 * Generic 64bit-to-32bit unary floating point operation. Provide an 3907 * "instr" line that specifies an instruction that performs "s0 = op d0". 3908 * 3909 * For: double-to-int, double-to-float 3910 */ 3911 /* unop vA, vB */ 3912 mov r3, rINST, lsr #12 @ r3<- B 3913 mov r9, rINST, lsr #8 @ r9<- A+ 3914 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3915 fldd d0, [r3] @ d0<- vB 3916 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3917 and r9, r9, #15 @ r9<- A 3918 fcvtsd s0, d0 @ s0<- op 3919 GET_INST_OPCODE(ip) @ extract opcode from rINST 3920 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3921 fsts s0, [r9] @ vA<- s0 3922 GOTO_OPCODE(ip) @ jump to next instruction 3923 3924 3925/* ------------------------------ */ 3926 .balign 64 3927.L_OP_INT_TO_BYTE: /* 0x8d */ 3928/* File: armv6t2/OP_INT_TO_BYTE.S */ 3929/* File: armv6t2/unop.S */ 3930 /* 3931 * Generic 32-bit unary operation. Provide an "instr" line that 3932 * specifies an instruction that performs "result = op r0". 3933 * This could be an ARM instruction or a function call. 3934 * 3935 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3936 * int-to-byte, int-to-char, int-to-short 3937 */ 3938 /* unop vA, vB */ 3939 mov r3, rINST, lsr #12 @ r3<- B 3940 ubfx r9, rINST, #8, #4 @ r9<- A 3941 GET_VREG(r0, r3) @ r0<- vB 3942 @ optional op; may set condition codes 3943 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3944 sxtb r0, r0 @ r0<- op, r0-r3 changed 3945 GET_INST_OPCODE(ip) @ extract opcode from rINST 3946 SET_VREG(r0, r9) @ vAA<- r0 3947 GOTO_OPCODE(ip) @ jump to next instruction 3948 /* 8-9 instructions */ 3949 3950 3951/* ------------------------------ */ 3952 .balign 64 3953.L_OP_INT_TO_CHAR: /* 0x8e */ 3954/* File: armv6t2/OP_INT_TO_CHAR.S */ 3955/* File: armv6t2/unop.S */ 3956 /* 3957 * Generic 32-bit unary operation. Provide an "instr" line that 3958 * specifies an instruction that performs "result = op r0". 3959 * This could be an ARM instruction or a function call. 3960 * 3961 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3962 * int-to-byte, int-to-char, int-to-short 3963 */ 3964 /* unop vA, vB */ 3965 mov r3, rINST, lsr #12 @ r3<- B 3966 ubfx r9, rINST, #8, #4 @ r9<- A 3967 GET_VREG(r0, r3) @ r0<- vB 3968 @ optional op; may set condition codes 3969 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3970 uxth r0, r0 @ r0<- op, r0-r3 changed 3971 GET_INST_OPCODE(ip) @ extract opcode from rINST 3972 SET_VREG(r0, r9) @ vAA<- r0 3973 GOTO_OPCODE(ip) @ jump to next instruction 3974 /* 8-9 instructions */ 3975 3976 3977/* ------------------------------ */ 3978 .balign 64 3979.L_OP_INT_TO_SHORT: /* 0x8f */ 3980/* File: armv6t2/OP_INT_TO_SHORT.S */ 3981/* File: armv6t2/unop.S */ 3982 /* 3983 * Generic 32-bit unary operation. Provide an "instr" line that 3984 * specifies an instruction that performs "result = op r0". 3985 * This could be an ARM instruction or a function call. 3986 * 3987 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3988 * int-to-byte, int-to-char, int-to-short 3989 */ 3990 /* unop vA, vB */ 3991 mov r3, rINST, lsr #12 @ r3<- B 3992 ubfx r9, rINST, #8, #4 @ r9<- A 3993 GET_VREG(r0, r3) @ r0<- vB 3994 @ optional op; may set condition codes 3995 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3996 sxth r0, r0 @ r0<- op, r0-r3 changed 3997 GET_INST_OPCODE(ip) @ extract opcode from rINST 3998 SET_VREG(r0, r9) @ vAA<- r0 3999 GOTO_OPCODE(ip) @ jump to next instruction 4000 /* 8-9 instructions */ 4001 4002 4003/* ------------------------------ */ 4004 .balign 64 4005.L_OP_ADD_INT: /* 0x90 */ 4006/* File: armv5te/OP_ADD_INT.S */ 4007/* File: armv5te/binop.S */ 4008 /* 4009 * Generic 32-bit binary operation. Provide an "instr" line that 4010 * specifies an instruction that performs "result = r0 op r1". 4011 * This could be an ARM instruction or a function call. (If the result 4012 * comes back in a register other than r0, you can override "result".) 4013 * 4014 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4015 * vCC (r1). Useful for integer division and modulus. Note that we 4016 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4017 * handles it correctly. 4018 * 4019 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4020 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4021 * mul-float, div-float, rem-float 4022 */ 4023 /* binop vAA, vBB, vCC */ 4024 FETCH(r0, 1) @ r0<- CCBB 4025 mov r9, rINST, lsr #8 @ r9<- AA 4026 mov r3, r0, lsr #8 @ r3<- CC 4027 and r2, r0, #255 @ r2<- BB 4028 GET_VREG(r1, r3) @ r1<- vCC 4029 GET_VREG(r0, r2) @ r0<- vBB 4030 .if 0 4031 cmp r1, #0 @ is second operand zero? 4032 beq common_errDivideByZero 4033 .endif 4034 4035 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4036 @ optional op; may set condition codes 4037 add r0, r0, r1 @ r0<- op, r0-r3 changed 4038 GET_INST_OPCODE(ip) @ extract opcode from rINST 4039 SET_VREG(r0, r9) @ vAA<- r0 4040 GOTO_OPCODE(ip) @ jump to next instruction 4041 /* 11-14 instructions */ 4042 4043 4044/* ------------------------------ */ 4045 .balign 64 4046.L_OP_SUB_INT: /* 0x91 */ 4047/* File: armv5te/OP_SUB_INT.S */ 4048/* File: armv5te/binop.S */ 4049 /* 4050 * Generic 32-bit binary operation. Provide an "instr" line that 4051 * specifies an instruction that performs "result = r0 op r1". 4052 * This could be an ARM instruction or a function call. (If the result 4053 * comes back in a register other than r0, you can override "result".) 4054 * 4055 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4056 * vCC (r1). Useful for integer division and modulus. Note that we 4057 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4058 * handles it correctly. 4059 * 4060 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4061 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4062 * mul-float, div-float, rem-float 4063 */ 4064 /* binop vAA, vBB, vCC */ 4065 FETCH(r0, 1) @ r0<- CCBB 4066 mov r9, rINST, lsr #8 @ r9<- AA 4067 mov r3, r0, lsr #8 @ r3<- CC 4068 and r2, r0, #255 @ r2<- BB 4069 GET_VREG(r1, r3) @ r1<- vCC 4070 GET_VREG(r0, r2) @ r0<- vBB 4071 .if 0 4072 cmp r1, #0 @ is second operand zero? 4073 beq common_errDivideByZero 4074 .endif 4075 4076 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4077 @ optional op; may set condition codes 4078 sub r0, r0, r1 @ r0<- op, r0-r3 changed 4079 GET_INST_OPCODE(ip) @ extract opcode from rINST 4080 SET_VREG(r0, r9) @ vAA<- r0 4081 GOTO_OPCODE(ip) @ jump to next instruction 4082 /* 11-14 instructions */ 4083 4084 4085/* ------------------------------ */ 4086 .balign 64 4087.L_OP_MUL_INT: /* 0x92 */ 4088/* File: armv5te/OP_MUL_INT.S */ 4089/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 4090/* File: armv5te/binop.S */ 4091 /* 4092 * Generic 32-bit binary operation. Provide an "instr" line that 4093 * specifies an instruction that performs "result = r0 op r1". 4094 * This could be an ARM instruction or a function call. (If the result 4095 * comes back in a register other than r0, you can override "result".) 4096 * 4097 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4098 * vCC (r1). Useful for integer division and modulus. Note that we 4099 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4100 * handles it correctly. 4101 * 4102 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4103 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4104 * mul-float, div-float, rem-float 4105 */ 4106 /* binop vAA, vBB, vCC */ 4107 FETCH(r0, 1) @ r0<- CCBB 4108 mov r9, rINST, lsr #8 @ r9<- AA 4109 mov r3, r0, lsr #8 @ r3<- CC 4110 and r2, r0, #255 @ r2<- BB 4111 GET_VREG(r1, r3) @ r1<- vCC 4112 GET_VREG(r0, r2) @ r0<- vBB 4113 .if 0 4114 cmp r1, #0 @ is second operand zero? 4115 beq common_errDivideByZero 4116 .endif 4117 4118 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4119 @ optional op; may set condition codes 4120 mul r0, r1, r0 @ r0<- op, r0-r3 changed 4121 GET_INST_OPCODE(ip) @ extract opcode from rINST 4122 SET_VREG(r0, r9) @ vAA<- r0 4123 GOTO_OPCODE(ip) @ jump to next instruction 4124 /* 11-14 instructions */ 4125 4126 4127/* ------------------------------ */ 4128 .balign 64 4129.L_OP_DIV_INT: /* 0x93 */ 4130/* File: armv5te/OP_DIV_INT.S */ 4131/* File: armv5te/binop.S */ 4132 /* 4133 * Generic 32-bit binary operation. Provide an "instr" line that 4134 * specifies an instruction that performs "result = r0 op r1". 4135 * This could be an ARM instruction or a function call. (If the result 4136 * comes back in a register other than r0, you can override "result".) 4137 * 4138 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4139 * vCC (r1). Useful for integer division and modulus. Note that we 4140 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4141 * handles it correctly. 4142 * 4143 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4144 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4145 * mul-float, div-float, rem-float 4146 */ 4147 /* binop vAA, vBB, vCC */ 4148 FETCH(r0, 1) @ r0<- CCBB 4149 mov r9, rINST, lsr #8 @ r9<- AA 4150 mov r3, r0, lsr #8 @ r3<- CC 4151 and r2, r0, #255 @ r2<- BB 4152 GET_VREG(r1, r3) @ r1<- vCC 4153 GET_VREG(r0, r2) @ r0<- vBB 4154 .if 1 4155 cmp r1, #0 @ is second operand zero? 4156 beq common_errDivideByZero 4157 .endif 4158 4159 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4160 @ optional op; may set condition codes 4161 bl __aeabi_idiv @ r0<- op, r0-r3 changed 4162 GET_INST_OPCODE(ip) @ extract opcode from rINST 4163 SET_VREG(r0, r9) @ vAA<- r0 4164 GOTO_OPCODE(ip) @ jump to next instruction 4165 /* 11-14 instructions */ 4166 4167 4168/* ------------------------------ */ 4169 .balign 64 4170.L_OP_REM_INT: /* 0x94 */ 4171/* File: armv5te/OP_REM_INT.S */ 4172/* idivmod returns quotient in r0 and remainder in r1 */ 4173/* File: armv5te/binop.S */ 4174 /* 4175 * Generic 32-bit binary operation. Provide an "instr" line that 4176 * specifies an instruction that performs "result = r0 op r1". 4177 * This could be an ARM instruction or a function call. (If the result 4178 * comes back in a register other than r0, you can override "result".) 4179 * 4180 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4181 * vCC (r1). Useful for integer division and modulus. Note that we 4182 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4183 * handles it correctly. 4184 * 4185 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4186 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4187 * mul-float, div-float, rem-float 4188 */ 4189 /* binop vAA, vBB, vCC */ 4190 FETCH(r0, 1) @ r0<- CCBB 4191 mov r9, rINST, lsr #8 @ r9<- AA 4192 mov r3, r0, lsr #8 @ r3<- CC 4193 and r2, r0, #255 @ r2<- BB 4194 GET_VREG(r1, r3) @ r1<- vCC 4195 GET_VREG(r0, r2) @ r0<- vBB 4196 .if 1 4197 cmp r1, #0 @ is second operand zero? 4198 beq common_errDivideByZero 4199 .endif 4200 4201 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4202 @ optional op; may set condition codes 4203 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 4204 GET_INST_OPCODE(ip) @ extract opcode from rINST 4205 SET_VREG(r1, r9) @ vAA<- r1 4206 GOTO_OPCODE(ip) @ jump to next instruction 4207 /* 11-14 instructions */ 4208 4209 4210/* ------------------------------ */ 4211 .balign 64 4212.L_OP_AND_INT: /* 0x95 */ 4213/* File: armv5te/OP_AND_INT.S */ 4214/* File: armv5te/binop.S */ 4215 /* 4216 * Generic 32-bit binary operation. Provide an "instr" line that 4217 * specifies an instruction that performs "result = r0 op r1". 4218 * This could be an ARM instruction or a function call. (If the result 4219 * comes back in a register other than r0, you can override "result".) 4220 * 4221 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4222 * vCC (r1). Useful for integer division and modulus. Note that we 4223 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4224 * handles it correctly. 4225 * 4226 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4227 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4228 * mul-float, div-float, rem-float 4229 */ 4230 /* binop vAA, vBB, vCC */ 4231 FETCH(r0, 1) @ r0<- CCBB 4232 mov r9, rINST, lsr #8 @ r9<- AA 4233 mov r3, r0, lsr #8 @ r3<- CC 4234 and r2, r0, #255 @ r2<- BB 4235 GET_VREG(r1, r3) @ r1<- vCC 4236 GET_VREG(r0, r2) @ r0<- vBB 4237 .if 0 4238 cmp r1, #0 @ is second operand zero? 4239 beq common_errDivideByZero 4240 .endif 4241 4242 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4243 @ optional op; may set condition codes 4244 and r0, r0, r1 @ r0<- op, r0-r3 changed 4245 GET_INST_OPCODE(ip) @ extract opcode from rINST 4246 SET_VREG(r0, r9) @ vAA<- r0 4247 GOTO_OPCODE(ip) @ jump to next instruction 4248 /* 11-14 instructions */ 4249 4250 4251/* ------------------------------ */ 4252 .balign 64 4253.L_OP_OR_INT: /* 0x96 */ 4254/* File: armv5te/OP_OR_INT.S */ 4255/* File: armv5te/binop.S */ 4256 /* 4257 * Generic 32-bit binary operation. Provide an "instr" line that 4258 * specifies an instruction that performs "result = r0 op r1". 4259 * This could be an ARM instruction or a function call. (If the result 4260 * comes back in a register other than r0, you can override "result".) 4261 * 4262 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4263 * vCC (r1). Useful for integer division and modulus. Note that we 4264 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4265 * handles it correctly. 4266 * 4267 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4268 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4269 * mul-float, div-float, rem-float 4270 */ 4271 /* binop vAA, vBB, vCC */ 4272 FETCH(r0, 1) @ r0<- CCBB 4273 mov r9, rINST, lsr #8 @ r9<- AA 4274 mov r3, r0, lsr #8 @ r3<- CC 4275 and r2, r0, #255 @ r2<- BB 4276 GET_VREG(r1, r3) @ r1<- vCC 4277 GET_VREG(r0, r2) @ r0<- vBB 4278 .if 0 4279 cmp r1, #0 @ is second operand zero? 4280 beq common_errDivideByZero 4281 .endif 4282 4283 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4284 @ optional op; may set condition codes 4285 orr r0, r0, r1 @ r0<- op, r0-r3 changed 4286 GET_INST_OPCODE(ip) @ extract opcode from rINST 4287 SET_VREG(r0, r9) @ vAA<- r0 4288 GOTO_OPCODE(ip) @ jump to next instruction 4289 /* 11-14 instructions */ 4290 4291 4292/* ------------------------------ */ 4293 .balign 64 4294.L_OP_XOR_INT: /* 0x97 */ 4295/* File: armv5te/OP_XOR_INT.S */ 4296/* File: armv5te/binop.S */ 4297 /* 4298 * Generic 32-bit binary operation. Provide an "instr" line that 4299 * specifies an instruction that performs "result = r0 op r1". 4300 * This could be an ARM instruction or a function call. (If the result 4301 * comes back in a register other than r0, you can override "result".) 4302 * 4303 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4304 * vCC (r1). Useful for integer division and modulus. Note that we 4305 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4306 * handles it correctly. 4307 * 4308 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4309 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4310 * mul-float, div-float, rem-float 4311 */ 4312 /* binop vAA, vBB, vCC */ 4313 FETCH(r0, 1) @ r0<- CCBB 4314 mov r9, rINST, lsr #8 @ r9<- AA 4315 mov r3, r0, lsr #8 @ r3<- CC 4316 and r2, r0, #255 @ r2<- BB 4317 GET_VREG(r1, r3) @ r1<- vCC 4318 GET_VREG(r0, r2) @ r0<- vBB 4319 .if 0 4320 cmp r1, #0 @ is second operand zero? 4321 beq common_errDivideByZero 4322 .endif 4323 4324 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4325 @ optional op; may set condition codes 4326 eor r0, r0, r1 @ r0<- op, r0-r3 changed 4327 GET_INST_OPCODE(ip) @ extract opcode from rINST 4328 SET_VREG(r0, r9) @ vAA<- r0 4329 GOTO_OPCODE(ip) @ jump to next instruction 4330 /* 11-14 instructions */ 4331 4332 4333/* ------------------------------ */ 4334 .balign 64 4335.L_OP_SHL_INT: /* 0x98 */ 4336/* File: armv5te/OP_SHL_INT.S */ 4337/* File: armv5te/binop.S */ 4338 /* 4339 * Generic 32-bit binary operation. Provide an "instr" line that 4340 * specifies an instruction that performs "result = r0 op r1". 4341 * This could be an ARM instruction or a function call. (If the result 4342 * comes back in a register other than r0, you can override "result".) 4343 * 4344 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4345 * vCC (r1). Useful for integer division and modulus. Note that we 4346 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4347 * handles it correctly. 4348 * 4349 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4350 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4351 * mul-float, div-float, rem-float 4352 */ 4353 /* binop vAA, vBB, vCC */ 4354 FETCH(r0, 1) @ r0<- CCBB 4355 mov r9, rINST, lsr #8 @ r9<- AA 4356 mov r3, r0, lsr #8 @ r3<- CC 4357 and r2, r0, #255 @ r2<- BB 4358 GET_VREG(r1, r3) @ r1<- vCC 4359 GET_VREG(r0, r2) @ r0<- vBB 4360 .if 0 4361 cmp r1, #0 @ is second operand zero? 4362 beq common_errDivideByZero 4363 .endif 4364 4365 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4366 and r1, r1, #31 @ optional op; may set condition codes 4367 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 4368 GET_INST_OPCODE(ip) @ extract opcode from rINST 4369 SET_VREG(r0, r9) @ vAA<- r0 4370 GOTO_OPCODE(ip) @ jump to next instruction 4371 /* 11-14 instructions */ 4372 4373 4374/* ------------------------------ */ 4375 .balign 64 4376.L_OP_SHR_INT: /* 0x99 */ 4377/* File: armv5te/OP_SHR_INT.S */ 4378/* File: armv5te/binop.S */ 4379 /* 4380 * Generic 32-bit binary operation. Provide an "instr" line that 4381 * specifies an instruction that performs "result = r0 op r1". 4382 * This could be an ARM instruction or a function call. (If the result 4383 * comes back in a register other than r0, you can override "result".) 4384 * 4385 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4386 * vCC (r1). Useful for integer division and modulus. Note that we 4387 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4388 * handles it correctly. 4389 * 4390 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4391 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4392 * mul-float, div-float, rem-float 4393 */ 4394 /* binop vAA, vBB, vCC */ 4395 FETCH(r0, 1) @ r0<- CCBB 4396 mov r9, rINST, lsr #8 @ r9<- AA 4397 mov r3, r0, lsr #8 @ r3<- CC 4398 and r2, r0, #255 @ r2<- BB 4399 GET_VREG(r1, r3) @ r1<- vCC 4400 GET_VREG(r0, r2) @ r0<- vBB 4401 .if 0 4402 cmp r1, #0 @ is second operand zero? 4403 beq common_errDivideByZero 4404 .endif 4405 4406 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4407 and r1, r1, #31 @ optional op; may set condition codes 4408 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 4409 GET_INST_OPCODE(ip) @ extract opcode from rINST 4410 SET_VREG(r0, r9) @ vAA<- r0 4411 GOTO_OPCODE(ip) @ jump to next instruction 4412 /* 11-14 instructions */ 4413 4414 4415/* ------------------------------ */ 4416 .balign 64 4417.L_OP_USHR_INT: /* 0x9a */ 4418/* File: armv5te/OP_USHR_INT.S */ 4419/* File: armv5te/binop.S */ 4420 /* 4421 * Generic 32-bit binary operation. Provide an "instr" line that 4422 * specifies an instruction that performs "result = r0 op r1". 4423 * This could be an ARM instruction or a function call. (If the result 4424 * comes back in a register other than r0, you can override "result".) 4425 * 4426 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4427 * vCC (r1). Useful for integer division and modulus. Note that we 4428 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4429 * handles it correctly. 4430 * 4431 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4432 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4433 * mul-float, div-float, rem-float 4434 */ 4435 /* binop vAA, vBB, vCC */ 4436 FETCH(r0, 1) @ r0<- CCBB 4437 mov r9, rINST, lsr #8 @ r9<- AA 4438 mov r3, r0, lsr #8 @ r3<- CC 4439 and r2, r0, #255 @ r2<- BB 4440 GET_VREG(r1, r3) @ r1<- vCC 4441 GET_VREG(r0, r2) @ r0<- vBB 4442 .if 0 4443 cmp r1, #0 @ is second operand zero? 4444 beq common_errDivideByZero 4445 .endif 4446 4447 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4448 and r1, r1, #31 @ optional op; may set condition codes 4449 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 4450 GET_INST_OPCODE(ip) @ extract opcode from rINST 4451 SET_VREG(r0, r9) @ vAA<- r0 4452 GOTO_OPCODE(ip) @ jump to next instruction 4453 /* 11-14 instructions */ 4454 4455 4456/* ------------------------------ */ 4457 .balign 64 4458.L_OP_ADD_LONG: /* 0x9b */ 4459/* File: armv5te/OP_ADD_LONG.S */ 4460/* File: armv5te/binopWide.S */ 4461 /* 4462 * Generic 64-bit binary operation. Provide an "instr" line that 4463 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4464 * This could be an ARM instruction or a function call. (If the result 4465 * comes back in a register other than r0, you can override "result".) 4466 * 4467 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4468 * vCC (r1). Useful for integer division and modulus. 4469 * 4470 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4471 * xor-long, add-double, sub-double, mul-double, div-double, 4472 * rem-double 4473 * 4474 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4475 */ 4476 /* binop vAA, vBB, vCC */ 4477 FETCH(r0, 1) @ r0<- CCBB 4478 mov r9, rINST, lsr #8 @ r9<- AA 4479 and r2, r0, #255 @ r2<- BB 4480 mov r3, r0, lsr #8 @ r3<- CC 4481 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4482 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4483 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4484 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4485 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4486 .if 0 4487 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4488 beq common_errDivideByZero 4489 .endif 4490 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4491 4492 adds r0, r0, r2 @ optional op; may set condition codes 4493 adc r1, r1, r3 @ result<- op, r0-r3 changed 4494 GET_INST_OPCODE(ip) @ extract opcode from rINST 4495 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4496 GOTO_OPCODE(ip) @ jump to next instruction 4497 /* 14-17 instructions */ 4498 4499 4500/* ------------------------------ */ 4501 .balign 64 4502.L_OP_SUB_LONG: /* 0x9c */ 4503/* File: armv5te/OP_SUB_LONG.S */ 4504/* File: armv5te/binopWide.S */ 4505 /* 4506 * Generic 64-bit binary operation. Provide an "instr" line that 4507 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4508 * This could be an ARM instruction or a function call. (If the result 4509 * comes back in a register other than r0, you can override "result".) 4510 * 4511 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4512 * vCC (r1). Useful for integer division and modulus. 4513 * 4514 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4515 * xor-long, add-double, sub-double, mul-double, div-double, 4516 * rem-double 4517 * 4518 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4519 */ 4520 /* binop vAA, vBB, vCC */ 4521 FETCH(r0, 1) @ r0<- CCBB 4522 mov r9, rINST, lsr #8 @ r9<- AA 4523 and r2, r0, #255 @ r2<- BB 4524 mov r3, r0, lsr #8 @ r3<- CC 4525 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4526 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4527 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4528 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4529 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4530 .if 0 4531 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4532 beq common_errDivideByZero 4533 .endif 4534 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4535 4536 subs r0, r0, r2 @ optional op; may set condition codes 4537 sbc r1, r1, r3 @ result<- op, r0-r3 changed 4538 GET_INST_OPCODE(ip) @ extract opcode from rINST 4539 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4540 GOTO_OPCODE(ip) @ jump to next instruction 4541 /* 14-17 instructions */ 4542 4543 4544/* ------------------------------ */ 4545 .balign 64 4546.L_OP_MUL_LONG: /* 0x9d */ 4547/* File: armv5te/OP_MUL_LONG.S */ 4548 /* 4549 * Signed 64-bit integer multiply. 4550 * 4551 * Consider WXxYZ (r1r0 x r3r2) with a long multiply: 4552 * WX 4553 * x YZ 4554 * -------- 4555 * ZW ZX 4556 * YW YX 4557 * 4558 * The low word of the result holds ZX, the high word holds 4559 * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because 4560 * it doesn't fit in the low 64 bits. 4561 * 4562 * Unlike most ARM math operations, multiply instructions have 4563 * restrictions on using the same register more than once (Rd and Rm 4564 * cannot be the same). 4565 */ 4566 /* mul-long vAA, vBB, vCC */ 4567 FETCH(r0, 1) @ r0<- CCBB 4568 and r2, r0, #255 @ r2<- BB 4569 mov r3, r0, lsr #8 @ r3<- CC 4570 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4571 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4572 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4573 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4574 mul ip, r2, r1 @ ip<- ZxW 4575 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 4576 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 4577 mov r0, rINST, lsr #8 @ r0<- AA 4578 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 4579 add r0, rFP, r0, lsl #2 @ r0<- &fp[AA] 4580 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4581 b .LOP_MUL_LONG_finish 4582 4583/* ------------------------------ */ 4584 .balign 64 4585.L_OP_DIV_LONG: /* 0x9e */ 4586/* File: armv5te/OP_DIV_LONG.S */ 4587/* File: armv5te/binopWide.S */ 4588 /* 4589 * Generic 64-bit binary operation. Provide an "instr" line that 4590 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4591 * This could be an ARM instruction or a function call. (If the result 4592 * comes back in a register other than r0, you can override "result".) 4593 * 4594 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4595 * vCC (r1). Useful for integer division and modulus. 4596 * 4597 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4598 * xor-long, add-double, sub-double, mul-double, div-double, 4599 * rem-double 4600 * 4601 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4602 */ 4603 /* binop vAA, vBB, vCC */ 4604 FETCH(r0, 1) @ r0<- CCBB 4605 mov r9, rINST, lsr #8 @ r9<- AA 4606 and r2, r0, #255 @ r2<- BB 4607 mov r3, r0, lsr #8 @ r3<- CC 4608 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4609 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4610 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4611 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4612 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4613 .if 1 4614 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4615 beq common_errDivideByZero 4616 .endif 4617 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4618 4619 @ optional op; may set condition codes 4620 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4621 GET_INST_OPCODE(ip) @ extract opcode from rINST 4622 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4623 GOTO_OPCODE(ip) @ jump to next instruction 4624 /* 14-17 instructions */ 4625 4626 4627/* ------------------------------ */ 4628 .balign 64 4629.L_OP_REM_LONG: /* 0x9f */ 4630/* File: armv5te/OP_REM_LONG.S */ 4631/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 4632/* File: armv5te/binopWide.S */ 4633 /* 4634 * Generic 64-bit binary operation. Provide an "instr" line that 4635 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4636 * This could be an ARM instruction or a function call. (If the result 4637 * comes back in a register other than r0, you can override "result".) 4638 * 4639 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4640 * vCC (r1). Useful for integer division and modulus. 4641 * 4642 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4643 * xor-long, add-double, sub-double, mul-double, div-double, 4644 * rem-double 4645 * 4646 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4647 */ 4648 /* binop vAA, vBB, vCC */ 4649 FETCH(r0, 1) @ r0<- CCBB 4650 mov r9, rINST, lsr #8 @ r9<- AA 4651 and r2, r0, #255 @ r2<- BB 4652 mov r3, r0, lsr #8 @ r3<- CC 4653 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4654 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4655 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4656 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4657 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4658 .if 1 4659 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4660 beq common_errDivideByZero 4661 .endif 4662 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4663 4664 @ optional op; may set condition codes 4665 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4666 GET_INST_OPCODE(ip) @ extract opcode from rINST 4667 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 4668 GOTO_OPCODE(ip) @ jump to next instruction 4669 /* 14-17 instructions */ 4670 4671 4672/* ------------------------------ */ 4673 .balign 64 4674.L_OP_AND_LONG: /* 0xa0 */ 4675/* File: armv5te/OP_AND_LONG.S */ 4676/* File: armv5te/binopWide.S */ 4677 /* 4678 * Generic 64-bit binary operation. Provide an "instr" line that 4679 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4680 * This could be an ARM instruction or a function call. (If the result 4681 * comes back in a register other than r0, you can override "result".) 4682 * 4683 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4684 * vCC (r1). Useful for integer division and modulus. 4685 * 4686 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4687 * xor-long, add-double, sub-double, mul-double, div-double, 4688 * rem-double 4689 * 4690 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4691 */ 4692 /* binop vAA, vBB, vCC */ 4693 FETCH(r0, 1) @ r0<- CCBB 4694 mov r9, rINST, lsr #8 @ r9<- AA 4695 and r2, r0, #255 @ r2<- BB 4696 mov r3, r0, lsr #8 @ r3<- CC 4697 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4698 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4699 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4700 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4701 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4702 .if 0 4703 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4704 beq common_errDivideByZero 4705 .endif 4706 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4707 4708 and r0, r0, r2 @ optional op; may set condition codes 4709 and r1, r1, r3 @ result<- op, r0-r3 changed 4710 GET_INST_OPCODE(ip) @ extract opcode from rINST 4711 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4712 GOTO_OPCODE(ip) @ jump to next instruction 4713 /* 14-17 instructions */ 4714 4715 4716/* ------------------------------ */ 4717 .balign 64 4718.L_OP_OR_LONG: /* 0xa1 */ 4719/* File: armv5te/OP_OR_LONG.S */ 4720/* File: armv5te/binopWide.S */ 4721 /* 4722 * Generic 64-bit binary operation. Provide an "instr" line that 4723 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4724 * This could be an ARM instruction or a function call. (If the result 4725 * comes back in a register other than r0, you can override "result".) 4726 * 4727 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4728 * vCC (r1). Useful for integer division and modulus. 4729 * 4730 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4731 * xor-long, add-double, sub-double, mul-double, div-double, 4732 * rem-double 4733 * 4734 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4735 */ 4736 /* binop vAA, vBB, vCC */ 4737 FETCH(r0, 1) @ r0<- CCBB 4738 mov r9, rINST, lsr #8 @ r9<- AA 4739 and r2, r0, #255 @ r2<- BB 4740 mov r3, r0, lsr #8 @ r3<- CC 4741 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4742 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4743 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4744 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4745 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4746 .if 0 4747 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4748 beq common_errDivideByZero 4749 .endif 4750 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4751 4752 orr r0, r0, r2 @ optional op; may set condition codes 4753 orr r1, r1, r3 @ result<- op, r0-r3 changed 4754 GET_INST_OPCODE(ip) @ extract opcode from rINST 4755 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4756 GOTO_OPCODE(ip) @ jump to next instruction 4757 /* 14-17 instructions */ 4758 4759 4760/* ------------------------------ */ 4761 .balign 64 4762.L_OP_XOR_LONG: /* 0xa2 */ 4763/* File: armv5te/OP_XOR_LONG.S */ 4764/* File: armv5te/binopWide.S */ 4765 /* 4766 * Generic 64-bit binary operation. Provide an "instr" line that 4767 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4768 * This could be an ARM instruction or a function call. (If the result 4769 * comes back in a register other than r0, you can override "result".) 4770 * 4771 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4772 * vCC (r1). Useful for integer division and modulus. 4773 * 4774 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4775 * xor-long, add-double, sub-double, mul-double, div-double, 4776 * rem-double 4777 * 4778 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4779 */ 4780 /* binop vAA, vBB, vCC */ 4781 FETCH(r0, 1) @ r0<- CCBB 4782 mov r9, rINST, lsr #8 @ r9<- AA 4783 and r2, r0, #255 @ r2<- BB 4784 mov r3, r0, lsr #8 @ r3<- CC 4785 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4786 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4787 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4788 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4789 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4790 .if 0 4791 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4792 beq common_errDivideByZero 4793 .endif 4794 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4795 4796 eor r0, r0, r2 @ optional op; may set condition codes 4797 eor r1, r1, r3 @ result<- op, r0-r3 changed 4798 GET_INST_OPCODE(ip) @ extract opcode from rINST 4799 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4800 GOTO_OPCODE(ip) @ jump to next instruction 4801 /* 14-17 instructions */ 4802 4803 4804/* ------------------------------ */ 4805 .balign 64 4806.L_OP_SHL_LONG: /* 0xa3 */ 4807/* File: armv5te/OP_SHL_LONG.S */ 4808 /* 4809 * Long integer shift. This is different from the generic 32/64-bit 4810 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4811 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4812 * 6 bits of the shift distance. 4813 */ 4814 /* shl-long vAA, vBB, vCC */ 4815 FETCH(r0, 1) @ r0<- CCBB 4816 mov r9, rINST, lsr #8 @ r9<- AA 4817 and r3, r0, #255 @ r3<- BB 4818 mov r0, r0, lsr #8 @ r0<- CC 4819 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4820 GET_VREG(r2, r0) @ r2<- vCC 4821 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4822 and r2, r2, #63 @ r2<- r2 & 0x3f 4823 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4824 4825 mov r1, r1, asl r2 @ r1<- r1 << r2 4826 rsb r3, r2, #32 @ r3<- 32 - r2 4827 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 4828 subs ip, r2, #32 @ ip<- r2 - 32 4829 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 4830 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4831 b .LOP_SHL_LONG_finish 4832 4833/* ------------------------------ */ 4834 .balign 64 4835.L_OP_SHR_LONG: /* 0xa4 */ 4836/* File: armv5te/OP_SHR_LONG.S */ 4837 /* 4838 * Long integer shift. This is different from the generic 32/64-bit 4839 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4840 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4841 * 6 bits of the shift distance. 4842 */ 4843 /* shr-long vAA, vBB, vCC */ 4844 FETCH(r0, 1) @ r0<- CCBB 4845 mov r9, rINST, lsr #8 @ r9<- AA 4846 and r3, r0, #255 @ r3<- BB 4847 mov r0, r0, lsr #8 @ r0<- CC 4848 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4849 GET_VREG(r2, r0) @ r2<- vCC 4850 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4851 and r2, r2, #63 @ r0<- r0 & 0x3f 4852 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4853 4854 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4855 rsb r3, r2, #32 @ r3<- 32 - r2 4856 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4857 subs ip, r2, #32 @ ip<- r2 - 32 4858 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 4859 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4860 b .LOP_SHR_LONG_finish 4861 4862/* ------------------------------ */ 4863 .balign 64 4864.L_OP_USHR_LONG: /* 0xa5 */ 4865/* File: armv5te/OP_USHR_LONG.S */ 4866 /* 4867 * Long integer shift. This is different from the generic 32/64-bit 4868 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4869 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4870 * 6 bits of the shift distance. 4871 */ 4872 /* ushr-long vAA, vBB, vCC */ 4873 FETCH(r0, 1) @ r0<- CCBB 4874 mov r9, rINST, lsr #8 @ r9<- AA 4875 and r3, r0, #255 @ r3<- BB 4876 mov r0, r0, lsr #8 @ r0<- CC 4877 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4878 GET_VREG(r2, r0) @ r2<- vCC 4879 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4880 and r2, r2, #63 @ r0<- r0 & 0x3f 4881 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4882 4883 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4884 rsb r3, r2, #32 @ r3<- 32 - r2 4885 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4886 subs ip, r2, #32 @ ip<- r2 - 32 4887 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 4888 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4889 b .LOP_USHR_LONG_finish 4890 4891/* ------------------------------ */ 4892 .balign 64 4893.L_OP_ADD_FLOAT: /* 0xa6 */ 4894/* File: arm-vfp/OP_ADD_FLOAT.S */ 4895/* File: arm-vfp/fbinop.S */ 4896 /* 4897 * Generic 32-bit floating-point operation. Provide an "instr" line that 4898 * specifies an instruction that performs "s2 = s0 op s1". Because we 4899 * use the "softfp" ABI, this must be an instruction, not a function call. 4900 * 4901 * For: add-float, sub-float, mul-float, div-float 4902 */ 4903 /* floatop vAA, vBB, vCC */ 4904 FETCH(r0, 1) @ r0<- CCBB 4905 mov r9, rINST, lsr #8 @ r9<- AA 4906 mov r3, r0, lsr #8 @ r3<- CC 4907 and r2, r0, #255 @ r2<- BB 4908 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4909 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4910 flds s1, [r3] @ s1<- vCC 4911 flds s0, [r2] @ s0<- vBB 4912 4913 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4914 fadds s2, s0, s1 @ s2<- op 4915 GET_INST_OPCODE(ip) @ extract opcode from rINST 4916 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4917 fsts s2, [r9] @ vAA<- s2 4918 GOTO_OPCODE(ip) @ jump to next instruction 4919 4920 4921/* ------------------------------ */ 4922 .balign 64 4923.L_OP_SUB_FLOAT: /* 0xa7 */ 4924/* File: arm-vfp/OP_SUB_FLOAT.S */ 4925/* File: arm-vfp/fbinop.S */ 4926 /* 4927 * Generic 32-bit floating-point operation. Provide an "instr" line that 4928 * specifies an instruction that performs "s2 = s0 op s1". Because we 4929 * use the "softfp" ABI, this must be an instruction, not a function call. 4930 * 4931 * For: add-float, sub-float, mul-float, div-float 4932 */ 4933 /* floatop vAA, vBB, vCC */ 4934 FETCH(r0, 1) @ r0<- CCBB 4935 mov r9, rINST, lsr #8 @ r9<- AA 4936 mov r3, r0, lsr #8 @ r3<- CC 4937 and r2, r0, #255 @ r2<- BB 4938 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4939 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4940 flds s1, [r3] @ s1<- vCC 4941 flds s0, [r2] @ s0<- vBB 4942 4943 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4944 fsubs s2, s0, s1 @ s2<- op 4945 GET_INST_OPCODE(ip) @ extract opcode from rINST 4946 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4947 fsts s2, [r9] @ vAA<- s2 4948 GOTO_OPCODE(ip) @ jump to next instruction 4949 4950 4951/* ------------------------------ */ 4952 .balign 64 4953.L_OP_MUL_FLOAT: /* 0xa8 */ 4954/* File: arm-vfp/OP_MUL_FLOAT.S */ 4955/* File: arm-vfp/fbinop.S */ 4956 /* 4957 * Generic 32-bit floating-point operation. Provide an "instr" line that 4958 * specifies an instruction that performs "s2 = s0 op s1". Because we 4959 * use the "softfp" ABI, this must be an instruction, not a function call. 4960 * 4961 * For: add-float, sub-float, mul-float, div-float 4962 */ 4963 /* floatop vAA, vBB, vCC */ 4964 FETCH(r0, 1) @ r0<- CCBB 4965 mov r9, rINST, lsr #8 @ r9<- AA 4966 mov r3, r0, lsr #8 @ r3<- CC 4967 and r2, r0, #255 @ r2<- BB 4968 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4969 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4970 flds s1, [r3] @ s1<- vCC 4971 flds s0, [r2] @ s0<- vBB 4972 4973 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4974 fmuls s2, s0, s1 @ s2<- op 4975 GET_INST_OPCODE(ip) @ extract opcode from rINST 4976 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4977 fsts s2, [r9] @ vAA<- s2 4978 GOTO_OPCODE(ip) @ jump to next instruction 4979 4980 4981/* ------------------------------ */ 4982 .balign 64 4983.L_OP_DIV_FLOAT: /* 0xa9 */ 4984/* File: arm-vfp/OP_DIV_FLOAT.S */ 4985/* File: arm-vfp/fbinop.S */ 4986 /* 4987 * Generic 32-bit floating-point operation. Provide an "instr" line that 4988 * specifies an instruction that performs "s2 = s0 op s1". Because we 4989 * use the "softfp" ABI, this must be an instruction, not a function call. 4990 * 4991 * For: add-float, sub-float, mul-float, div-float 4992 */ 4993 /* floatop vAA, vBB, vCC */ 4994 FETCH(r0, 1) @ r0<- CCBB 4995 mov r9, rINST, lsr #8 @ r9<- AA 4996 mov r3, r0, lsr #8 @ r3<- CC 4997 and r2, r0, #255 @ r2<- BB 4998 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4999 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5000 flds s1, [r3] @ s1<- vCC 5001 flds s0, [r2] @ s0<- vBB 5002 5003 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5004 fdivs s2, s0, s1 @ s2<- op 5005 GET_INST_OPCODE(ip) @ extract opcode from rINST 5006 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5007 fsts s2, [r9] @ vAA<- s2 5008 GOTO_OPCODE(ip) @ jump to next instruction 5009 5010 5011/* ------------------------------ */ 5012 .balign 64 5013.L_OP_REM_FLOAT: /* 0xaa */ 5014/* File: armv5te/OP_REM_FLOAT.S */ 5015/* EABI doesn't define a float remainder function, but libm does */ 5016/* File: armv5te/binop.S */ 5017 /* 5018 * Generic 32-bit binary operation. Provide an "instr" line that 5019 * specifies an instruction that performs "result = r0 op r1". 5020 * This could be an ARM instruction or a function call. (If the result 5021 * comes back in a register other than r0, you can override "result".) 5022 * 5023 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5024 * vCC (r1). Useful for integer division and modulus. Note that we 5025 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 5026 * handles it correctly. 5027 * 5028 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 5029 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 5030 * mul-float, div-float, rem-float 5031 */ 5032 /* binop vAA, vBB, vCC */ 5033 FETCH(r0, 1) @ r0<- CCBB 5034 mov r9, rINST, lsr #8 @ r9<- AA 5035 mov r3, r0, lsr #8 @ r3<- CC 5036 and r2, r0, #255 @ r2<- BB 5037 GET_VREG(r1, r3) @ r1<- vCC 5038 GET_VREG(r0, r2) @ r0<- vBB 5039 .if 0 5040 cmp r1, #0 @ is second operand zero? 5041 beq common_errDivideByZero 5042 .endif 5043 5044 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5045 @ optional op; may set condition codes 5046 bl fmodf @ r0<- op, r0-r3 changed 5047 GET_INST_OPCODE(ip) @ extract opcode from rINST 5048 SET_VREG(r0, r9) @ vAA<- r0 5049 GOTO_OPCODE(ip) @ jump to next instruction 5050 /* 11-14 instructions */ 5051 5052 5053/* ------------------------------ */ 5054 .balign 64 5055.L_OP_ADD_DOUBLE: /* 0xab */ 5056/* File: arm-vfp/OP_ADD_DOUBLE.S */ 5057/* File: arm-vfp/fbinopWide.S */ 5058 /* 5059 * Generic 64-bit double-precision floating point binary operation. 5060 * Provide an "instr" line that specifies an instruction that performs 5061 * "d2 = d0 op d1". 5062 * 5063 * for: add-double, sub-double, mul-double, div-double 5064 */ 5065 /* doubleop vAA, vBB, vCC */ 5066 FETCH(r0, 1) @ r0<- CCBB 5067 mov r9, rINST, lsr #8 @ r9<- AA 5068 mov r3, r0, lsr #8 @ r3<- CC 5069 and r2, r0, #255 @ r2<- BB 5070 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5071 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5072 fldd d1, [r3] @ d1<- vCC 5073 fldd d0, [r2] @ d0<- vBB 5074 5075 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5076 faddd d2, d0, d1 @ s2<- op 5077 GET_INST_OPCODE(ip) @ extract opcode from rINST 5078 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5079 fstd d2, [r9] @ vAA<- d2 5080 GOTO_OPCODE(ip) @ jump to next instruction 5081 5082 5083/* ------------------------------ */ 5084 .balign 64 5085.L_OP_SUB_DOUBLE: /* 0xac */ 5086/* File: arm-vfp/OP_SUB_DOUBLE.S */ 5087/* File: arm-vfp/fbinopWide.S */ 5088 /* 5089 * Generic 64-bit double-precision floating point binary operation. 5090 * Provide an "instr" line that specifies an instruction that performs 5091 * "d2 = d0 op d1". 5092 * 5093 * for: add-double, sub-double, mul-double, div-double 5094 */ 5095 /* doubleop vAA, vBB, vCC */ 5096 FETCH(r0, 1) @ r0<- CCBB 5097 mov r9, rINST, lsr #8 @ r9<- AA 5098 mov r3, r0, lsr #8 @ r3<- CC 5099 and r2, r0, #255 @ r2<- BB 5100 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5101 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5102 fldd d1, [r3] @ d1<- vCC 5103 fldd d0, [r2] @ d0<- vBB 5104 5105 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5106 fsubd d2, d0, d1 @ s2<- op 5107 GET_INST_OPCODE(ip) @ extract opcode from rINST 5108 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5109 fstd d2, [r9] @ vAA<- d2 5110 GOTO_OPCODE(ip) @ jump to next instruction 5111 5112 5113/* ------------------------------ */ 5114 .balign 64 5115.L_OP_MUL_DOUBLE: /* 0xad */ 5116/* File: arm-vfp/OP_MUL_DOUBLE.S */ 5117/* File: arm-vfp/fbinopWide.S */ 5118 /* 5119 * Generic 64-bit double-precision floating point binary operation. 5120 * Provide an "instr" line that specifies an instruction that performs 5121 * "d2 = d0 op d1". 5122 * 5123 * for: add-double, sub-double, mul-double, div-double 5124 */ 5125 /* doubleop vAA, vBB, vCC */ 5126 FETCH(r0, 1) @ r0<- CCBB 5127 mov r9, rINST, lsr #8 @ r9<- AA 5128 mov r3, r0, lsr #8 @ r3<- CC 5129 and r2, r0, #255 @ r2<- BB 5130 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5131 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5132 fldd d1, [r3] @ d1<- vCC 5133 fldd d0, [r2] @ d0<- vBB 5134 5135 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5136 fmuld d2, d0, d1 @ s2<- op 5137 GET_INST_OPCODE(ip) @ extract opcode from rINST 5138 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5139 fstd d2, [r9] @ vAA<- d2 5140 GOTO_OPCODE(ip) @ jump to next instruction 5141 5142 5143/* ------------------------------ */ 5144 .balign 64 5145.L_OP_DIV_DOUBLE: /* 0xae */ 5146/* File: arm-vfp/OP_DIV_DOUBLE.S */ 5147/* File: arm-vfp/fbinopWide.S */ 5148 /* 5149 * Generic 64-bit double-precision floating point binary operation. 5150 * Provide an "instr" line that specifies an instruction that performs 5151 * "d2 = d0 op d1". 5152 * 5153 * for: add-double, sub-double, mul-double, div-double 5154 */ 5155 /* doubleop vAA, vBB, vCC */ 5156 FETCH(r0, 1) @ r0<- CCBB 5157 mov r9, rINST, lsr #8 @ r9<- AA 5158 mov r3, r0, lsr #8 @ r3<- CC 5159 and r2, r0, #255 @ r2<- BB 5160 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5161 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5162 fldd d1, [r3] @ d1<- vCC 5163 fldd d0, [r2] @ d0<- vBB 5164 5165 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5166 fdivd d2, d0, d1 @ s2<- op 5167 GET_INST_OPCODE(ip) @ extract opcode from rINST 5168 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5169 fstd d2, [r9] @ vAA<- d2 5170 GOTO_OPCODE(ip) @ jump to next instruction 5171 5172 5173/* ------------------------------ */ 5174 .balign 64 5175.L_OP_REM_DOUBLE: /* 0xaf */ 5176/* File: armv5te/OP_REM_DOUBLE.S */ 5177/* EABI doesn't define a double remainder function, but libm does */ 5178/* File: armv5te/binopWide.S */ 5179 /* 5180 * Generic 64-bit binary operation. Provide an "instr" line that 5181 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5182 * This could be an ARM instruction or a function call. (If the result 5183 * comes back in a register other than r0, you can override "result".) 5184 * 5185 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5186 * vCC (r1). Useful for integer division and modulus. 5187 * 5188 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5189 * xor-long, add-double, sub-double, mul-double, div-double, 5190 * rem-double 5191 * 5192 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5193 */ 5194 /* binop vAA, vBB, vCC */ 5195 FETCH(r0, 1) @ r0<- CCBB 5196 mov r9, rINST, lsr #8 @ r9<- AA 5197 and r2, r0, #255 @ r2<- BB 5198 mov r3, r0, lsr #8 @ r3<- CC 5199 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5200 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5201 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5202 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5203 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5204 .if 0 5205 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5206 beq common_errDivideByZero 5207 .endif 5208 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5209 5210 @ optional op; may set condition codes 5211 bl fmod @ result<- op, r0-r3 changed 5212 GET_INST_OPCODE(ip) @ extract opcode from rINST 5213 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5214 GOTO_OPCODE(ip) @ jump to next instruction 5215 /* 14-17 instructions */ 5216 5217 5218/* ------------------------------ */ 5219 .balign 64 5220.L_OP_ADD_INT_2ADDR: /* 0xb0 */ 5221/* File: armv6t2/OP_ADD_INT_2ADDR.S */ 5222/* File: armv6t2/binop2addr.S */ 5223 /* 5224 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5225 * that specifies an instruction that performs "result = r0 op r1". 5226 * This could be an ARM instruction or a function call. (If the result 5227 * comes back in a register other than r0, you can override "result".) 5228 * 5229 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5230 * vCC (r1). Useful for integer division and modulus. 5231 * 5232 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5233 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5234 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5235 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5236 */ 5237 /* binop/2addr vA, vB */ 5238 mov r3, rINST, lsr #12 @ r3<- B 5239 ubfx r9, rINST, #8, #4 @ r9<- A 5240 GET_VREG(r1, r3) @ r1<- vB 5241 GET_VREG(r0, r9) @ r0<- vA 5242 .if 0 5243 cmp r1, #0 @ is second operand zero? 5244 beq common_errDivideByZero 5245 .endif 5246 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5247 5248 @ optional op; may set condition codes 5249 add r0, r0, r1 @ r0<- op, r0-r3 changed 5250 GET_INST_OPCODE(ip) @ extract opcode from rINST 5251 SET_VREG(r0, r9) @ vAA<- r0 5252 GOTO_OPCODE(ip) @ jump to next instruction 5253 /* 10-13 instructions */ 5254 5255 5256/* ------------------------------ */ 5257 .balign 64 5258.L_OP_SUB_INT_2ADDR: /* 0xb1 */ 5259/* File: armv6t2/OP_SUB_INT_2ADDR.S */ 5260/* File: armv6t2/binop2addr.S */ 5261 /* 5262 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5263 * that specifies an instruction that performs "result = r0 op r1". 5264 * This could be an ARM instruction or a function call. (If the result 5265 * comes back in a register other than r0, you can override "result".) 5266 * 5267 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5268 * vCC (r1). Useful for integer division and modulus. 5269 * 5270 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5271 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5272 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5273 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5274 */ 5275 /* binop/2addr vA, vB */ 5276 mov r3, rINST, lsr #12 @ r3<- B 5277 ubfx r9, rINST, #8, #4 @ r9<- A 5278 GET_VREG(r1, r3) @ r1<- vB 5279 GET_VREG(r0, r9) @ r0<- vA 5280 .if 0 5281 cmp r1, #0 @ is second operand zero? 5282 beq common_errDivideByZero 5283 .endif 5284 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5285 5286 @ optional op; may set condition codes 5287 sub r0, r0, r1 @ r0<- op, r0-r3 changed 5288 GET_INST_OPCODE(ip) @ extract opcode from rINST 5289 SET_VREG(r0, r9) @ vAA<- r0 5290 GOTO_OPCODE(ip) @ jump to next instruction 5291 /* 10-13 instructions */ 5292 5293 5294/* ------------------------------ */ 5295 .balign 64 5296.L_OP_MUL_INT_2ADDR: /* 0xb2 */ 5297/* File: armv6t2/OP_MUL_INT_2ADDR.S */ 5298/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 5299/* File: armv6t2/binop2addr.S */ 5300 /* 5301 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5302 * that specifies an instruction that performs "result = r0 op r1". 5303 * This could be an ARM instruction or a function call. (If the result 5304 * comes back in a register other than r0, you can override "result".) 5305 * 5306 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5307 * vCC (r1). Useful for integer division and modulus. 5308 * 5309 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5310 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5311 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5312 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5313 */ 5314 /* binop/2addr vA, vB */ 5315 mov r3, rINST, lsr #12 @ r3<- B 5316 ubfx r9, rINST, #8, #4 @ r9<- A 5317 GET_VREG(r1, r3) @ r1<- vB 5318 GET_VREG(r0, r9) @ r0<- vA 5319 .if 0 5320 cmp r1, #0 @ is second operand zero? 5321 beq common_errDivideByZero 5322 .endif 5323 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5324 5325 @ optional op; may set condition codes 5326 mul r0, r1, r0 @ r0<- op, r0-r3 changed 5327 GET_INST_OPCODE(ip) @ extract opcode from rINST 5328 SET_VREG(r0, r9) @ vAA<- r0 5329 GOTO_OPCODE(ip) @ jump to next instruction 5330 /* 10-13 instructions */ 5331 5332 5333/* ------------------------------ */ 5334 .balign 64 5335.L_OP_DIV_INT_2ADDR: /* 0xb3 */ 5336/* File: armv6t2/OP_DIV_INT_2ADDR.S */ 5337/* File: armv6t2/binop2addr.S */ 5338 /* 5339 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5340 * that specifies an instruction that performs "result = r0 op r1". 5341 * This could be an ARM instruction or a function call. (If the result 5342 * comes back in a register other than r0, you can override "result".) 5343 * 5344 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5345 * vCC (r1). Useful for integer division and modulus. 5346 * 5347 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5348 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5349 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5350 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5351 */ 5352 /* binop/2addr vA, vB */ 5353 mov r3, rINST, lsr #12 @ r3<- B 5354 ubfx r9, rINST, #8, #4 @ r9<- A 5355 GET_VREG(r1, r3) @ r1<- vB 5356 GET_VREG(r0, r9) @ r0<- vA 5357 .if 1 5358 cmp r1, #0 @ is second operand zero? 5359 beq common_errDivideByZero 5360 .endif 5361 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5362 5363 @ optional op; may set condition codes 5364 bl __aeabi_idiv @ r0<- op, r0-r3 changed 5365 GET_INST_OPCODE(ip) @ extract opcode from rINST 5366 SET_VREG(r0, r9) @ vAA<- r0 5367 GOTO_OPCODE(ip) @ jump to next instruction 5368 /* 10-13 instructions */ 5369 5370 5371/* ------------------------------ */ 5372 .balign 64 5373.L_OP_REM_INT_2ADDR: /* 0xb4 */ 5374/* File: armv6t2/OP_REM_INT_2ADDR.S */ 5375/* idivmod returns quotient in r0 and remainder in r1 */ 5376/* File: armv6t2/binop2addr.S */ 5377 /* 5378 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5379 * that specifies an instruction that performs "result = r0 op r1". 5380 * This could be an ARM instruction or a function call. (If the result 5381 * comes back in a register other than r0, you can override "result".) 5382 * 5383 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5384 * vCC (r1). Useful for integer division and modulus. 5385 * 5386 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5387 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5388 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5389 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5390 */ 5391 /* binop/2addr vA, vB */ 5392 mov r3, rINST, lsr #12 @ r3<- B 5393 ubfx r9, rINST, #8, #4 @ r9<- A 5394 GET_VREG(r1, r3) @ r1<- vB 5395 GET_VREG(r0, r9) @ r0<- vA 5396 .if 1 5397 cmp r1, #0 @ is second operand zero? 5398 beq common_errDivideByZero 5399 .endif 5400 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5401 5402 @ optional op; may set condition codes 5403 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 5404 GET_INST_OPCODE(ip) @ extract opcode from rINST 5405 SET_VREG(r1, r9) @ vAA<- r1 5406 GOTO_OPCODE(ip) @ jump to next instruction 5407 /* 10-13 instructions */ 5408 5409 5410/* ------------------------------ */ 5411 .balign 64 5412.L_OP_AND_INT_2ADDR: /* 0xb5 */ 5413/* File: armv6t2/OP_AND_INT_2ADDR.S */ 5414/* File: armv6t2/binop2addr.S */ 5415 /* 5416 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5417 * that specifies an instruction that performs "result = r0 op r1". 5418 * This could be an ARM instruction or a function call. (If the result 5419 * comes back in a register other than r0, you can override "result".) 5420 * 5421 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5422 * vCC (r1). Useful for integer division and modulus. 5423 * 5424 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5425 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5426 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5427 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5428 */ 5429 /* binop/2addr vA, vB */ 5430 mov r3, rINST, lsr #12 @ r3<- B 5431 ubfx r9, rINST, #8, #4 @ r9<- A 5432 GET_VREG(r1, r3) @ r1<- vB 5433 GET_VREG(r0, r9) @ r0<- vA 5434 .if 0 5435 cmp r1, #0 @ is second operand zero? 5436 beq common_errDivideByZero 5437 .endif 5438 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5439 5440 @ optional op; may set condition codes 5441 and r0, r0, r1 @ r0<- op, r0-r3 changed 5442 GET_INST_OPCODE(ip) @ extract opcode from rINST 5443 SET_VREG(r0, r9) @ vAA<- r0 5444 GOTO_OPCODE(ip) @ jump to next instruction 5445 /* 10-13 instructions */ 5446 5447 5448/* ------------------------------ */ 5449 .balign 64 5450.L_OP_OR_INT_2ADDR: /* 0xb6 */ 5451/* File: armv6t2/OP_OR_INT_2ADDR.S */ 5452/* File: armv6t2/binop2addr.S */ 5453 /* 5454 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5455 * that specifies an instruction that performs "result = r0 op r1". 5456 * This could be an ARM instruction or a function call. (If the result 5457 * comes back in a register other than r0, you can override "result".) 5458 * 5459 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5460 * vCC (r1). Useful for integer division and modulus. 5461 * 5462 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5463 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5464 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5465 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5466 */ 5467 /* binop/2addr vA, vB */ 5468 mov r3, rINST, lsr #12 @ r3<- B 5469 ubfx r9, rINST, #8, #4 @ r9<- A 5470 GET_VREG(r1, r3) @ r1<- vB 5471 GET_VREG(r0, r9) @ r0<- vA 5472 .if 0 5473 cmp r1, #0 @ is second operand zero? 5474 beq common_errDivideByZero 5475 .endif 5476 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5477 5478 @ optional op; may set condition codes 5479 orr r0, r0, r1 @ r0<- op, r0-r3 changed 5480 GET_INST_OPCODE(ip) @ extract opcode from rINST 5481 SET_VREG(r0, r9) @ vAA<- r0 5482 GOTO_OPCODE(ip) @ jump to next instruction 5483 /* 10-13 instructions */ 5484 5485 5486/* ------------------------------ */ 5487 .balign 64 5488.L_OP_XOR_INT_2ADDR: /* 0xb7 */ 5489/* File: armv6t2/OP_XOR_INT_2ADDR.S */ 5490/* File: armv6t2/binop2addr.S */ 5491 /* 5492 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5493 * that specifies an instruction that performs "result = r0 op r1". 5494 * This could be an ARM instruction or a function call. (If the result 5495 * comes back in a register other than r0, you can override "result".) 5496 * 5497 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5498 * vCC (r1). Useful for integer division and modulus. 5499 * 5500 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5501 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5502 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5503 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5504 */ 5505 /* binop/2addr vA, vB */ 5506 mov r3, rINST, lsr #12 @ r3<- B 5507 ubfx r9, rINST, #8, #4 @ r9<- A 5508 GET_VREG(r1, r3) @ r1<- vB 5509 GET_VREG(r0, r9) @ r0<- vA 5510 .if 0 5511 cmp r1, #0 @ is second operand zero? 5512 beq common_errDivideByZero 5513 .endif 5514 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5515 5516 @ optional op; may set condition codes 5517 eor r0, r0, r1 @ r0<- op, r0-r3 changed 5518 GET_INST_OPCODE(ip) @ extract opcode from rINST 5519 SET_VREG(r0, r9) @ vAA<- r0 5520 GOTO_OPCODE(ip) @ jump to next instruction 5521 /* 10-13 instructions */ 5522 5523 5524/* ------------------------------ */ 5525 .balign 64 5526.L_OP_SHL_INT_2ADDR: /* 0xb8 */ 5527/* File: armv6t2/OP_SHL_INT_2ADDR.S */ 5528/* File: armv6t2/binop2addr.S */ 5529 /* 5530 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5531 * that specifies an instruction that performs "result = r0 op r1". 5532 * This could be an ARM instruction or a function call. (If the result 5533 * comes back in a register other than r0, you can override "result".) 5534 * 5535 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5536 * vCC (r1). Useful for integer division and modulus. 5537 * 5538 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5539 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5540 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5541 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5542 */ 5543 /* binop/2addr vA, vB */ 5544 mov r3, rINST, lsr #12 @ r3<- B 5545 ubfx r9, rINST, #8, #4 @ r9<- A 5546 GET_VREG(r1, r3) @ r1<- vB 5547 GET_VREG(r0, r9) @ r0<- vA 5548 .if 0 5549 cmp r1, #0 @ is second operand zero? 5550 beq common_errDivideByZero 5551 .endif 5552 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5553 5554 and r1, r1, #31 @ optional op; may set condition codes 5555 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 5556 GET_INST_OPCODE(ip) @ extract opcode from rINST 5557 SET_VREG(r0, r9) @ vAA<- r0 5558 GOTO_OPCODE(ip) @ jump to next instruction 5559 /* 10-13 instructions */ 5560 5561 5562/* ------------------------------ */ 5563 .balign 64 5564.L_OP_SHR_INT_2ADDR: /* 0xb9 */ 5565/* File: armv6t2/OP_SHR_INT_2ADDR.S */ 5566/* File: armv6t2/binop2addr.S */ 5567 /* 5568 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5569 * that specifies an instruction that performs "result = r0 op r1". 5570 * This could be an ARM instruction or a function call. (If the result 5571 * comes back in a register other than r0, you can override "result".) 5572 * 5573 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5574 * vCC (r1). Useful for integer division and modulus. 5575 * 5576 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5577 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5578 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5579 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5580 */ 5581 /* binop/2addr vA, vB */ 5582 mov r3, rINST, lsr #12 @ r3<- B 5583 ubfx r9, rINST, #8, #4 @ r9<- A 5584 GET_VREG(r1, r3) @ r1<- vB 5585 GET_VREG(r0, r9) @ r0<- vA 5586 .if 0 5587 cmp r1, #0 @ is second operand zero? 5588 beq common_errDivideByZero 5589 .endif 5590 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5591 5592 and r1, r1, #31 @ optional op; may set condition codes 5593 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 5594 GET_INST_OPCODE(ip) @ extract opcode from rINST 5595 SET_VREG(r0, r9) @ vAA<- r0 5596 GOTO_OPCODE(ip) @ jump to next instruction 5597 /* 10-13 instructions */ 5598 5599 5600/* ------------------------------ */ 5601 .balign 64 5602.L_OP_USHR_INT_2ADDR: /* 0xba */ 5603/* File: armv6t2/OP_USHR_INT_2ADDR.S */ 5604/* File: armv6t2/binop2addr.S */ 5605 /* 5606 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5607 * that specifies an instruction that performs "result = r0 op r1". 5608 * This could be an ARM instruction or a function call. (If the result 5609 * comes back in a register other than r0, you can override "result".) 5610 * 5611 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5612 * vCC (r1). Useful for integer division and modulus. 5613 * 5614 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5615 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5616 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5617 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5618 */ 5619 /* binop/2addr vA, vB */ 5620 mov r3, rINST, lsr #12 @ r3<- B 5621 ubfx r9, rINST, #8, #4 @ r9<- A 5622 GET_VREG(r1, r3) @ r1<- vB 5623 GET_VREG(r0, r9) @ r0<- vA 5624 .if 0 5625 cmp r1, #0 @ is second operand zero? 5626 beq common_errDivideByZero 5627 .endif 5628 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5629 5630 and r1, r1, #31 @ optional op; may set condition codes 5631 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 5632 GET_INST_OPCODE(ip) @ extract opcode from rINST 5633 SET_VREG(r0, r9) @ vAA<- r0 5634 GOTO_OPCODE(ip) @ jump to next instruction 5635 /* 10-13 instructions */ 5636 5637 5638/* ------------------------------ */ 5639 .balign 64 5640.L_OP_ADD_LONG_2ADDR: /* 0xbb */ 5641/* File: armv6t2/OP_ADD_LONG_2ADDR.S */ 5642/* File: armv6t2/binopWide2addr.S */ 5643 /* 5644 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5645 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5646 * This could be an ARM instruction or a function call. (If the result 5647 * comes back in a register other than r0, you can override "result".) 5648 * 5649 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5650 * vCC (r1). Useful for integer division and modulus. 5651 * 5652 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5653 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5654 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5655 * rem-double/2addr 5656 */ 5657 /* binop/2addr vA, vB */ 5658 mov r1, rINST, lsr #12 @ r1<- B 5659 ubfx r9, rINST, #8, #4 @ r9<- A 5660 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5661 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5662 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5663 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5664 .if 0 5665 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5666 beq common_errDivideByZero 5667 .endif 5668 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5669 5670 adds r0, r0, r2 @ optional op; may set condition codes 5671 adc r1, r1, r3 @ result<- op, r0-r3 changed 5672 GET_INST_OPCODE(ip) @ extract opcode from rINST 5673 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5674 GOTO_OPCODE(ip) @ jump to next instruction 5675 /* 12-15 instructions */ 5676 5677 5678/* ------------------------------ */ 5679 .balign 64 5680.L_OP_SUB_LONG_2ADDR: /* 0xbc */ 5681/* File: armv6t2/OP_SUB_LONG_2ADDR.S */ 5682/* File: armv6t2/binopWide2addr.S */ 5683 /* 5684 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5685 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5686 * This could be an ARM instruction or a function call. (If the result 5687 * comes back in a register other than r0, you can override "result".) 5688 * 5689 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5690 * vCC (r1). Useful for integer division and modulus. 5691 * 5692 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5693 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5694 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5695 * rem-double/2addr 5696 */ 5697 /* binop/2addr vA, vB */ 5698 mov r1, rINST, lsr #12 @ r1<- B 5699 ubfx r9, rINST, #8, #4 @ r9<- A 5700 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5701 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5702 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5703 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5704 .if 0 5705 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5706 beq common_errDivideByZero 5707 .endif 5708 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5709 5710 subs r0, r0, r2 @ optional op; may set condition codes 5711 sbc r1, r1, r3 @ result<- op, r0-r3 changed 5712 GET_INST_OPCODE(ip) @ extract opcode from rINST 5713 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5714 GOTO_OPCODE(ip) @ jump to next instruction 5715 /* 12-15 instructions */ 5716 5717 5718/* ------------------------------ */ 5719 .balign 64 5720.L_OP_MUL_LONG_2ADDR: /* 0xbd */ 5721/* File: armv6t2/OP_MUL_LONG_2ADDR.S */ 5722 /* 5723 * Signed 64-bit integer multiply, "/2addr" version. 5724 * 5725 * See OP_MUL_LONG for an explanation. 5726 * 5727 * We get a little tight on registers, so to avoid looking up &fp[A] 5728 * again we stuff it into rINST. 5729 */ 5730 /* mul-long/2addr vA, vB */ 5731 mov r1, rINST, lsr #12 @ r1<- B 5732 ubfx r9, rINST, #8, #4 @ r9<- A 5733 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5734 add rINST, rFP, r9, lsl #2 @ rINST<- &fp[A] 5735 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5736 ldmia rINST, {r0-r1} @ r0/r1<- vAA/vAA+1 5737 mul ip, r2, r1 @ ip<- ZxW 5738 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 5739 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 5740 mov r0, rINST @ r0<- &fp[A] (free up rINST) 5741 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5742 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 5743 GET_INST_OPCODE(ip) @ extract opcode from rINST 5744 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 5745 GOTO_OPCODE(ip) @ jump to next instruction 5746 5747/* ------------------------------ */ 5748 .balign 64 5749.L_OP_DIV_LONG_2ADDR: /* 0xbe */ 5750/* File: armv6t2/OP_DIV_LONG_2ADDR.S */ 5751/* File: armv6t2/binopWide2addr.S */ 5752 /* 5753 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5754 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5755 * This could be an ARM instruction or a function call. (If the result 5756 * comes back in a register other than r0, you can override "result".) 5757 * 5758 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5759 * vCC (r1). Useful for integer division and modulus. 5760 * 5761 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5762 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5763 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5764 * rem-double/2addr 5765 */ 5766 /* binop/2addr vA, vB */ 5767 mov r1, rINST, lsr #12 @ r1<- B 5768 ubfx r9, rINST, #8, #4 @ r9<- A 5769 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5770 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5771 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5772 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5773 .if 1 5774 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5775 beq common_errDivideByZero 5776 .endif 5777 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5778 5779 @ optional op; may set condition codes 5780 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5781 GET_INST_OPCODE(ip) @ extract opcode from rINST 5782 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5783 GOTO_OPCODE(ip) @ jump to next instruction 5784 /* 12-15 instructions */ 5785 5786 5787/* ------------------------------ */ 5788 .balign 64 5789.L_OP_REM_LONG_2ADDR: /* 0xbf */ 5790/* File: armv6t2/OP_REM_LONG_2ADDR.S */ 5791/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 5792/* File: armv6t2/binopWide2addr.S */ 5793 /* 5794 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5795 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5796 * This could be an ARM instruction or a function call. (If the result 5797 * comes back in a register other than r0, you can override "result".) 5798 * 5799 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5800 * vCC (r1). Useful for integer division and modulus. 5801 * 5802 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5803 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5804 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5805 * rem-double/2addr 5806 */ 5807 /* binop/2addr vA, vB */ 5808 mov r1, rINST, lsr #12 @ r1<- B 5809 ubfx r9, rINST, #8, #4 @ r9<- A 5810 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5811 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5812 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5813 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5814 .if 1 5815 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5816 beq common_errDivideByZero 5817 .endif 5818 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5819 5820 @ optional op; may set condition codes 5821 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5822 GET_INST_OPCODE(ip) @ extract opcode from rINST 5823 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 5824 GOTO_OPCODE(ip) @ jump to next instruction 5825 /* 12-15 instructions */ 5826 5827 5828/* ------------------------------ */ 5829 .balign 64 5830.L_OP_AND_LONG_2ADDR: /* 0xc0 */ 5831/* File: armv6t2/OP_AND_LONG_2ADDR.S */ 5832/* File: armv6t2/binopWide2addr.S */ 5833 /* 5834 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5835 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5836 * This could be an ARM instruction or a function call. (If the result 5837 * comes back in a register other than r0, you can override "result".) 5838 * 5839 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5840 * vCC (r1). Useful for integer division and modulus. 5841 * 5842 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5843 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5844 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5845 * rem-double/2addr 5846 */ 5847 /* binop/2addr vA, vB */ 5848 mov r1, rINST, lsr #12 @ r1<- B 5849 ubfx r9, rINST, #8, #4 @ r9<- A 5850 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5851 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5852 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5853 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5854 .if 0 5855 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5856 beq common_errDivideByZero 5857 .endif 5858 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5859 5860 and r0, r0, r2 @ optional op; may set condition codes 5861 and r1, r1, r3 @ result<- op, r0-r3 changed 5862 GET_INST_OPCODE(ip) @ extract opcode from rINST 5863 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5864 GOTO_OPCODE(ip) @ jump to next instruction 5865 /* 12-15 instructions */ 5866 5867 5868/* ------------------------------ */ 5869 .balign 64 5870.L_OP_OR_LONG_2ADDR: /* 0xc1 */ 5871/* File: armv6t2/OP_OR_LONG_2ADDR.S */ 5872/* File: armv6t2/binopWide2addr.S */ 5873 /* 5874 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5875 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5876 * This could be an ARM instruction or a function call. (If the result 5877 * comes back in a register other than r0, you can override "result".) 5878 * 5879 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5880 * vCC (r1). Useful for integer division and modulus. 5881 * 5882 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5883 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5884 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5885 * rem-double/2addr 5886 */ 5887 /* binop/2addr vA, vB */ 5888 mov r1, rINST, lsr #12 @ r1<- B 5889 ubfx r9, rINST, #8, #4 @ r9<- A 5890 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5891 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5892 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5893 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5894 .if 0 5895 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5896 beq common_errDivideByZero 5897 .endif 5898 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5899 5900 orr r0, r0, r2 @ optional op; may set condition codes 5901 orr r1, r1, r3 @ result<- op, r0-r3 changed 5902 GET_INST_OPCODE(ip) @ extract opcode from rINST 5903 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5904 GOTO_OPCODE(ip) @ jump to next instruction 5905 /* 12-15 instructions */ 5906 5907 5908/* ------------------------------ */ 5909 .balign 64 5910.L_OP_XOR_LONG_2ADDR: /* 0xc2 */ 5911/* File: armv6t2/OP_XOR_LONG_2ADDR.S */ 5912/* File: armv6t2/binopWide2addr.S */ 5913 /* 5914 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5915 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5916 * This could be an ARM instruction or a function call. (If the result 5917 * comes back in a register other than r0, you can override "result".) 5918 * 5919 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5920 * vCC (r1). Useful for integer division and modulus. 5921 * 5922 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5923 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5924 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5925 * rem-double/2addr 5926 */ 5927 /* binop/2addr vA, vB */ 5928 mov r1, rINST, lsr #12 @ r1<- B 5929 ubfx r9, rINST, #8, #4 @ r9<- A 5930 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5931 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5932 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5933 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5934 .if 0 5935 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5936 beq common_errDivideByZero 5937 .endif 5938 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5939 5940 eor r0, r0, r2 @ optional op; may set condition codes 5941 eor r1, r1, r3 @ result<- op, r0-r3 changed 5942 GET_INST_OPCODE(ip) @ extract opcode from rINST 5943 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5944 GOTO_OPCODE(ip) @ jump to next instruction 5945 /* 12-15 instructions */ 5946 5947 5948/* ------------------------------ */ 5949 .balign 64 5950.L_OP_SHL_LONG_2ADDR: /* 0xc3 */ 5951/* File: armv6t2/OP_SHL_LONG_2ADDR.S */ 5952 /* 5953 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5954 * 32-bit shift distance. 5955 */ 5956 /* shl-long/2addr vA, vB */ 5957 mov r3, rINST, lsr #12 @ r3<- B 5958 ubfx r9, rINST, #8, #4 @ r9<- A 5959 GET_VREG(r2, r3) @ r2<- vB 5960 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5961 and r2, r2, #63 @ r2<- r2 & 0x3f 5962 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5963 5964 mov r1, r1, asl r2 @ r1<- r1 << r2 5965 rsb r3, r2, #32 @ r3<- 32 - r2 5966 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 5967 subs ip, r2, #32 @ ip<- r2 - 32 5968 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5969 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 5970 mov r0, r0, asl r2 @ r0<- r0 << r2 5971 b .LOP_SHL_LONG_2ADDR_finish 5972 5973/* ------------------------------ */ 5974 .balign 64 5975.L_OP_SHR_LONG_2ADDR: /* 0xc4 */ 5976/* File: armv6t2/OP_SHR_LONG_2ADDR.S */ 5977 /* 5978 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5979 * 32-bit shift distance. 5980 */ 5981 /* shr-long/2addr vA, vB */ 5982 mov r3, rINST, lsr #12 @ r3<- B 5983 ubfx r9, rINST, #8, #4 @ r9<- A 5984 GET_VREG(r2, r3) @ r2<- vB 5985 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5986 and r2, r2, #63 @ r2<- r2 & 0x3f 5987 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5988 5989 mov r0, r0, lsr r2 @ r0<- r2 >> r2 5990 rsb r3, r2, #32 @ r3<- 32 - r2 5991 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 5992 subs ip, r2, #32 @ ip<- r2 - 32 5993 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5994 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 5995 mov r1, r1, asr r2 @ r1<- r1 >> r2 5996 b .LOP_SHR_LONG_2ADDR_finish 5997 5998/* ------------------------------ */ 5999 .balign 64 6000.L_OP_USHR_LONG_2ADDR: /* 0xc5 */ 6001/* File: armv6t2/OP_USHR_LONG_2ADDR.S */ 6002 /* 6003 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6004 * 32-bit shift distance. 6005 */ 6006 /* ushr-long/2addr vA, vB */ 6007 mov r3, rINST, lsr #12 @ r3<- B 6008 ubfx r9, rINST, #8, #4 @ r9<- A 6009 GET_VREG(r2, r3) @ r2<- vB 6010 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6011 and r2, r2, #63 @ r2<- r2 & 0x3f 6012 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6013 6014 mov r0, r0, lsr r2 @ r0<- r2 >> r2 6015 rsb r3, r2, #32 @ r3<- 32 - r2 6016 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 6017 subs ip, r2, #32 @ ip<- r2 - 32 6018 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6019 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 6020 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 6021 b .LOP_USHR_LONG_2ADDR_finish 6022 6023/* ------------------------------ */ 6024 .balign 64 6025.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 6026/* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */ 6027/* File: arm-vfp/fbinop2addr.S */ 6028 /* 6029 * Generic 32-bit floating point "/2addr" binary operation. Provide 6030 * an "instr" line that specifies an instruction that performs 6031 * "s2 = s0 op s1". 6032 * 6033 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6034 */ 6035 /* binop/2addr vA, vB */ 6036 mov r3, rINST, lsr #12 @ r3<- B 6037 mov r9, rINST, lsr #8 @ r9<- A+ 6038 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6039 and r9, r9, #15 @ r9<- A 6040 flds s1, [r3] @ s1<- vB 6041 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6042 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6043 flds s0, [r9] @ s0<- vA 6044 6045 fadds s2, s0, s1 @ s2<- op 6046 GET_INST_OPCODE(ip) @ extract opcode from rINST 6047 fsts s2, [r9] @ vAA<- s2 6048 GOTO_OPCODE(ip) @ jump to next instruction 6049 6050 6051/* ------------------------------ */ 6052 .balign 64 6053.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 6054/* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */ 6055/* File: arm-vfp/fbinop2addr.S */ 6056 /* 6057 * Generic 32-bit floating point "/2addr" binary operation. Provide 6058 * an "instr" line that specifies an instruction that performs 6059 * "s2 = s0 op s1". 6060 * 6061 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6062 */ 6063 /* binop/2addr vA, vB */ 6064 mov r3, rINST, lsr #12 @ r3<- B 6065 mov r9, rINST, lsr #8 @ r9<- A+ 6066 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6067 and r9, r9, #15 @ r9<- A 6068 flds s1, [r3] @ s1<- vB 6069 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6070 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6071 flds s0, [r9] @ s0<- vA 6072 6073 fsubs s2, s0, s1 @ s2<- op 6074 GET_INST_OPCODE(ip) @ extract opcode from rINST 6075 fsts s2, [r9] @ vAA<- s2 6076 GOTO_OPCODE(ip) @ jump to next instruction 6077 6078 6079/* ------------------------------ */ 6080 .balign 64 6081.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 6082/* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */ 6083/* File: arm-vfp/fbinop2addr.S */ 6084 /* 6085 * Generic 32-bit floating point "/2addr" binary operation. Provide 6086 * an "instr" line that specifies an instruction that performs 6087 * "s2 = s0 op s1". 6088 * 6089 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6090 */ 6091 /* binop/2addr vA, vB */ 6092 mov r3, rINST, lsr #12 @ r3<- B 6093 mov r9, rINST, lsr #8 @ r9<- A+ 6094 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6095 and r9, r9, #15 @ r9<- A 6096 flds s1, [r3] @ s1<- vB 6097 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6098 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6099 flds s0, [r9] @ s0<- vA 6100 6101 fmuls s2, s0, s1 @ s2<- op 6102 GET_INST_OPCODE(ip) @ extract opcode from rINST 6103 fsts s2, [r9] @ vAA<- s2 6104 GOTO_OPCODE(ip) @ jump to next instruction 6105 6106 6107/* ------------------------------ */ 6108 .balign 64 6109.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 6110/* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */ 6111/* File: arm-vfp/fbinop2addr.S */ 6112 /* 6113 * Generic 32-bit floating point "/2addr" binary operation. Provide 6114 * an "instr" line that specifies an instruction that performs 6115 * "s2 = s0 op s1". 6116 * 6117 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6118 */ 6119 /* binop/2addr vA, vB */ 6120 mov r3, rINST, lsr #12 @ r3<- B 6121 mov r9, rINST, lsr #8 @ r9<- A+ 6122 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6123 and r9, r9, #15 @ r9<- A 6124 flds s1, [r3] @ s1<- vB 6125 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6126 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6127 flds s0, [r9] @ s0<- vA 6128 6129 fdivs s2, s0, s1 @ s2<- op 6130 GET_INST_OPCODE(ip) @ extract opcode from rINST 6131 fsts s2, [r9] @ vAA<- s2 6132 GOTO_OPCODE(ip) @ jump to next instruction 6133 6134 6135/* ------------------------------ */ 6136 .balign 64 6137.L_OP_REM_FLOAT_2ADDR: /* 0xca */ 6138/* File: armv6t2/OP_REM_FLOAT_2ADDR.S */ 6139/* EABI doesn't define a float remainder function, but libm does */ 6140/* File: armv6t2/binop2addr.S */ 6141 /* 6142 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6143 * that specifies an instruction that performs "result = r0 op r1". 6144 * This could be an ARM instruction or a function call. (If the result 6145 * comes back in a register other than r0, you can override "result".) 6146 * 6147 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6148 * vCC (r1). Useful for integer division and modulus. 6149 * 6150 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6151 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6152 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6153 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6154 */ 6155 /* binop/2addr vA, vB */ 6156 mov r3, rINST, lsr #12 @ r3<- B 6157 ubfx r9, rINST, #8, #4 @ r9<- A 6158 GET_VREG(r1, r3) @ r1<- vB 6159 GET_VREG(r0, r9) @ r0<- vA 6160 .if 0 6161 cmp r1, #0 @ is second operand zero? 6162 beq common_errDivideByZero 6163 .endif 6164 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6165 6166 @ optional op; may set condition codes 6167 bl fmodf @ r0<- op, r0-r3 changed 6168 GET_INST_OPCODE(ip) @ extract opcode from rINST 6169 SET_VREG(r0, r9) @ vAA<- r0 6170 GOTO_OPCODE(ip) @ jump to next instruction 6171 /* 10-13 instructions */ 6172 6173 6174/* ------------------------------ */ 6175 .balign 64 6176.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 6177/* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */ 6178/* File: arm-vfp/fbinopWide2addr.S */ 6179 /* 6180 * Generic 64-bit floating point "/2addr" binary operation. Provide 6181 * an "instr" line that specifies an instruction that performs 6182 * "d2 = d0 op d1". 6183 * 6184 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6185 * div-double/2addr 6186 */ 6187 /* binop/2addr vA, vB */ 6188 mov r3, rINST, lsr #12 @ r3<- B 6189 mov r9, rINST, lsr #8 @ r9<- A+ 6190 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6191 and r9, r9, #15 @ r9<- A 6192 fldd d1, [r3] @ d1<- vB 6193 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6194 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6195 fldd d0, [r9] @ d0<- vA 6196 6197 faddd d2, d0, d1 @ d2<- op 6198 GET_INST_OPCODE(ip) @ extract opcode from rINST 6199 fstd d2, [r9] @ vAA<- d2 6200 GOTO_OPCODE(ip) @ jump to next instruction 6201 6202 6203/* ------------------------------ */ 6204 .balign 64 6205.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 6206/* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */ 6207/* File: arm-vfp/fbinopWide2addr.S */ 6208 /* 6209 * Generic 64-bit floating point "/2addr" binary operation. Provide 6210 * an "instr" line that specifies an instruction that performs 6211 * "d2 = d0 op d1". 6212 * 6213 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6214 * div-double/2addr 6215 */ 6216 /* binop/2addr vA, vB */ 6217 mov r3, rINST, lsr #12 @ r3<- B 6218 mov r9, rINST, lsr #8 @ r9<- A+ 6219 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6220 and r9, r9, #15 @ r9<- A 6221 fldd d1, [r3] @ d1<- vB 6222 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6223 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6224 fldd d0, [r9] @ d0<- vA 6225 6226 fsubd d2, d0, d1 @ d2<- op 6227 GET_INST_OPCODE(ip) @ extract opcode from rINST 6228 fstd d2, [r9] @ vAA<- d2 6229 GOTO_OPCODE(ip) @ jump to next instruction 6230 6231 6232/* ------------------------------ */ 6233 .balign 64 6234.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 6235/* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */ 6236/* File: arm-vfp/fbinopWide2addr.S */ 6237 /* 6238 * Generic 64-bit floating point "/2addr" binary operation. Provide 6239 * an "instr" line that specifies an instruction that performs 6240 * "d2 = d0 op d1". 6241 * 6242 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6243 * div-double/2addr 6244 */ 6245 /* binop/2addr vA, vB */ 6246 mov r3, rINST, lsr #12 @ r3<- B 6247 mov r9, rINST, lsr #8 @ r9<- A+ 6248 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6249 and r9, r9, #15 @ r9<- A 6250 fldd d1, [r3] @ d1<- vB 6251 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6252 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6253 fldd d0, [r9] @ d0<- vA 6254 6255 fmuld d2, d0, d1 @ d2<- op 6256 GET_INST_OPCODE(ip) @ extract opcode from rINST 6257 fstd d2, [r9] @ vAA<- d2 6258 GOTO_OPCODE(ip) @ jump to next instruction 6259 6260 6261/* ------------------------------ */ 6262 .balign 64 6263.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 6264/* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */ 6265/* File: arm-vfp/fbinopWide2addr.S */ 6266 /* 6267 * Generic 64-bit floating point "/2addr" binary operation. Provide 6268 * an "instr" line that specifies an instruction that performs 6269 * "d2 = d0 op d1". 6270 * 6271 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6272 * div-double/2addr 6273 */ 6274 /* binop/2addr vA, vB */ 6275 mov r3, rINST, lsr #12 @ r3<- B 6276 mov r9, rINST, lsr #8 @ r9<- A+ 6277 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6278 and r9, r9, #15 @ r9<- A 6279 fldd d1, [r3] @ d1<- vB 6280 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6281 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6282 fldd d0, [r9] @ d0<- vA 6283 6284 fdivd d2, d0, d1 @ d2<- op 6285 GET_INST_OPCODE(ip) @ extract opcode from rINST 6286 fstd d2, [r9] @ vAA<- d2 6287 GOTO_OPCODE(ip) @ jump to next instruction 6288 6289 6290/* ------------------------------ */ 6291 .balign 64 6292.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 6293/* File: armv6t2/OP_REM_DOUBLE_2ADDR.S */ 6294/* EABI doesn't define a double remainder function, but libm does */ 6295/* File: armv6t2/binopWide2addr.S */ 6296 /* 6297 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6298 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 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-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6306 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6307 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6308 * rem-double/2addr 6309 */ 6310 /* binop/2addr vA, vB */ 6311 mov r1, rINST, lsr #12 @ r1<- B 6312 ubfx r9, rINST, #8, #4 @ r9<- A 6313 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6314 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6315 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6316 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6317 .if 0 6318 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6319 beq common_errDivideByZero 6320 .endif 6321 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6322 6323 @ optional op; may set condition codes 6324 bl fmod @ result<- op, r0-r3 changed 6325 GET_INST_OPCODE(ip) @ extract opcode from rINST 6326 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6327 GOTO_OPCODE(ip) @ jump to next instruction 6328 /* 12-15 instructions */ 6329 6330 6331/* ------------------------------ */ 6332 .balign 64 6333.L_OP_ADD_INT_LIT16: /* 0xd0 */ 6334/* File: armv6t2/OP_ADD_INT_LIT16.S */ 6335/* File: armv6t2/binopLit16.S */ 6336 /* 6337 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6338 * that specifies an instruction that performs "result = r0 op r1". 6339 * This could be an ARM instruction or a function call. (If the result 6340 * comes back in a register other than r0, you can override "result".) 6341 * 6342 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6343 * vCC (r1). Useful for integer division and modulus. 6344 * 6345 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6346 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6347 */ 6348 /* binop/lit16 vA, vB, #+CCCC */ 6349 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6350 mov r2, rINST, lsr #12 @ r2<- B 6351 ubfx r9, rINST, #8, #4 @ r9<- A 6352 GET_VREG(r0, r2) @ r0<- vB 6353 .if 0 6354 cmp r1, #0 @ is second operand zero? 6355 beq common_errDivideByZero 6356 .endif 6357 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6358 6359 add r0, r0, r1 @ r0<- op, r0-r3 changed 6360 GET_INST_OPCODE(ip) @ extract opcode from rINST 6361 SET_VREG(r0, r9) @ vAA<- r0 6362 GOTO_OPCODE(ip) @ jump to next instruction 6363 /* 10-13 instructions */ 6364 6365 6366/* ------------------------------ */ 6367 .balign 64 6368.L_OP_RSUB_INT: /* 0xd1 */ 6369/* File: armv6t2/OP_RSUB_INT.S */ 6370/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */ 6371/* File: armv6t2/binopLit16.S */ 6372 /* 6373 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6374 * that specifies an instruction that performs "result = r0 op r1". 6375 * This could be an ARM instruction or a function call. (If the result 6376 * comes back in a register other than r0, you can override "result".) 6377 * 6378 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6379 * vCC (r1). Useful for integer division and modulus. 6380 * 6381 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6382 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6383 */ 6384 /* binop/lit16 vA, vB, #+CCCC */ 6385 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6386 mov r2, rINST, lsr #12 @ r2<- B 6387 ubfx r9, rINST, #8, #4 @ r9<- A 6388 GET_VREG(r0, r2) @ r0<- vB 6389 .if 0 6390 cmp r1, #0 @ is second operand zero? 6391 beq common_errDivideByZero 6392 .endif 6393 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6394 6395 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6396 GET_INST_OPCODE(ip) @ extract opcode from rINST 6397 SET_VREG(r0, r9) @ vAA<- r0 6398 GOTO_OPCODE(ip) @ jump to next instruction 6399 /* 10-13 instructions */ 6400 6401 6402/* ------------------------------ */ 6403 .balign 64 6404.L_OP_MUL_INT_LIT16: /* 0xd2 */ 6405/* File: armv6t2/OP_MUL_INT_LIT16.S */ 6406/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6407/* File: armv6t2/binopLit16.S */ 6408 /* 6409 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6410 * that specifies an instruction that performs "result = r0 op r1". 6411 * This could be an ARM instruction or a function call. (If the result 6412 * comes back in a register other than r0, you can override "result".) 6413 * 6414 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6415 * vCC (r1). Useful for integer division and modulus. 6416 * 6417 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6418 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6419 */ 6420 /* binop/lit16 vA, vB, #+CCCC */ 6421 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6422 mov r2, rINST, lsr #12 @ r2<- B 6423 ubfx r9, rINST, #8, #4 @ r9<- A 6424 GET_VREG(r0, r2) @ r0<- vB 6425 .if 0 6426 cmp r1, #0 @ is second operand zero? 6427 beq common_errDivideByZero 6428 .endif 6429 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6430 6431 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6432 GET_INST_OPCODE(ip) @ extract opcode from rINST 6433 SET_VREG(r0, r9) @ vAA<- r0 6434 GOTO_OPCODE(ip) @ jump to next instruction 6435 /* 10-13 instructions */ 6436 6437 6438/* ------------------------------ */ 6439 .balign 64 6440.L_OP_DIV_INT_LIT16: /* 0xd3 */ 6441/* File: armv6t2/OP_DIV_INT_LIT16.S */ 6442/* File: armv6t2/binopLit16.S */ 6443 /* 6444 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6445 * that specifies an instruction that performs "result = r0 op r1". 6446 * This could be an ARM instruction or a function call. (If the result 6447 * comes back in a register other than r0, you can override "result".) 6448 * 6449 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6450 * vCC (r1). Useful for integer division and modulus. 6451 * 6452 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6453 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6454 */ 6455 /* binop/lit16 vA, vB, #+CCCC */ 6456 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6457 mov r2, rINST, lsr #12 @ r2<- B 6458 ubfx r9, rINST, #8, #4 @ r9<- A 6459 GET_VREG(r0, r2) @ r0<- vB 6460 .if 1 6461 cmp r1, #0 @ is second operand zero? 6462 beq common_errDivideByZero 6463 .endif 6464 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6465 6466 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6467 GET_INST_OPCODE(ip) @ extract opcode from rINST 6468 SET_VREG(r0, r9) @ vAA<- r0 6469 GOTO_OPCODE(ip) @ jump to next instruction 6470 /* 10-13 instructions */ 6471 6472 6473/* ------------------------------ */ 6474 .balign 64 6475.L_OP_REM_INT_LIT16: /* 0xd4 */ 6476/* File: armv6t2/OP_REM_INT_LIT16.S */ 6477/* idivmod returns quotient in r0 and remainder in r1 */ 6478/* File: armv6t2/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 ubfx r9, rINST, #8, #4 @ r9<- A 6495 GET_VREG(r0, r2) @ r0<- vB 6496 .if 1 6497 cmp r1, #0 @ is second operand zero? 6498 beq common_errDivideByZero 6499 .endif 6500 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6501 6502 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6503 GET_INST_OPCODE(ip) @ extract opcode from rINST 6504 SET_VREG(r1, r9) @ vAA<- r1 6505 GOTO_OPCODE(ip) @ jump to next instruction 6506 /* 10-13 instructions */ 6507 6508 6509/* ------------------------------ */ 6510 .balign 64 6511.L_OP_AND_INT_LIT16: /* 0xd5 */ 6512/* File: armv6t2/OP_AND_INT_LIT16.S */ 6513/* File: armv6t2/binopLit16.S */ 6514 /* 6515 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6516 * that specifies an instruction that performs "result = r0 op r1". 6517 * This could be an ARM instruction or a function call. (If the result 6518 * comes back in a register other than r0, you can override "result".) 6519 * 6520 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6521 * vCC (r1). Useful for integer division and modulus. 6522 * 6523 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6524 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6525 */ 6526 /* binop/lit16 vA, vB, #+CCCC */ 6527 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6528 mov r2, rINST, lsr #12 @ r2<- B 6529 ubfx r9, rINST, #8, #4 @ r9<- A 6530 GET_VREG(r0, r2) @ r0<- vB 6531 .if 0 6532 cmp r1, #0 @ is second operand zero? 6533 beq common_errDivideByZero 6534 .endif 6535 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6536 6537 and r0, r0, r1 @ r0<- op, r0-r3 changed 6538 GET_INST_OPCODE(ip) @ extract opcode from rINST 6539 SET_VREG(r0, r9) @ vAA<- r0 6540 GOTO_OPCODE(ip) @ jump to next instruction 6541 /* 10-13 instructions */ 6542 6543 6544/* ------------------------------ */ 6545 .balign 64 6546.L_OP_OR_INT_LIT16: /* 0xd6 */ 6547/* File: armv6t2/OP_OR_INT_LIT16.S */ 6548/* File: armv6t2/binopLit16.S */ 6549 /* 6550 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6551 * that specifies an instruction that performs "result = r0 op r1". 6552 * This could be an ARM instruction or a function call. (If the result 6553 * comes back in a register other than r0, you can override "result".) 6554 * 6555 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6556 * vCC (r1). Useful for integer division and modulus. 6557 * 6558 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6559 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6560 */ 6561 /* binop/lit16 vA, vB, #+CCCC */ 6562 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6563 mov r2, rINST, lsr #12 @ r2<- B 6564 ubfx r9, rINST, #8, #4 @ r9<- A 6565 GET_VREG(r0, r2) @ r0<- vB 6566 .if 0 6567 cmp r1, #0 @ is second operand zero? 6568 beq common_errDivideByZero 6569 .endif 6570 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6571 6572 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6573 GET_INST_OPCODE(ip) @ extract opcode from rINST 6574 SET_VREG(r0, r9) @ vAA<- r0 6575 GOTO_OPCODE(ip) @ jump to next instruction 6576 /* 10-13 instructions */ 6577 6578 6579/* ------------------------------ */ 6580 .balign 64 6581.L_OP_XOR_INT_LIT16: /* 0xd7 */ 6582/* File: armv6t2/OP_XOR_INT_LIT16.S */ 6583/* File: armv6t2/binopLit16.S */ 6584 /* 6585 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6586 * that specifies an instruction that performs "result = r0 op r1". 6587 * This could be an ARM instruction or a function call. (If the result 6588 * comes back in a register other than r0, you can override "result".) 6589 * 6590 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6591 * vCC (r1). Useful for integer division and modulus. 6592 * 6593 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6594 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6595 */ 6596 /* binop/lit16 vA, vB, #+CCCC */ 6597 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6598 mov r2, rINST, lsr #12 @ r2<- B 6599 ubfx r9, rINST, #8, #4 @ r9<- A 6600 GET_VREG(r0, r2) @ r0<- vB 6601 .if 0 6602 cmp r1, #0 @ is second operand zero? 6603 beq common_errDivideByZero 6604 .endif 6605 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6606 6607 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6608 GET_INST_OPCODE(ip) @ extract opcode from rINST 6609 SET_VREG(r0, r9) @ vAA<- r0 6610 GOTO_OPCODE(ip) @ jump to next instruction 6611 /* 10-13 instructions */ 6612 6613 6614/* ------------------------------ */ 6615 .balign 64 6616.L_OP_ADD_INT_LIT8: /* 0xd8 */ 6617/* File: armv5te/OP_ADD_INT_LIT8.S */ 6618/* File: armv5te/binopLit8.S */ 6619 /* 6620 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6621 * that specifies an instruction that performs "result = r0 op r1". 6622 * This could be an ARM instruction or a function call. (If the result 6623 * comes back in a register other than r0, you can override "result".) 6624 * 6625 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6626 * vCC (r1). Useful for integer division and modulus. 6627 * 6628 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6629 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6630 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6631 */ 6632 /* binop/lit8 vAA, vBB, #+CC */ 6633 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6634 mov r9, rINST, lsr #8 @ r9<- AA 6635 and r2, r3, #255 @ r2<- BB 6636 GET_VREG(r0, r2) @ r0<- vBB 6637 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6638 .if 0 6639 @cmp r1, #0 @ is second operand zero? 6640 beq common_errDivideByZero 6641 .endif 6642 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6643 6644 @ optional op; may set condition codes 6645 add r0, r0, r1 @ r0<- op, r0-r3 changed 6646 GET_INST_OPCODE(ip) @ extract opcode from rINST 6647 SET_VREG(r0, r9) @ vAA<- r0 6648 GOTO_OPCODE(ip) @ jump to next instruction 6649 /* 10-12 instructions */ 6650 6651 6652/* ------------------------------ */ 6653 .balign 64 6654.L_OP_RSUB_INT_LIT8: /* 0xd9 */ 6655/* File: armv5te/OP_RSUB_INT_LIT8.S */ 6656/* File: armv5te/binopLit8.S */ 6657 /* 6658 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6659 * that specifies an instruction that performs "result = r0 op r1". 6660 * This could be an ARM instruction or a function call. (If the result 6661 * comes back in a register other than r0, you can override "result".) 6662 * 6663 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6664 * vCC (r1). Useful for integer division and modulus. 6665 * 6666 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6667 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6668 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6669 */ 6670 /* binop/lit8 vAA, vBB, #+CC */ 6671 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6672 mov r9, rINST, lsr #8 @ r9<- AA 6673 and r2, r3, #255 @ r2<- BB 6674 GET_VREG(r0, r2) @ r0<- vBB 6675 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6676 .if 0 6677 @cmp r1, #0 @ is second operand zero? 6678 beq common_errDivideByZero 6679 .endif 6680 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6681 6682 @ optional op; may set condition codes 6683 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6684 GET_INST_OPCODE(ip) @ extract opcode from rINST 6685 SET_VREG(r0, r9) @ vAA<- r0 6686 GOTO_OPCODE(ip) @ jump to next instruction 6687 /* 10-12 instructions */ 6688 6689 6690/* ------------------------------ */ 6691 .balign 64 6692.L_OP_MUL_INT_LIT8: /* 0xda */ 6693/* File: armv5te/OP_MUL_INT_LIT8.S */ 6694/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6695/* File: armv5te/binopLit8.S */ 6696 /* 6697 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6698 * that specifies an instruction that performs "result = r0 op r1". 6699 * This could be an ARM instruction or a function call. (If the result 6700 * comes back in a register other than r0, you can override "result".) 6701 * 6702 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6703 * vCC (r1). Useful for integer division and modulus. 6704 * 6705 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6706 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6707 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6708 */ 6709 /* binop/lit8 vAA, vBB, #+CC */ 6710 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6711 mov r9, rINST, lsr #8 @ r9<- AA 6712 and r2, r3, #255 @ r2<- BB 6713 GET_VREG(r0, r2) @ r0<- vBB 6714 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6715 .if 0 6716 @cmp r1, #0 @ is second operand zero? 6717 beq common_errDivideByZero 6718 .endif 6719 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6720 6721 @ optional op; may set condition codes 6722 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6723 GET_INST_OPCODE(ip) @ extract opcode from rINST 6724 SET_VREG(r0, r9) @ vAA<- r0 6725 GOTO_OPCODE(ip) @ jump to next instruction 6726 /* 10-12 instructions */ 6727 6728 6729/* ------------------------------ */ 6730 .balign 64 6731.L_OP_DIV_INT_LIT8: /* 0xdb */ 6732/* File: armv5te/OP_DIV_INT_LIT8.S */ 6733/* File: armv5te/binopLit8.S */ 6734 /* 6735 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6736 * that specifies an instruction that performs "result = r0 op r1". 6737 * This could be an ARM instruction or a function call. (If the result 6738 * comes back in a register other than r0, you can override "result".) 6739 * 6740 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6741 * vCC (r1). Useful for integer division and modulus. 6742 * 6743 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6744 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6745 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6746 */ 6747 /* binop/lit8 vAA, vBB, #+CC */ 6748 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6749 mov r9, rINST, lsr #8 @ r9<- AA 6750 and r2, r3, #255 @ r2<- BB 6751 GET_VREG(r0, r2) @ r0<- vBB 6752 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6753 .if 1 6754 @cmp r1, #0 @ is second operand zero? 6755 beq common_errDivideByZero 6756 .endif 6757 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6758 6759 @ optional op; may set condition codes 6760 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6761 GET_INST_OPCODE(ip) @ extract opcode from rINST 6762 SET_VREG(r0, r9) @ vAA<- r0 6763 GOTO_OPCODE(ip) @ jump to next instruction 6764 /* 10-12 instructions */ 6765 6766 6767/* ------------------------------ */ 6768 .balign 64 6769.L_OP_REM_INT_LIT8: /* 0xdc */ 6770/* File: armv5te/OP_REM_INT_LIT8.S */ 6771/* idivmod returns quotient in r0 and remainder in r1 */ 6772/* File: armv5te/binopLit8.S */ 6773 /* 6774 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6775 * that specifies an instruction that performs "result = r0 op r1". 6776 * This could be an ARM instruction or a function call. (If the result 6777 * comes back in a register other than r0, you can override "result".) 6778 * 6779 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6780 * vCC (r1). Useful for integer division and modulus. 6781 * 6782 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6783 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6784 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6785 */ 6786 /* binop/lit8 vAA, vBB, #+CC */ 6787 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6788 mov r9, rINST, lsr #8 @ r9<- AA 6789 and r2, r3, #255 @ r2<- BB 6790 GET_VREG(r0, r2) @ r0<- vBB 6791 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6792 .if 1 6793 @cmp r1, #0 @ is second operand zero? 6794 beq common_errDivideByZero 6795 .endif 6796 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6797 6798 @ optional op; may set condition codes 6799 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6800 GET_INST_OPCODE(ip) @ extract opcode from rINST 6801 SET_VREG(r1, r9) @ vAA<- r1 6802 GOTO_OPCODE(ip) @ jump to next instruction 6803 /* 10-12 instructions */ 6804 6805 6806/* ------------------------------ */ 6807 .balign 64 6808.L_OP_AND_INT_LIT8: /* 0xdd */ 6809/* File: armv5te/OP_AND_INT_LIT8.S */ 6810/* File: armv5te/binopLit8.S */ 6811 /* 6812 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6813 * that specifies an instruction that performs "result = r0 op r1". 6814 * This could be an ARM instruction or a function call. (If the result 6815 * comes back in a register other than r0, you can override "result".) 6816 * 6817 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6818 * vCC (r1). Useful for integer division and modulus. 6819 * 6820 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6821 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6822 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6823 */ 6824 /* binop/lit8 vAA, vBB, #+CC */ 6825 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6826 mov r9, rINST, lsr #8 @ r9<- AA 6827 and r2, r3, #255 @ r2<- BB 6828 GET_VREG(r0, r2) @ r0<- vBB 6829 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6830 .if 0 6831 @cmp r1, #0 @ is second operand zero? 6832 beq common_errDivideByZero 6833 .endif 6834 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6835 6836 @ optional op; may set condition codes 6837 and r0, r0, r1 @ r0<- op, r0-r3 changed 6838 GET_INST_OPCODE(ip) @ extract opcode from rINST 6839 SET_VREG(r0, r9) @ vAA<- r0 6840 GOTO_OPCODE(ip) @ jump to next instruction 6841 /* 10-12 instructions */ 6842 6843 6844/* ------------------------------ */ 6845 .balign 64 6846.L_OP_OR_INT_LIT8: /* 0xde */ 6847/* File: armv5te/OP_OR_INT_LIT8.S */ 6848/* File: armv5te/binopLit8.S */ 6849 /* 6850 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6851 * that specifies an instruction that performs "result = r0 op r1". 6852 * This could be an ARM instruction or a function call. (If the result 6853 * comes back in a register other than r0, you can override "result".) 6854 * 6855 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6856 * vCC (r1). Useful for integer division and modulus. 6857 * 6858 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6859 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6860 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6861 */ 6862 /* binop/lit8 vAA, vBB, #+CC */ 6863 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6864 mov r9, rINST, lsr #8 @ r9<- AA 6865 and r2, r3, #255 @ r2<- BB 6866 GET_VREG(r0, r2) @ r0<- vBB 6867 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6868 .if 0 6869 @cmp r1, #0 @ is second operand zero? 6870 beq common_errDivideByZero 6871 .endif 6872 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6873 6874 @ optional op; may set condition codes 6875 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6876 GET_INST_OPCODE(ip) @ extract opcode from rINST 6877 SET_VREG(r0, r9) @ vAA<- r0 6878 GOTO_OPCODE(ip) @ jump to next instruction 6879 /* 10-12 instructions */ 6880 6881 6882/* ------------------------------ */ 6883 .balign 64 6884.L_OP_XOR_INT_LIT8: /* 0xdf */ 6885/* File: armv5te/OP_XOR_INT_LIT8.S */ 6886/* File: armv5te/binopLit8.S */ 6887 /* 6888 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6889 * that specifies an instruction that performs "result = r0 op r1". 6890 * This could be an ARM instruction or a function call. (If the result 6891 * comes back in a register other than r0, you can override "result".) 6892 * 6893 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6894 * vCC (r1). Useful for integer division and modulus. 6895 * 6896 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6897 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6898 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6899 */ 6900 /* binop/lit8 vAA, vBB, #+CC */ 6901 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6902 mov r9, rINST, lsr #8 @ r9<- AA 6903 and r2, r3, #255 @ r2<- BB 6904 GET_VREG(r0, r2) @ r0<- vBB 6905 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6906 .if 0 6907 @cmp r1, #0 @ is second operand zero? 6908 beq common_errDivideByZero 6909 .endif 6910 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6911 6912 @ optional op; may set condition codes 6913 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6914 GET_INST_OPCODE(ip) @ extract opcode from rINST 6915 SET_VREG(r0, r9) @ vAA<- r0 6916 GOTO_OPCODE(ip) @ jump to next instruction 6917 /* 10-12 instructions */ 6918 6919 6920/* ------------------------------ */ 6921 .balign 64 6922.L_OP_SHL_INT_LIT8: /* 0xe0 */ 6923/* File: armv5te/OP_SHL_INT_LIT8.S */ 6924/* File: armv5te/binopLit8.S */ 6925 /* 6926 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6927 * that specifies an instruction that performs "result = r0 op r1". 6928 * This could be an ARM instruction or a function call. (If the result 6929 * comes back in a register other than r0, you can override "result".) 6930 * 6931 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6932 * vCC (r1). Useful for integer division and modulus. 6933 * 6934 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6935 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6936 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6937 */ 6938 /* binop/lit8 vAA, vBB, #+CC */ 6939 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6940 mov r9, rINST, lsr #8 @ r9<- AA 6941 and r2, r3, #255 @ r2<- BB 6942 GET_VREG(r0, r2) @ r0<- vBB 6943 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6944 .if 0 6945 @cmp r1, #0 @ is second operand zero? 6946 beq common_errDivideByZero 6947 .endif 6948 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6949 6950 and r1, r1, #31 @ optional op; may set condition codes 6951 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 6952 GET_INST_OPCODE(ip) @ extract opcode from rINST 6953 SET_VREG(r0, r9) @ vAA<- r0 6954 GOTO_OPCODE(ip) @ jump to next instruction 6955 /* 10-12 instructions */ 6956 6957 6958/* ------------------------------ */ 6959 .balign 64 6960.L_OP_SHR_INT_LIT8: /* 0xe1 */ 6961/* File: armv5te/OP_SHR_INT_LIT8.S */ 6962/* File: armv5te/binopLit8.S */ 6963 /* 6964 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6965 * that specifies an instruction that performs "result = r0 op r1". 6966 * This could be an ARM instruction or a function call. (If the result 6967 * comes back in a register other than r0, you can override "result".) 6968 * 6969 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6970 * vCC (r1). Useful for integer division and modulus. 6971 * 6972 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6973 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6974 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6975 */ 6976 /* binop/lit8 vAA, vBB, #+CC */ 6977 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6978 mov r9, rINST, lsr #8 @ r9<- AA 6979 and r2, r3, #255 @ r2<- BB 6980 GET_VREG(r0, r2) @ r0<- vBB 6981 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6982 .if 0 6983 @cmp r1, #0 @ is second operand zero? 6984 beq common_errDivideByZero 6985 .endif 6986 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6987 6988 and r1, r1, #31 @ optional op; may set condition codes 6989 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 6990 GET_INST_OPCODE(ip) @ extract opcode from rINST 6991 SET_VREG(r0, r9) @ vAA<- r0 6992 GOTO_OPCODE(ip) @ jump to next instruction 6993 /* 10-12 instructions */ 6994 6995 6996/* ------------------------------ */ 6997 .balign 64 6998.L_OP_USHR_INT_LIT8: /* 0xe2 */ 6999/* File: armv5te/OP_USHR_INT_LIT8.S */ 7000/* File: armv5te/binopLit8.S */ 7001 /* 7002 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7003 * that specifies an instruction that performs "result = r0 op r1". 7004 * This could be an ARM instruction or a function call. (If the result 7005 * comes back in a register other than r0, you can override "result".) 7006 * 7007 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7008 * vCC (r1). Useful for integer division and modulus. 7009 * 7010 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7011 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7012 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7013 */ 7014 /* binop/lit8 vAA, vBB, #+CC */ 7015 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7016 mov r9, rINST, lsr #8 @ r9<- AA 7017 and r2, r3, #255 @ r2<- BB 7018 GET_VREG(r0, r2) @ r0<- vBB 7019 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7020 .if 0 7021 @cmp r1, #0 @ is second operand zero? 7022 beq common_errDivideByZero 7023 .endif 7024 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7025 7026 and r1, r1, #31 @ optional op; may set condition codes 7027 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 7028 GET_INST_OPCODE(ip) @ extract opcode from rINST 7029 SET_VREG(r0, r9) @ vAA<- r0 7030 GOTO_OPCODE(ip) @ jump to next instruction 7031 /* 10-12 instructions */ 7032 7033 7034/* ------------------------------ */ 7035 .balign 64 7036.L_OP_IGET_VOLATILE: /* 0xe3 */ 7037/* File: armv5te/OP_IGET_VOLATILE.S */ 7038/* File: armv5te/OP_IGET.S */ 7039 /* 7040 * General 32-bit instance field get. 7041 * 7042 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7043 */ 7044 /* op vA, vB, field@CCCC */ 7045 mov r0, rINST, lsr #12 @ r0<- B 7046 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7047 FETCH(r1, 1) @ r1<- field ref CCCC 7048 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7049 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7050 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7051 cmp r0, #0 @ is resolved entry null? 7052 bne .LOP_IGET_VOLATILE_finish @ no, already resolved 70538: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7054 EXPORT_PC() @ resolve() could throw 7055 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7056 bl dvmResolveInstField @ r0<- resolved InstField ptr 7057 cmp r0, #0 7058 bne .LOP_IGET_VOLATILE_finish 7059 b common_exceptionThrown 7060 7061 7062/* ------------------------------ */ 7063 .balign 64 7064.L_OP_IPUT_VOLATILE: /* 0xe4 */ 7065/* File: armv5te/OP_IPUT_VOLATILE.S */ 7066/* File: armv5te/OP_IPUT.S */ 7067 /* 7068 * General 32-bit instance field put. 7069 * 7070 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 7071 */ 7072 /* op vA, vB, field@CCCC */ 7073 mov r0, rINST, lsr #12 @ r0<- B 7074 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7075 FETCH(r1, 1) @ r1<- field ref CCCC 7076 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7077 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7078 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7079 cmp r0, #0 @ is resolved entry null? 7080 bne .LOP_IPUT_VOLATILE_finish @ no, already resolved 70818: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7082 EXPORT_PC() @ resolve() could throw 7083 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7084 bl dvmResolveInstField @ r0<- resolved InstField ptr 7085 cmp r0, #0 @ success? 7086 bne .LOP_IPUT_VOLATILE_finish @ yes, finish up 7087 b common_exceptionThrown 7088 7089 7090/* ------------------------------ */ 7091 .balign 64 7092.L_OP_SGET_VOLATILE: /* 0xe5 */ 7093/* File: armv5te/OP_SGET_VOLATILE.S */ 7094/* File: armv5te/OP_SGET.S */ 7095 /* 7096 * General 32-bit SGET handler. 7097 * 7098 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7099 */ 7100 /* op vAA, field@BBBB */ 7101 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7102 FETCH(r1, 1) @ r1<- field ref BBBB 7103 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7104 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7105 cmp r0, #0 @ is resolved entry null? 7106 beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve 7107.LOP_SGET_VOLATILE_finish: @ field ptr in r0 7108 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7109 SMP_DMB @ acquiring load 7110 mov r2, rINST, lsr #8 @ r2<- AA 7111 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7112 SET_VREG(r1, r2) @ fp[AA]<- r1 7113 GET_INST_OPCODE(ip) @ extract opcode from rINST 7114 GOTO_OPCODE(ip) @ jump to next instruction 7115 7116 7117/* ------------------------------ */ 7118 .balign 64 7119.L_OP_SPUT_VOLATILE: /* 0xe6 */ 7120/* File: armv5te/OP_SPUT_VOLATILE.S */ 7121/* File: armv5te/OP_SPUT.S */ 7122 /* 7123 * General 32-bit SPUT handler. 7124 * 7125 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 7126 */ 7127 /* op vAA, field@BBBB */ 7128 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7129 FETCH(r1, 1) @ r1<- field ref BBBB 7130 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7131 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7132 cmp r0, #0 @ is resolved entry null? 7133 beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve 7134.LOP_SPUT_VOLATILE_finish: @ field ptr in r0 7135 mov r2, rINST, lsr #8 @ r2<- AA 7136 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7137 GET_VREG(r1, r2) @ r1<- fp[AA] 7138 GET_INST_OPCODE(ip) @ extract opcode from rINST 7139 SMP_DMB @ releasing store 7140 str r1, [r0, #offStaticField_value] @ field<- vAA 7141 GOTO_OPCODE(ip) @ jump to next instruction 7142 7143 7144/* ------------------------------ */ 7145 .balign 64 7146.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 7147/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */ 7148/* File: armv5te/OP_IGET.S */ 7149 /* 7150 * General 32-bit instance field get. 7151 * 7152 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7153 */ 7154 /* op vA, vB, field@CCCC */ 7155 mov r0, rINST, lsr #12 @ r0<- B 7156 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7157 FETCH(r1, 1) @ r1<- field ref CCCC 7158 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7159 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7160 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7161 cmp r0, #0 @ is resolved entry null? 7162 bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved 71638: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7164 EXPORT_PC() @ resolve() could throw 7165 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7166 bl dvmResolveInstField @ r0<- resolved InstField ptr 7167 cmp r0, #0 7168 bne .LOP_IGET_OBJECT_VOLATILE_finish 7169 b common_exceptionThrown 7170 7171 7172/* ------------------------------ */ 7173 .balign 64 7174.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 7175/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */ 7176/* File: armv5te/OP_IGET_WIDE.S */ 7177 /* 7178 * Wide 32-bit instance field get. 7179 */ 7180 /* iget-wide vA, vB, field@CCCC */ 7181 mov r0, rINST, lsr #12 @ r0<- B 7182 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7183 FETCH(r1, 1) @ r1<- field ref CCCC 7184 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7185 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7186 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7187 cmp r0, #0 @ is resolved entry null? 7188 bne .LOP_IGET_WIDE_VOLATILE_finish @ no, already resolved 71898: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7190 EXPORT_PC() @ resolve() could throw 7191 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7192 bl dvmResolveInstField @ r0<- resolved InstField ptr 7193 cmp r0, #0 7194 bne .LOP_IGET_WIDE_VOLATILE_finish 7195 b common_exceptionThrown 7196 7197 7198/* ------------------------------ */ 7199 .balign 64 7200.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 7201/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */ 7202/* File: armv5te/OP_IPUT_WIDE.S */ 7203 /* iput-wide vA, vB, field@CCCC */ 7204 mov r0, rINST, lsr #12 @ r0<- B 7205 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7206 FETCH(r1, 1) @ r1<- field ref CCCC 7207 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7208 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7209 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7210 cmp r0, #0 @ is resolved entry null? 7211 bne .LOP_IPUT_WIDE_VOLATILE_finish @ no, already resolved 72128: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7213 EXPORT_PC() @ resolve() could throw 7214 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7215 bl dvmResolveInstField @ r0<- resolved InstField ptr 7216 cmp r0, #0 @ success? 7217 bne .LOP_IPUT_WIDE_VOLATILE_finish @ yes, finish up 7218 b common_exceptionThrown 7219 7220 7221/* ------------------------------ */ 7222 .balign 64 7223.L_OP_SGET_WIDE_VOLATILE: /* 0xea */ 7224/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */ 7225/* File: armv5te/OP_SGET_WIDE.S */ 7226 /* 7227 * 64-bit SGET handler. 7228 */ 7229 /* sget-wide vAA, field@BBBB */ 7230 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7231 FETCH(r1, 1) @ r1<- field ref BBBB 7232 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7233 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7234 cmp r0, #0 @ is resolved entry null? 7235 beq .LOP_SGET_WIDE_VOLATILE_resolve @ yes, do resolve 7236.LOP_SGET_WIDE_VOLATILE_finish: 7237 mov r9, rINST, lsr #8 @ r9<- AA 7238 .if 1 7239 add r0, r0, #offStaticField_value @ r0<- pointer to data 7240 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 7241 .else 7242 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 7243 .endif 7244 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7245 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7246 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 7247 GET_INST_OPCODE(ip) @ extract opcode from rINST 7248 GOTO_OPCODE(ip) @ jump to next instruction 7249 7250 7251/* ------------------------------ */ 7252 .balign 64 7253.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 7254/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */ 7255/* File: armv5te/OP_SPUT_WIDE.S */ 7256 /* 7257 * 64-bit SPUT handler. 7258 */ 7259 /* sput-wide vAA, field@BBBB */ 7260 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- DvmDex 7261 FETCH(r1, 1) @ r1<- field ref BBBB 7262 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 7263 mov r9, rINST, lsr #8 @ r9<- AA 7264 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 7265 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7266 cmp r2, #0 @ is resolved entry null? 7267 beq .LOP_SPUT_WIDE_VOLATILE_resolve @ yes, do resolve 7268.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9 7269 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7270 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 7271 GET_INST_OPCODE(r10) @ extract opcode from rINST 7272 .if 1 7273 add r2, r2, #offStaticField_value @ r2<- pointer to data 7274 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 7275 .else 7276 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 7277 .endif 7278 GOTO_OPCODE(r10) @ jump to next instruction 7279 7280 7281/* ------------------------------ */ 7282 .balign 64 7283.L_OP_BREAKPOINT: /* 0xec */ 7284/* File: armv5te/OP_BREAKPOINT.S */ 7285/* File: armv5te/unused.S */ 7286 bl common_abort 7287 7288 7289/* ------------------------------ */ 7290 .balign 64 7291.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 7292/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */ 7293 /* 7294 * Handle a throw-verification-error instruction. This throws an 7295 * exception for an error discovered during verification. The 7296 * exception is indicated by AA, with some detail provided by BBBB. 7297 */ 7298 /* op AA, ref@BBBB */ 7299 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 7300 FETCH(r2, 1) @ r2<- BBBB 7301 EXPORT_PC() @ export the PC 7302 mov r1, rINST, lsr #8 @ r1<- AA 7303 bl dvmThrowVerificationError @ always throws 7304 b common_exceptionThrown @ handle exception 7305 7306/* ------------------------------ */ 7307 .balign 64 7308.L_OP_EXECUTE_INLINE: /* 0xee */ 7309/* File: armv5te/OP_EXECUTE_INLINE.S */ 7310 /* 7311 * Execute a "native inline" instruction. 7312 * 7313 * We need to call an InlineOp4Func: 7314 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7315 * 7316 * The first four args are in r0-r3, pointer to return value storage 7317 * is on the stack. The function's return value is a flag that tells 7318 * us if an exception was thrown. 7319 */ 7320 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 7321 FETCH(r10, 1) @ r10<- BBBB 7322 add r1, rSELF, #offThread_retval @ r1<- &self->retval 7323 EXPORT_PC() @ can throw 7324 sub sp, sp, #8 @ make room for arg, +64 bit align 7325 mov r0, rINST, lsr #12 @ r0<- B 7326 str r1, [sp] @ push &self->retval 7327 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 7328 add sp, sp, #8 @ pop stack 7329 cmp r0, #0 @ test boolean result of inline 7330 beq common_exceptionThrown @ returned false, handle exception 7331 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7332 GET_INST_OPCODE(ip) @ extract opcode from rINST 7333 GOTO_OPCODE(ip) @ jump to next instruction 7334 7335/* ------------------------------ */ 7336 .balign 64 7337.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 7338/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */ 7339 /* 7340 * Execute a "native inline" instruction, using "/range" semantics. 7341 * Same idea as execute-inline, but we get the args differently. 7342 * 7343 * We need to call an InlineOp4Func: 7344 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7345 * 7346 * The first four args are in r0-r3, pointer to return value storage 7347 * is on the stack. The function's return value is a flag that tells 7348 * us if an exception was thrown. 7349 */ 7350 /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */ 7351 FETCH(r10, 1) @ r10<- BBBB 7352 add r1, rSELF, #offThread_retval @ r1<- &self->retval 7353 EXPORT_PC() @ can throw 7354 sub sp, sp, #8 @ make room for arg, +64 bit align 7355 mov r0, rINST, lsr #8 @ r0<- AA 7356 str r1, [sp] @ push &self->retval 7357 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 7358 add sp, sp, #8 @ pop stack 7359 cmp r0, #0 @ test boolean result of inline 7360 beq common_exceptionThrown @ returned false, handle exception 7361 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7362 GET_INST_OPCODE(ip) @ extract opcode from rINST 7363 GOTO_OPCODE(ip) @ jump to next instruction 7364 7365/* ------------------------------ */ 7366 .balign 64 7367.L_OP_INVOKE_OBJECT_INIT: /* 0xf0 */ 7368/* File: armv5te/OP_INVOKE_OBJECT_INIT.S */ 7369 /* 7370 * Invoke Object.<init> on an object. In practice we know that 7371 * Object's nullary constructor doesn't do anything, so we just 7372 * skip it (we know a debugger isn't active). 7373 */ 7374 FETCH(r0, 2) @ r0<- GFED 7375 and r1, r0, #15 @ r1<- D 7376 GET_VREG(r0, r1) @ r0<- "this" ptr 7377 cmp r0, #0 @ check for NULL 7378 beq common_errNullObject @ export PC and throw NPE 7379 ldr r1, [r0, #offObject_clazz] @ r1<- obj->clazz 7380 ldr r2, [r1, #offClassObject_accessFlags] @ r2<- clazz->accessFlags 7381 tst r2, #CLASS_ISFINALIZABLE @ is this class finalizable? 7382 beq 1f @ nope, done 7383 bl dvmSetFinalizable @ call dvmSetFinalizable(obj) 73841: FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 7385 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 7386 GOTO_OPCODE(ip) @ execute it 7387 7388/* ------------------------------ */ 7389 .balign 64 7390.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 7391/* File: armv5te/OP_RETURN_VOID_BARRIER.S */ 7392 SMP_DMB_ST 7393 b common_returnFromMethod 7394 7395/* ------------------------------ */ 7396 .balign 64 7397.L_OP_IGET_QUICK: /* 0xf2 */ 7398/* File: armv6t2/OP_IGET_QUICK.S */ 7399 /* For: iget-quick, iget-object-quick */ 7400 /* op vA, vB, offset@CCCC */ 7401 mov r2, rINST, lsr #12 @ r2<- B 7402 FETCH(r1, 1) @ r1<- field byte offset 7403 GET_VREG(r3, r2) @ r3<- object we're operating on 7404 ubfx r2, rINST, #8, #4 @ r2<- A 7405 cmp r3, #0 @ check object for null 7406 beq common_errNullObject @ object was null 7407 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7408 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7409 GET_INST_OPCODE(ip) @ extract opcode from rINST 7410 SET_VREG(r0, r2) @ fp[A]<- r0 7411 GOTO_OPCODE(ip) @ jump to next instruction 7412 7413/* ------------------------------ */ 7414 .balign 64 7415.L_OP_IGET_WIDE_QUICK: /* 0xf3 */ 7416/* File: armv6t2/OP_IGET_WIDE_QUICK.S */ 7417 /* iget-wide-quick vA, vB, offset@CCCC */ 7418 mov r2, rINST, lsr #12 @ r2<- B 7419 FETCH(ip, 1) @ ip<- field byte offset 7420 GET_VREG(r3, r2) @ r3<- object we're operating on 7421 ubfx r2, rINST, #8, #4 @ r2<- A 7422 cmp r3, #0 @ check object for null 7423 beq common_errNullObject @ object was null 7424 ldrd r0, [r3, ip] @ r0<- obj.field (64 bits, aligned) 7425 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7426 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 7427 GET_INST_OPCODE(ip) @ extract opcode from rINST 7428 stmia r3, {r0-r1} @ fp[A]<- r0/r1 7429 GOTO_OPCODE(ip) @ jump to next instruction 7430 7431/* ------------------------------ */ 7432 .balign 64 7433.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 7434/* File: armv5te/OP_IGET_OBJECT_QUICK.S */ 7435/* File: armv5te/OP_IGET_QUICK.S */ 7436 /* For: iget-quick, iget-object-quick */ 7437 /* op vA, vB, offset@CCCC */ 7438 mov r2, rINST, lsr #12 @ r2<- B 7439 GET_VREG(r3, r2) @ r3<- object we're operating on 7440 FETCH(r1, 1) @ r1<- field byte offset 7441 cmp r3, #0 @ check object for null 7442 mov r2, rINST, lsr #8 @ r2<- A(+) 7443 beq common_errNullObject @ object was null 7444 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7445 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7446 and r2, r2, #15 7447 GET_INST_OPCODE(ip) @ extract opcode from rINST 7448 SET_VREG(r0, r2) @ fp[A]<- r0 7449 GOTO_OPCODE(ip) @ jump to next instruction 7450 7451 7452/* ------------------------------ */ 7453 .balign 64 7454.L_OP_IPUT_QUICK: /* 0xf5 */ 7455/* File: armv6t2/OP_IPUT_QUICK.S */ 7456 /* For: iput-quick, iput-object-quick */ 7457 /* op vA, vB, offset@CCCC */ 7458 mov r2, rINST, lsr #12 @ r2<- B 7459 FETCH(r1, 1) @ r1<- field byte offset 7460 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7461 ubfx r2, rINST, #8, #4 @ r2<- A 7462 cmp r3, #0 @ check object for null 7463 beq common_errNullObject @ object was null 7464 GET_VREG(r0, r2) @ r0<- fp[A] 7465 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7466 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7467 GET_INST_OPCODE(ip) @ extract opcode from rINST 7468 GOTO_OPCODE(ip) @ jump to next instruction 7469 7470/* ------------------------------ */ 7471 .balign 64 7472.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 7473/* File: armv6t2/OP_IPUT_WIDE_QUICK.S */ 7474 /* iput-wide-quick vA, vB, offset@CCCC */ 7475 mov r1, rINST, lsr #12 @ r1<- B 7476 ubfx r0, rINST, #8, #4 @ r0<- A 7477 GET_VREG(r2, r1) @ r2<- fp[B], the object pointer 7478 add r3, rFP, r0, lsl #2 @ r3<- &fp[A] 7479 cmp r2, #0 @ check object for null 7480 ldmia r3, {r0-r1} @ r0/r1<- fp[A] 7481 beq common_errNullObject @ object was null 7482 FETCH(r3, 1) @ r3<- field byte offset 7483 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7484 strd r0, [r2, r3] @ obj.field (64 bits, aligned)<- r0/r1 7485 GET_INST_OPCODE(ip) @ extract opcode from rINST 7486 GOTO_OPCODE(ip) @ jump to next instruction 7487 7488/* ------------------------------ */ 7489 .balign 64 7490.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 7491/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */ 7492 /* For: iput-object-quick */ 7493 /* op vA, vB, offset@CCCC */ 7494 mov r2, rINST, lsr #12 @ r2<- B 7495 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7496 FETCH(r1, 1) @ r1<- field byte offset 7497 cmp r3, #0 @ check object for null 7498 mov r2, rINST, lsr #8 @ r2<- A(+) 7499 beq common_errNullObject @ object was null 7500 and r2, r2, #15 7501 GET_VREG(r0, r2) @ r0<- fp[A] 7502 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 7503 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7504 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7505 cmp r0, #0 7506 strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head 7507 GET_INST_OPCODE(ip) @ extract opcode from rINST 7508 GOTO_OPCODE(ip) @ jump to next instruction 7509 7510/* ------------------------------ */ 7511 .balign 64 7512.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 7513/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7514 /* 7515 * Handle an optimized virtual method call. 7516 * 7517 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7518 */ 7519 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7520 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7521 FETCH(r3, 2) @ r3<- FEDC or CCCC 7522 FETCH(r1, 1) @ r1<- BBBB 7523 .if (!0) 7524 and r3, r3, #15 @ r3<- C (or stays CCCC) 7525 .endif 7526 GET_VREG(r2, r3) @ r2<- vC ("this" ptr) 7527 cmp r2, #0 @ is "this" null? 7528 beq common_errNullObject @ null "this", throw exception 7529 ldr r2, [r2, #offObject_clazz] @ r2<- thisPtr->clazz 7530 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7531 EXPORT_PC() @ invoke must export 7532 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7533 bl common_invokeMethodNoRange @ continue on 7534 7535/* ------------------------------ */ 7536 .balign 64 7537.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 7538/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */ 7539/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7540 /* 7541 * Handle an optimized virtual method call. 7542 * 7543 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7544 */ 7545 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7546 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7547 FETCH(r3, 2) @ r3<- FEDC or CCCC 7548 FETCH(r1, 1) @ r1<- BBBB 7549 .if (!1) 7550 and r3, r3, #15 @ r3<- C (or stays CCCC) 7551 .endif 7552 GET_VREG(r2, r3) @ r2<- vC ("this" ptr) 7553 cmp r2, #0 @ is "this" null? 7554 beq common_errNullObject @ null "this", throw exception 7555 ldr r2, [r2, #offObject_clazz] @ r2<- thisPtr->clazz 7556 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7557 EXPORT_PC() @ invoke must export 7558 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7559 bl common_invokeMethodRange @ continue on 7560 7561 7562/* ------------------------------ */ 7563 .balign 64 7564.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 7565/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7566 /* 7567 * Handle an optimized "super" method call. 7568 * 7569 * for: [opt] invoke-super-quick, invoke-super-quick/range 7570 */ 7571 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7572 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7573 FETCH(r10, 2) @ r10<- GFED or CCCC 7574 ldr r2, [rSELF, #offThread_method] @ r2<- current method 7575 .if (!0) 7576 and r10, r10, #15 @ r10<- D (or stays CCCC) 7577 .endif 7578 FETCH(r1, 1) @ r1<- BBBB 7579 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7580 EXPORT_PC() @ must export for invoke 7581 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7582 GET_VREG(r3, r10) @ r3<- "this" 7583 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7584 cmp r3, #0 @ null "this" ref? 7585 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7586 beq common_errNullObject @ "this" is null, throw exception 7587 bl common_invokeMethodNoRange @ continue on 7588 7589/* ------------------------------ */ 7590 .balign 64 7591.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 7592/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */ 7593/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7594 /* 7595 * Handle an optimized "super" method call. 7596 * 7597 * for: [opt] invoke-super-quick, invoke-super-quick/range 7598 */ 7599 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7600 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7601 FETCH(r10, 2) @ r10<- GFED or CCCC 7602 ldr r2, [rSELF, #offThread_method] @ r2<- current method 7603 .if (!1) 7604 and r10, r10, #15 @ r10<- D (or stays CCCC) 7605 .endif 7606 FETCH(r1, 1) @ r1<- BBBB 7607 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7608 EXPORT_PC() @ must export for invoke 7609 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7610 GET_VREG(r3, r10) @ r3<- "this" 7611 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7612 cmp r3, #0 @ null "this" ref? 7613 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7614 beq common_errNullObject @ "this" is null, throw exception 7615 bl common_invokeMethodRange @ continue on 7616 7617 7618/* ------------------------------ */ 7619 .balign 64 7620.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 7621/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */ 7622/* File: armv5te/OP_IPUT_OBJECT.S */ 7623 /* 7624 * 32-bit instance field put. 7625 * 7626 * for: iput-object, iput-object-volatile 7627 */ 7628 /* op vA, vB, field@CCCC */ 7629 mov r0, rINST, lsr #12 @ r0<- B 7630 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7631 FETCH(r1, 1) @ r1<- field ref CCCC 7632 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7633 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7634 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7635 cmp r0, #0 @ is resolved entry null? 7636 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved 76378: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7638 EXPORT_PC() @ resolve() could throw 7639 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7640 bl dvmResolveInstField @ r0<- resolved InstField ptr 7641 cmp r0, #0 @ success? 7642 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up 7643 b common_exceptionThrown 7644 7645 7646/* ------------------------------ */ 7647 .balign 64 7648.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 7649/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */ 7650/* File: armv5te/OP_SGET.S */ 7651 /* 7652 * General 32-bit SGET handler. 7653 * 7654 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7655 */ 7656 /* op vAA, field@BBBB */ 7657 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7658 FETCH(r1, 1) @ r1<- field ref BBBB 7659 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7660 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7661 cmp r0, #0 @ is resolved entry null? 7662 beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve 7663.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0 7664 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7665 SMP_DMB @ acquiring load 7666 mov r2, rINST, lsr #8 @ r2<- AA 7667 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7668 SET_VREG(r1, r2) @ fp[AA]<- r1 7669 GET_INST_OPCODE(ip) @ extract opcode from rINST 7670 GOTO_OPCODE(ip) @ jump to next instruction 7671 7672 7673/* ------------------------------ */ 7674 .balign 64 7675.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 7676/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */ 7677/* File: armv5te/OP_SPUT_OBJECT.S */ 7678 /* 7679 * 32-bit SPUT handler for objects 7680 * 7681 * for: sput-object, sput-object-volatile 7682 */ 7683 /* op vAA, field@BBBB */ 7684 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 7685 FETCH(r1, 1) @ r1<- field ref BBBB 7686 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7687 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7688 cmp r0, #0 @ is resolved entry null? 7689 bne .LOP_SPUT_OBJECT_VOLATILE_finish @ no, continue 7690 ldr r9, [rSELF, #offThread_method] @ r9<- current method 7691 EXPORT_PC() @ resolve() could throw, so export now 7692 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 7693 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 7694 cmp r0, #0 @ success? 7695 bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish 7696 b common_exceptionThrown @ no, handle exception 7697 7698 7699 7700/* ------------------------------ */ 7701 .balign 64 7702.L_OP_DISPATCH_FF: /* 0xff */ 7703/* File: armv5te/OP_DISPATCH_FF.S */ 7704 mov ip, rINST, lsr #8 @ r9<- extended opcode 7705 add ip, ip, #256 @ add offset for extended opcodes 7706 GOTO_OPCODE(ip) @ go to proper extended handler 7707 7708 7709/* ------------------------------ */ 7710 .balign 64 7711.L_OP_CONST_CLASS_JUMBO: /* 0x100 */ 7712/* File: armv5te/OP_CONST_CLASS_JUMBO.S */ 7713 /* const-class/jumbo vBBBB, Class@AAAAAAAA */ 7714 FETCH(r0, 1) @ r0<- aaaa (lo) 7715 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<-self>methodClassDex 7716 FETCH(r1, 2) @ r1<- AAAA (hi) 7717 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- dvmDex->pResClasses 7718 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 7719 FETCH(r9, 3) @ r9<- BBBB 7720 ldr r0, [r2, r1, lsl #2] @ r0<- pResClasses[AAAAaaaa] 7721 cmp r0, #0 @ not yet resolved? 7722 beq .LOP_CONST_CLASS_JUMBO_resolve 7723 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 7724 GET_INST_OPCODE(ip) @ extract opcode from rINST 7725 SET_VREG(r0, r9) @ vBBBB<- r0 7726 GOTO_OPCODE(ip) @ jump to next instruction 7727 7728/* ------------------------------ */ 7729 .balign 64 7730.L_OP_CHECK_CAST_JUMBO: /* 0x101 */ 7731/* File: armv5te/OP_CHECK_CAST_JUMBO.S */ 7732 /* 7733 * Check to see if a cast from one class to another is allowed. 7734 */ 7735 /* check-cast/jumbo vBBBB, class@AAAAAAAA */ 7736 FETCH(r0, 1) @ r0<- aaaa (lo) 7737 FETCH(r2, 2) @ r2<- AAAA (hi) 7738 FETCH(r3, 3) @ r3<- BBBB 7739 orr r2, r0, r2, lsl #16 @ r2<- AAAAaaaa 7740 GET_VREG(r9, r3) @ r9<- object 7741 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- pDvmDex 7742 cmp r9, #0 @ is object null? 7743 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 7744 beq .LOP_CHECK_CAST_JUMBO_okay @ null obj, cast always succeeds 7745 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 7746 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 7747 cmp r1, #0 @ have we resolved this before? 7748 beq .LOP_CHECK_CAST_JUMBO_resolve @ not resolved, do it now 7749.LOP_CHECK_CAST_JUMBO_resolved: 7750 cmp r0, r1 @ same class (trivial success)? 7751 bne .LOP_CHECK_CAST_JUMBO_fullcheck @ no, do full check 7752 b .LOP_CHECK_CAST_JUMBO_okay @ yes, finish up 7753 7754/* ------------------------------ */ 7755 .balign 64 7756.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */ 7757/* File: armv5te/OP_INSTANCE_OF_JUMBO.S */ 7758 /* 7759 * Check to see if an object reference is an instance of a class. 7760 * 7761 * Most common situation is a non-null object, being compared against 7762 * an already-resolved class. 7763 * 7764 * TODO: convert most of this into a common subroutine, shared with 7765 * OP_INSTANCE_OF.S. 7766 */ 7767 /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 7768 FETCH(r3, 4) @ r3<- vCCCC 7769 FETCH(r9, 3) @ r9<- vBBBB 7770 GET_VREG(r0, r3) @ r0<- vCCCC (object) 7771 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- pDvmDex 7772 cmp r0, #0 @ is object null? 7773 beq .LOP_INSTANCE_OF_JUMBO_store @ null obj, not an instance, store r0 7774 FETCH(r1, 1) @ r1<- aaaa (lo) 7775 FETCH(r3, 2) @ r3<- AAAA (hi) 7776 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 7777 orr r3, r1, r3, lsl #16 @ r3<- AAAAaaaa 7778 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 7779 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 7780 cmp r1, #0 @ have we resolved this before? 7781 beq .LOP_INSTANCE_OF_JUMBO_resolve @ not resolved, do it now 7782 b .LOP_INSTANCE_OF_JUMBO_resolved @ resolved, continue 7783 7784/* ------------------------------ */ 7785 .balign 64 7786.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */ 7787/* File: armv5te/OP_NEW_INSTANCE_JUMBO.S */ 7788 /* 7789 * Create a new instance of a class. 7790 */ 7791 /* new-instance/jumbo vBBBB, class@AAAAAAAA */ 7792 FETCH(r0, 1) @ r0<- aaaa (lo) 7793 FETCH(r1, 2) @ r1<- AAAA (hi) 7794 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 7795 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 7796 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 7797 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 7798 EXPORT_PC() @ req'd for init, resolve, alloc 7799 cmp r0, #0 @ already resolved? 7800 beq .LOP_NEW_INSTANCE_JUMBO_resolve @ no, resolve it now 7801.LOP_NEW_INSTANCE_JUMBO_resolved: @ r0=class 7802 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 7803 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 7804 bne .LOP_NEW_INSTANCE_JUMBO_needinit @ no, init class now 7805.LOP_NEW_INSTANCE_JUMBO_initialized: @ r0=class 7806 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 7807 bl dvmAllocObject @ r0<- new object 7808 b .LOP_NEW_INSTANCE_JUMBO_finish @ continue 7809 7810/* ------------------------------ */ 7811 .balign 64 7812.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */ 7813/* File: armv5te/OP_NEW_ARRAY_JUMBO.S */ 7814 /* 7815 * Allocate an array of objects, specified with the array class 7816 * and a count. 7817 * 7818 * The verifier guarantees that this is an array class, so we don't 7819 * check for it here. 7820 */ 7821 /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 7822 FETCH(r2, 1) @ r2<- aaaa (lo) 7823 FETCH(r3, 2) @ r3<- AAAA (hi) 7824 FETCH(r0, 4) @ r0<- vCCCC 7825 orr r2, r2, r3, lsl #16 @ r2<- AAAAaaaa 7826 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 7827 GET_VREG(r1, r0) @ r1<- vCCCC (array length) 7828 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 7829 cmp r1, #0 @ check length 7830 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 7831 bmi common_errNegativeArraySize @ negative length, bail - len in r1 7832 cmp r0, #0 @ already resolved? 7833 EXPORT_PC() @ req'd for resolve, alloc 7834 bne .LOP_NEW_ARRAY_JUMBO_finish @ resolved, continue 7835 b .LOP_NEW_ARRAY_JUMBO_resolve @ do resolve now 7836 7837/* ------------------------------ */ 7838 .balign 64 7839.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */ 7840/* File: armv5te/OP_FILLED_NEW_ARRAY_JUMBO.S */ 7841 /* 7842 * Create a new array with elements filled from registers. 7843 * 7844 * TODO: convert most of this into a common subroutine, shared with 7845 * OP_FILLED_NEW_ARRAY.S. 7846 */ 7847 /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */ 7848 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 7849 FETCH(r0, 1) @ r0<- aaaa (lo) 7850 FETCH(r1, 2) @ r1<- AAAA (hi) 7851 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 7852 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 7853 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 7854 EXPORT_PC() @ need for resolve and alloc 7855 cmp r0, #0 @ already resolved? 7856 bne .LOP_FILLED_NEW_ARRAY_JUMBO_continue @ yes, continue on 78578: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 7858 mov r2, #0 @ r2<- false 7859 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7860 bl dvmResolveClass @ r0<- call(clazz, ref) 7861 cmp r0, #0 @ got null? 7862 beq common_exceptionThrown @ yes, handle exception 7863 b .LOP_FILLED_NEW_ARRAY_JUMBO_continue 7864 7865/* ------------------------------ */ 7866 .balign 64 7867.L_OP_IGET_JUMBO: /* 0x106 */ 7868/* File: armv5te/OP_IGET_JUMBO.S */ 7869 /* 7870 * Jumbo 32-bit instance field get. 7871 * 7872 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7873 * iget-char/jumbo, iget-short/jumbo 7874 */ 7875 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 7876 FETCH(r1, 1) @ r1<- aaaa (lo) 7877 FETCH(r2, 2) @ r2<- AAAA (hi) 7878 FETCH(r0, 4) @ r0<- CCCC 7879 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7880 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7881 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7882 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7883 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7884 cmp r0, #0 @ is resolved entry null? 7885 bne .LOP_IGET_JUMBO_finish @ no, already resolved 78868: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7887 EXPORT_PC() @ resolve() could throw 7888 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7889 bl dvmResolveInstField @ r0<- resolved InstField ptr 7890 b .LOP_IGET_JUMBO_resolved @ resolved, continue 7891 7892/* ------------------------------ */ 7893 .balign 64 7894.L_OP_IGET_WIDE_JUMBO: /* 0x107 */ 7895/* File: armv5te/OP_IGET_WIDE_JUMBO.S */ 7896 /* 7897 * Jumbo 64-bit instance field get. 7898 */ 7899 /* iget-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 7900 FETCH(r1, 1) @ r1<- aaaa (lo) 7901 FETCH(r2, 2) @ r2<- AAAA (hi) 7902 FETCH(r0, 4) @ r0<- CCCC 7903 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7904 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7905 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7906 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7907 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7908 cmp r0, #0 @ is resolved entry null? 7909 bne .LOP_IGET_WIDE_JUMBO_finish @ no, already resolved 79108: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7911 EXPORT_PC() @ resolve() could throw 7912 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7913 bl dvmResolveInstField @ r0<- resolved InstField ptr 7914 b .LOP_IGET_WIDE_JUMBO_resolved @ resolved, continue 7915 7916/* ------------------------------ */ 7917 .balign 64 7918.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */ 7919/* File: armv5te/OP_IGET_OBJECT_JUMBO.S */ 7920/* File: armv5te/OP_IGET_JUMBO.S */ 7921 /* 7922 * Jumbo 32-bit instance field get. 7923 * 7924 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7925 * iget-char/jumbo, iget-short/jumbo 7926 */ 7927 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 7928 FETCH(r1, 1) @ r1<- aaaa (lo) 7929 FETCH(r2, 2) @ r2<- AAAA (hi) 7930 FETCH(r0, 4) @ r0<- CCCC 7931 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7932 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7933 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7934 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7935 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7936 cmp r0, #0 @ is resolved entry null? 7937 bne .LOP_IGET_OBJECT_JUMBO_finish @ no, already resolved 79388: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7939 EXPORT_PC() @ resolve() could throw 7940 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7941 bl dvmResolveInstField @ r0<- resolved InstField ptr 7942 b .LOP_IGET_OBJECT_JUMBO_resolved @ resolved, continue 7943 7944 7945/* ------------------------------ */ 7946 .balign 64 7947.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */ 7948/* File: armv5te/OP_IGET_BOOLEAN_JUMBO.S */ 7949@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrb", "sqnum":"1" } 7950/* File: armv5te/OP_IGET_JUMBO.S */ 7951 /* 7952 * Jumbo 32-bit instance field get. 7953 * 7954 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7955 * iget-char/jumbo, iget-short/jumbo 7956 */ 7957 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 7958 FETCH(r1, 1) @ r1<- aaaa (lo) 7959 FETCH(r2, 2) @ r2<- AAAA (hi) 7960 FETCH(r0, 4) @ r0<- CCCC 7961 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7962 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7963 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7964 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7965 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7966 cmp r0, #0 @ is resolved entry null? 7967 bne .LOP_IGET_BOOLEAN_JUMBO_finish @ no, already resolved 79688: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7969 EXPORT_PC() @ resolve() could throw 7970 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7971 bl dvmResolveInstField @ r0<- resolved InstField ptr 7972 b .LOP_IGET_BOOLEAN_JUMBO_resolved @ resolved, continue 7973 7974 7975/* ------------------------------ */ 7976 .balign 64 7977.L_OP_IGET_BYTE_JUMBO: /* 0x10a */ 7978/* File: armv5te/OP_IGET_BYTE_JUMBO.S */ 7979@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsb", "sqnum":"2" } 7980/* File: armv5te/OP_IGET_JUMBO.S */ 7981 /* 7982 * Jumbo 32-bit instance field get. 7983 * 7984 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7985 * iget-char/jumbo, iget-short/jumbo 7986 */ 7987 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 7988 FETCH(r1, 1) @ r1<- aaaa (lo) 7989 FETCH(r2, 2) @ r2<- AAAA (hi) 7990 FETCH(r0, 4) @ r0<- CCCC 7991 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 7992 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7993 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7994 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7995 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7996 cmp r0, #0 @ is resolved entry null? 7997 bne .LOP_IGET_BYTE_JUMBO_finish @ no, already resolved 79988: ldr r2, [rSELF, #offThread_method] @ r2<- current method 7999 EXPORT_PC() @ resolve() could throw 8000 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8001 bl dvmResolveInstField @ r0<- resolved InstField ptr 8002 b .LOP_IGET_BYTE_JUMBO_resolved @ resolved, continue 8003 8004 8005/* ------------------------------ */ 8006 .balign 64 8007.L_OP_IGET_CHAR_JUMBO: /* 0x10b */ 8008/* File: armv5te/OP_IGET_CHAR_JUMBO.S */ 8009@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrh", "sqnum":"3" } 8010/* File: armv5te/OP_IGET_JUMBO.S */ 8011 /* 8012 * Jumbo 32-bit instance field get. 8013 * 8014 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8015 * iget-char/jumbo, iget-short/jumbo 8016 */ 8017 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8018 FETCH(r1, 1) @ r1<- aaaa (lo) 8019 FETCH(r2, 2) @ r2<- AAAA (hi) 8020 FETCH(r0, 4) @ r0<- CCCC 8021 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 8022 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8023 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8024 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8025 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8026 cmp r0, #0 @ is resolved entry null? 8027 bne .LOP_IGET_CHAR_JUMBO_finish @ no, already resolved 80288: ldr r2, [rSELF, #offThread_method] @ r2<- current method 8029 EXPORT_PC() @ resolve() could throw 8030 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8031 bl dvmResolveInstField @ r0<- resolved InstField ptr 8032 b .LOP_IGET_CHAR_JUMBO_resolved @ resolved, continue 8033 8034 8035/* ------------------------------ */ 8036 .balign 64 8037.L_OP_IGET_SHORT_JUMBO: /* 0x10c */ 8038/* File: armv5te/OP_IGET_SHORT_JUMBO.S */ 8039@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsh", "sqnum":"4" } 8040/* File: armv5te/OP_IGET_JUMBO.S */ 8041 /* 8042 * Jumbo 32-bit instance field get. 8043 * 8044 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8045 * iget-char/jumbo, iget-short/jumbo 8046 */ 8047 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8048 FETCH(r1, 1) @ r1<- aaaa (lo) 8049 FETCH(r2, 2) @ r2<- AAAA (hi) 8050 FETCH(r0, 4) @ r0<- CCCC 8051 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 8052 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8053 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8054 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8055 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8056 cmp r0, #0 @ is resolved entry null? 8057 bne .LOP_IGET_SHORT_JUMBO_finish @ no, already resolved 80588: ldr r2, [rSELF, #offThread_method] @ r2<- current method 8059 EXPORT_PC() @ resolve() could throw 8060 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8061 bl dvmResolveInstField @ r0<- resolved InstField ptr 8062 b .LOP_IGET_SHORT_JUMBO_resolved @ resolved, continue 8063 8064 8065/* ------------------------------ */ 8066 .balign 64 8067.L_OP_IPUT_JUMBO: /* 0x10d */ 8068/* File: armv5te/OP_IPUT_JUMBO.S */ 8069 /* 8070 * Jumbo 32-bit instance field put. 8071 * 8072 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8073 * iput-short/jumbo 8074 */ 8075 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8076 FETCH(r1, 1) @ r1<- aaaa (lo) 8077 FETCH(r2, 2) @ r2<- AAAA (hi) 8078 FETCH(r0, 4) @ r0<- CCCC 8079 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 8080 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8081 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8082 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8083 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8084 cmp r0, #0 @ is resolved entry null? 8085 bne .LOP_IPUT_JUMBO_finish @ no, already resolved 80868: ldr r2, [rSELF, #offThread_method] @ r2<- current method 8087 EXPORT_PC() @ resolve() could throw 8088 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8089 bl dvmResolveInstField @ r0<- resolved InstField ptr 8090 b .LOP_IPUT_JUMBO_resolved @ resolved, continue 8091 8092/* ------------------------------ */ 8093 .balign 64 8094.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */ 8095/* File: armv5te/OP_IPUT_WIDE_JUMBO.S */ 8096 /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 8097 FETCH(r1, 1) @ r1<- aaaa (lo) 8098 FETCH(r2, 2) @ r2<- AAAA (hi) 8099 FETCH(r0, 4) @ r0<- CCCC 8100 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 8101 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8102 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 8103 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 8104 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8105 cmp r0, #0 @ is resolved entry null? 8106 bne .LOP_IPUT_WIDE_JUMBO_finish @ no, already resolved 81078: ldr r2, [rSELF, #offThread_method] @ r2<- current method 8108 EXPORT_PC() @ resolve() could throw 8109 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8110 bl dvmResolveInstField @ r0<- resolved InstField ptr 8111 b .LOP_IPUT_WIDE_JUMBO_resolved @ resolved, continue 8112 8113/* ------------------------------ */ 8114 .balign 64 8115.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */ 8116/* File: armv5te/OP_IPUT_OBJECT_JUMBO.S */ 8117 /* 8118 * Jumbo 32-bit instance field put. 8119 */ 8120 /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 8121 FETCH(r1, 1) @ r1<- aaaa (lo) 8122 FETCH(r2, 2) @ r2<- AAAA (hi) 8123 FETCH(r0, 4) @ r0<- CCCC 8124 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 8125 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8126 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8127 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8128 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8129 cmp r0, #0 @ is resolved entry null? 8130 bne .LOP_IPUT_OBJECT_JUMBO_finish @ no, already resolved 81318: ldr r2, [rSELF, #offThread_method] @ r2<- current method 8132 EXPORT_PC() @ resolve() could throw 8133 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8134 bl dvmResolveInstField @ r0<- resolved InstField ptr 8135 b .LOP_IPUT_OBJECT_JUMBO_resolved @ resolved, continue 8136 8137/* ------------------------------ */ 8138 .balign 64 8139.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */ 8140/* File: armv5te/OP_IPUT_BOOLEAN_JUMBO.S */ 8141@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"1" } 8142/* File: armv5te/OP_IPUT_JUMBO.S */ 8143 /* 8144 * Jumbo 32-bit instance field put. 8145 * 8146 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8147 * iput-short/jumbo 8148 */ 8149 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8150 FETCH(r1, 1) @ r1<- aaaa (lo) 8151 FETCH(r2, 2) @ r2<- AAAA (hi) 8152 FETCH(r0, 4) @ r0<- CCCC 8153 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 8154 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8155 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8156 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8157 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8158 cmp r0, #0 @ is resolved entry null? 8159 bne .LOP_IPUT_BOOLEAN_JUMBO_finish @ no, already resolved 81608: ldr r2, [rSELF, #offThread_method] @ r2<- current method 8161 EXPORT_PC() @ resolve() could throw 8162 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8163 bl dvmResolveInstField @ r0<- resolved InstField ptr 8164 b .LOP_IPUT_BOOLEAN_JUMBO_resolved @ resolved, continue 8165 8166 8167/* ------------------------------ */ 8168 .balign 64 8169.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */ 8170/* File: armv5te/OP_IPUT_BYTE_JUMBO.S */ 8171@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"2" } 8172/* File: armv5te/OP_IPUT_JUMBO.S */ 8173 /* 8174 * Jumbo 32-bit instance field put. 8175 * 8176 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8177 * iput-short/jumbo 8178 */ 8179 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8180 FETCH(r1, 1) @ r1<- aaaa (lo) 8181 FETCH(r2, 2) @ r2<- AAAA (hi) 8182 FETCH(r0, 4) @ r0<- CCCC 8183 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 8184 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8185 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8186 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8187 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8188 cmp r0, #0 @ is resolved entry null? 8189 bne .LOP_IPUT_BYTE_JUMBO_finish @ no, already resolved 81908: ldr r2, [rSELF, #offThread_method] @ r2<- current method 8191 EXPORT_PC() @ resolve() could throw 8192 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8193 bl dvmResolveInstField @ r0<- resolved InstField ptr 8194 b .LOP_IPUT_BYTE_JUMBO_resolved @ resolved, continue 8195 8196 8197/* ------------------------------ */ 8198 .balign 64 8199.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */ 8200/* File: armv5te/OP_IPUT_CHAR_JUMBO.S */ 8201@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"3" } 8202/* File: armv5te/OP_IPUT_JUMBO.S */ 8203 /* 8204 * Jumbo 32-bit instance field put. 8205 * 8206 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8207 * iput-short/jumbo 8208 */ 8209 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8210 FETCH(r1, 1) @ r1<- aaaa (lo) 8211 FETCH(r2, 2) @ r2<- AAAA (hi) 8212 FETCH(r0, 4) @ r0<- CCCC 8213 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 8214 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8215 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8216 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8217 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8218 cmp r0, #0 @ is resolved entry null? 8219 bne .LOP_IPUT_CHAR_JUMBO_finish @ no, already resolved 82208: ldr r2, [rSELF, #offThread_method] @ r2<- current method 8221 EXPORT_PC() @ resolve() could throw 8222 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8223 bl dvmResolveInstField @ r0<- resolved InstField ptr 8224 b .LOP_IPUT_CHAR_JUMBO_resolved @ resolved, continue 8225 8226 8227/* ------------------------------ */ 8228 .balign 64 8229.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */ 8230/* File: armv5te/OP_IPUT_SHORT_JUMBO.S */ 8231@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"4" } 8232/* File: armv5te/OP_IPUT_JUMBO.S */ 8233 /* 8234 * Jumbo 32-bit instance field put. 8235 * 8236 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8237 * iput-short/jumbo 8238 */ 8239 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8240 FETCH(r1, 1) @ r1<- aaaa (lo) 8241 FETCH(r2, 2) @ r2<- AAAA (hi) 8242 FETCH(r0, 4) @ r0<- CCCC 8243 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- DvmDex 8244 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8245 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8246 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8247 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8248 cmp r0, #0 @ is resolved entry null? 8249 bne .LOP_IPUT_SHORT_JUMBO_finish @ no, already resolved 82508: ldr r2, [rSELF, #offThread_method] @ r2<- current method 8251 EXPORT_PC() @ resolve() could throw 8252 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8253 bl dvmResolveInstField @ r0<- resolved InstField ptr 8254 b .LOP_IPUT_SHORT_JUMBO_resolved @ resolved, continue 8255 8256 8257/* ------------------------------ */ 8258 .balign 64 8259.L_OP_SGET_JUMBO: /* 0x114 */ 8260/* File: armv5te/OP_SGET_JUMBO.S */ 8261 /* 8262 * Jumbo 32-bit SGET handler. 8263 * 8264 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8265 * sget-char/jumbo, sget-short/jumbo 8266 */ 8267 /* exop vBBBB, field@AAAAAAAA */ 8268 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8269 FETCH(r0, 1) @ r0<- aaaa (lo) 8270 FETCH(r1, 2) @ r1<- AAAA (hi) 8271 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8272 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8273 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8274 cmp r0, #0 @ is resolved entry null? 8275 beq .LOP_SGET_JUMBO_resolve @ yes, do resolve 8276.LOP_SGET_JUMBO_finish: @ field ptr in r0 8277 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8278 @ no-op @ acquiring load 8279 FETCH(r2, 3) @ r2<- BBBB 8280 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8281 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8282 GET_INST_OPCODE(ip) @ extract opcode from rINST 8283 GOTO_OPCODE(ip) @ jump to next instruction 8284 8285/* ------------------------------ */ 8286 .balign 64 8287.L_OP_SGET_WIDE_JUMBO: /* 0x115 */ 8288/* File: armv5te/OP_SGET_WIDE_JUMBO.S */ 8289 /* 8290 * Jumbo 64-bit SGET handler. 8291 */ 8292 /* sget-wide/jumbo vBBBB, field@AAAAAAAA */ 8293 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8294 FETCH(r0, 1) @ r0<- aaaa (lo) 8295 FETCH(r1, 2) @ r1<- AAAA (hi) 8296 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8297 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8298 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8299 cmp r0, #0 @ is resolved entry null? 8300 beq .LOP_SGET_WIDE_JUMBO_resolve @ yes, do resolve 8301.LOP_SGET_WIDE_JUMBO_finish: 8302 FETCH(r9, 3) @ r9<- BBBB 8303 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 8304 add r9, rFP, r9, lsl #2 @ r9<- &fp[BBBB] 8305 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8306 stmia r9, {r0-r1} @ vBBBB/vBBBB+1<- r0/r1 8307 GET_INST_OPCODE(ip) @ extract opcode from rINST 8308 GOTO_OPCODE(ip) @ jump to next instruction 8309 8310/* ------------------------------ */ 8311 .balign 64 8312.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */ 8313/* File: armv5te/OP_SGET_OBJECT_JUMBO.S */ 8314/* File: armv5te/OP_SGET_JUMBO.S */ 8315 /* 8316 * Jumbo 32-bit SGET handler. 8317 * 8318 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8319 * sget-char/jumbo, sget-short/jumbo 8320 */ 8321 /* exop vBBBB, field@AAAAAAAA */ 8322 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8323 FETCH(r0, 1) @ r0<- aaaa (lo) 8324 FETCH(r1, 2) @ r1<- AAAA (hi) 8325 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8326 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8327 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8328 cmp r0, #0 @ is resolved entry null? 8329 beq .LOP_SGET_OBJECT_JUMBO_resolve @ yes, do resolve 8330.LOP_SGET_OBJECT_JUMBO_finish: @ field ptr in r0 8331 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8332 @ no-op @ acquiring load 8333 FETCH(r2, 3) @ r2<- BBBB 8334 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8335 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8336 GET_INST_OPCODE(ip) @ extract opcode from rINST 8337 GOTO_OPCODE(ip) @ jump to next instruction 8338 8339 8340/* ------------------------------ */ 8341 .balign 64 8342.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */ 8343/* File: armv5te/OP_SGET_BOOLEAN_JUMBO.S */ 8344/* File: armv5te/OP_SGET_JUMBO.S */ 8345 /* 8346 * Jumbo 32-bit SGET handler. 8347 * 8348 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8349 * sget-char/jumbo, sget-short/jumbo 8350 */ 8351 /* exop vBBBB, field@AAAAAAAA */ 8352 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8353 FETCH(r0, 1) @ r0<- aaaa (lo) 8354 FETCH(r1, 2) @ r1<- AAAA (hi) 8355 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8356 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8357 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8358 cmp r0, #0 @ is resolved entry null? 8359 beq .LOP_SGET_BOOLEAN_JUMBO_resolve @ yes, do resolve 8360.LOP_SGET_BOOLEAN_JUMBO_finish: @ field ptr in r0 8361 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8362 @ no-op @ acquiring load 8363 FETCH(r2, 3) @ r2<- BBBB 8364 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8365 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8366 GET_INST_OPCODE(ip) @ extract opcode from rINST 8367 GOTO_OPCODE(ip) @ jump to next instruction 8368 8369 8370/* ------------------------------ */ 8371 .balign 64 8372.L_OP_SGET_BYTE_JUMBO: /* 0x118 */ 8373/* File: armv5te/OP_SGET_BYTE_JUMBO.S */ 8374/* File: armv5te/OP_SGET_JUMBO.S */ 8375 /* 8376 * Jumbo 32-bit SGET handler. 8377 * 8378 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8379 * sget-char/jumbo, sget-short/jumbo 8380 */ 8381 /* exop vBBBB, field@AAAAAAAA */ 8382 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8383 FETCH(r0, 1) @ r0<- aaaa (lo) 8384 FETCH(r1, 2) @ r1<- AAAA (hi) 8385 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8386 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8387 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8388 cmp r0, #0 @ is resolved entry null? 8389 beq .LOP_SGET_BYTE_JUMBO_resolve @ yes, do resolve 8390.LOP_SGET_BYTE_JUMBO_finish: @ field ptr in r0 8391 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8392 @ no-op @ acquiring load 8393 FETCH(r2, 3) @ r2<- BBBB 8394 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8395 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8396 GET_INST_OPCODE(ip) @ extract opcode from rINST 8397 GOTO_OPCODE(ip) @ jump to next instruction 8398 8399 8400/* ------------------------------ */ 8401 .balign 64 8402.L_OP_SGET_CHAR_JUMBO: /* 0x119 */ 8403/* File: armv5te/OP_SGET_CHAR_JUMBO.S */ 8404/* File: armv5te/OP_SGET_JUMBO.S */ 8405 /* 8406 * Jumbo 32-bit SGET handler. 8407 * 8408 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8409 * sget-char/jumbo, sget-short/jumbo 8410 */ 8411 /* exop vBBBB, field@AAAAAAAA */ 8412 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8413 FETCH(r0, 1) @ r0<- aaaa (lo) 8414 FETCH(r1, 2) @ r1<- AAAA (hi) 8415 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8416 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8417 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8418 cmp r0, #0 @ is resolved entry null? 8419 beq .LOP_SGET_CHAR_JUMBO_resolve @ yes, do resolve 8420.LOP_SGET_CHAR_JUMBO_finish: @ field ptr in r0 8421 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8422 @ no-op @ acquiring load 8423 FETCH(r2, 3) @ r2<- BBBB 8424 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8425 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8426 GET_INST_OPCODE(ip) @ extract opcode from rINST 8427 GOTO_OPCODE(ip) @ jump to next instruction 8428 8429 8430/* ------------------------------ */ 8431 .balign 64 8432.L_OP_SGET_SHORT_JUMBO: /* 0x11a */ 8433/* File: armv5te/OP_SGET_SHORT_JUMBO.S */ 8434/* File: armv5te/OP_SGET_JUMBO.S */ 8435 /* 8436 * Jumbo 32-bit SGET handler. 8437 * 8438 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8439 * sget-char/jumbo, sget-short/jumbo 8440 */ 8441 /* exop vBBBB, field@AAAAAAAA */ 8442 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8443 FETCH(r0, 1) @ r0<- aaaa (lo) 8444 FETCH(r1, 2) @ r1<- AAAA (hi) 8445 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8446 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8447 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8448 cmp r0, #0 @ is resolved entry null? 8449 beq .LOP_SGET_SHORT_JUMBO_resolve @ yes, do resolve 8450.LOP_SGET_SHORT_JUMBO_finish: @ field ptr in r0 8451 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8452 @ no-op @ acquiring load 8453 FETCH(r2, 3) @ r2<- BBBB 8454 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8455 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8456 GET_INST_OPCODE(ip) @ extract opcode from rINST 8457 GOTO_OPCODE(ip) @ jump to next instruction 8458 8459 8460/* ------------------------------ */ 8461 .balign 64 8462.L_OP_SPUT_JUMBO: /* 0x11b */ 8463/* File: armv5te/OP_SPUT_JUMBO.S */ 8464 /* 8465 * Jumbo 32-bit SPUT handler. 8466 * 8467 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8468 * sput-short/jumbo 8469 */ 8470 /* exop vBBBB, field@AAAAAAAA */ 8471 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8472 FETCH(r0, 1) @ r0<- aaaa (lo) 8473 FETCH(r1, 2) @ r1<- AAAA (hi) 8474 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8475 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8476 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8477 cmp r0, #0 @ is resolved entry null? 8478 beq .LOP_SPUT_JUMBO_resolve @ yes, do resolve 8479.LOP_SPUT_JUMBO_finish: @ field ptr in r0 8480 FETCH(r2, 3) @ r2<- BBBB 8481 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8482 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8483 GET_INST_OPCODE(ip) @ extract opcode from rINST 8484 @ no-op @ releasing store 8485 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8486 GOTO_OPCODE(ip) @ jump to next instruction 8487 8488/* ------------------------------ */ 8489 .balign 64 8490.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */ 8491/* File: armv5te/OP_SPUT_WIDE_JUMBO.S */ 8492 /* 8493 * Jumbo 64-bit SPUT handler. 8494 */ 8495 /* sput-wide/jumbo vBBBB, field@AAAAAAAA */ 8496 ldr r0, [rSELF, #offThread_methodClassDex] @ r0<- DvmDex 8497 FETCH(r1, 1) @ r1<- aaaa (lo) 8498 FETCH(r2, 2) @ r2<- AAAA (hi) 8499 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 8500 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8501 FETCH(r9, 3) @ r9<- BBBB 8502 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 8503 add r9, rFP, r9, lsl #2 @ r9<- &fp[BBBB] 8504 cmp r2, #0 @ is resolved entry null? 8505 beq .LOP_SPUT_WIDE_JUMBO_resolve @ yes, do resolve 8506.LOP_SPUT_WIDE_JUMBO_finish: @ field ptr in r2, BBBB in r9 8507 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8508 ldmia r9, {r0-r1} @ r0/r1<- vBBBB/vBBBB+1 8509 GET_INST_OPCODE(r10) @ extract opcode from rINST 8510 strd r0, [r2, #offStaticField_value] @ field<- vBBBB/vBBBB+1 8511 GOTO_OPCODE(r10) @ jump to next instruction 8512 8513/* ------------------------------ */ 8514 .balign 64 8515.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */ 8516/* File: armv5te/OP_SPUT_OBJECT_JUMBO.S */ 8517 /* 8518 * Jumbo 32-bit SPUT handler for objects 8519 */ 8520 /* sput-object/jumbo vBBBB, field@AAAAAAAA */ 8521 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8522 FETCH(r0, 1) @ r0<- aaaa (lo) 8523 FETCH(r1, 2) @ r1<- AAAA (hi) 8524 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8525 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8526 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8527 cmp r0, #0 @ is resolved entry null? 8528 bne .LOP_SPUT_OBJECT_JUMBO_finish @ no, continue 8529 ldr r9, [rSELF, #offThread_method] @ r9<- current method 8530 EXPORT_PC() @ resolve() could throw, so export now 8531 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 8532 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8533 cmp r0, #0 @ success? 8534 bne .LOP_SPUT_OBJECT_JUMBO_finish @ yes, finish 8535 b common_exceptionThrown @ no, handle exception 8536 8537/* ------------------------------ */ 8538 .balign 64 8539.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */ 8540/* File: armv5te/OP_SPUT_BOOLEAN_JUMBO.S */ 8541/* File: armv5te/OP_SPUT_JUMBO.S */ 8542 /* 8543 * Jumbo 32-bit SPUT handler. 8544 * 8545 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8546 * sput-short/jumbo 8547 */ 8548 /* exop vBBBB, field@AAAAAAAA */ 8549 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8550 FETCH(r0, 1) @ r0<- aaaa (lo) 8551 FETCH(r1, 2) @ r1<- AAAA (hi) 8552 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8553 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8554 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8555 cmp r0, #0 @ is resolved entry null? 8556 beq .LOP_SPUT_BOOLEAN_JUMBO_resolve @ yes, do resolve 8557.LOP_SPUT_BOOLEAN_JUMBO_finish: @ field ptr in r0 8558 FETCH(r2, 3) @ r2<- BBBB 8559 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8560 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8561 GET_INST_OPCODE(ip) @ extract opcode from rINST 8562 @ no-op @ releasing store 8563 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8564 GOTO_OPCODE(ip) @ jump to next instruction 8565 8566 8567/* ------------------------------ */ 8568 .balign 64 8569.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */ 8570/* File: armv5te/OP_SPUT_BYTE_JUMBO.S */ 8571/* File: armv5te/OP_SPUT_JUMBO.S */ 8572 /* 8573 * Jumbo 32-bit SPUT handler. 8574 * 8575 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8576 * sput-short/jumbo 8577 */ 8578 /* exop vBBBB, field@AAAAAAAA */ 8579 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8580 FETCH(r0, 1) @ r0<- aaaa (lo) 8581 FETCH(r1, 2) @ r1<- AAAA (hi) 8582 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8583 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8584 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8585 cmp r0, #0 @ is resolved entry null? 8586 beq .LOP_SPUT_BYTE_JUMBO_resolve @ yes, do resolve 8587.LOP_SPUT_BYTE_JUMBO_finish: @ field ptr in r0 8588 FETCH(r2, 3) @ r2<- BBBB 8589 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8590 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8591 GET_INST_OPCODE(ip) @ extract opcode from rINST 8592 @ no-op @ releasing store 8593 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8594 GOTO_OPCODE(ip) @ jump to next instruction 8595 8596 8597/* ------------------------------ */ 8598 .balign 64 8599.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */ 8600/* File: armv5te/OP_SPUT_CHAR_JUMBO.S */ 8601/* File: armv5te/OP_SPUT_JUMBO.S */ 8602 /* 8603 * Jumbo 32-bit SPUT handler. 8604 * 8605 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8606 * sput-short/jumbo 8607 */ 8608 /* exop vBBBB, field@AAAAAAAA */ 8609 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8610 FETCH(r0, 1) @ r0<- aaaa (lo) 8611 FETCH(r1, 2) @ r1<- AAAA (hi) 8612 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8613 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8614 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8615 cmp r0, #0 @ is resolved entry null? 8616 beq .LOP_SPUT_CHAR_JUMBO_resolve @ yes, do resolve 8617.LOP_SPUT_CHAR_JUMBO_finish: @ field ptr in r0 8618 FETCH(r2, 3) @ r2<- BBBB 8619 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8620 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8621 GET_INST_OPCODE(ip) @ extract opcode from rINST 8622 @ no-op @ releasing store 8623 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8624 GOTO_OPCODE(ip) @ jump to next instruction 8625 8626 8627/* ------------------------------ */ 8628 .balign 64 8629.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */ 8630/* File: armv5te/OP_SPUT_SHORT_JUMBO.S */ 8631/* File: armv5te/OP_SPUT_JUMBO.S */ 8632 /* 8633 * Jumbo 32-bit SPUT handler. 8634 * 8635 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8636 * sput-short/jumbo 8637 */ 8638 /* exop vBBBB, field@AAAAAAAA */ 8639 ldr r2, [rSELF, #offThread_methodClassDex] @ r2<- DvmDex 8640 FETCH(r0, 1) @ r0<- aaaa (lo) 8641 FETCH(r1, 2) @ r1<- AAAA (hi) 8642 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8643 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8644 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8645 cmp r0, #0 @ is resolved entry null? 8646 beq .LOP_SPUT_SHORT_JUMBO_resolve @ yes, do resolve 8647.LOP_SPUT_SHORT_JUMBO_finish: @ field ptr in r0 8648 FETCH(r2, 3) @ r2<- BBBB 8649 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8650 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8651 GET_INST_OPCODE(ip) @ extract opcode from rINST 8652 @ no-op @ releasing store 8653 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8654 GOTO_OPCODE(ip) @ jump to next instruction 8655 8656 8657/* ------------------------------ */ 8658 .balign 64 8659.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */ 8660/* File: armv5te/OP_INVOKE_VIRTUAL_JUMBO.S */ 8661 /* 8662 * Handle a virtual method call. 8663 */ 8664 /* invoke-virtual/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8665 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 8666 FETCH(r0, 1) @ r1<- aaaa (lo) 8667 FETCH(r1, 2) @ r1<- AAAA (hi) 8668 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8669 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8670 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 8671 cmp r0, #0 @ already resolved? 8672 EXPORT_PC() @ must export for invoke 8673 bne .LOP_INVOKE_VIRTUAL_JUMBO_continue @ yes, continue on 8674 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 8675 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8676 mov r2, #METHOD_VIRTUAL @ resolver method type 8677 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8678 cmp r0, #0 @ got null? 8679 bne .LOP_INVOKE_VIRTUAL_JUMBO_continue @ no, continue 8680 b common_exceptionThrown @ yes, handle exception 8681 8682/* ------------------------------ */ 8683 .balign 64 8684.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */ 8685/* File: armv5te/OP_INVOKE_SUPER_JUMBO.S */ 8686 /* 8687 * Handle a "super" method call. 8688 */ 8689 /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8690 FETCH(r10, 4) @ r10<- CCCC 8691 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 8692 FETCH(r0, 1) @ r1<- aaaa (lo) 8693 FETCH(r1, 2) @ r1<- AAAA (hi) 8694 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8695 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8696 GET_VREG(r2, r10) @ r2<- "this" ptr 8697 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 8698 cmp r2, #0 @ null "this"? 8699 ldr r9, [rSELF, #offThread_method] @ r9<- current method 8700 beq common_errNullObject @ null "this", throw exception 8701 cmp r0, #0 @ already resolved? 8702 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 8703 EXPORT_PC() @ must export for invoke 8704 bne .LOP_INVOKE_SUPER_JUMBO_continue @ resolved, continue on 8705 b .LOP_INVOKE_SUPER_JUMBO_resolve @ do resolve now 8706 8707/* ------------------------------ */ 8708 .balign 64 8709.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */ 8710/* File: armv5te/OP_INVOKE_DIRECT_JUMBO.S */ 8711 /* 8712 * Handle a direct method call. 8713 * 8714 * (We could defer the "is 'this' pointer null" test to the common 8715 * method invocation code, and use a flag to indicate that static 8716 * calls don't count. If we do this as part of copying the arguments 8717 * out we could avoiding loading the first arg twice.) 8718 * 8719 */ 8720 /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8721 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 8722 FETCH(r0, 1) @ r1<- aaaa (lo) 8723 FETCH(r1, 2) @ r1<- AAAA (hi) 8724 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8725 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8726 FETCH(r10, 4) @ r10<- CCCC 8727 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 8728 cmp r0, #0 @ already resolved? 8729 EXPORT_PC() @ must export for invoke 8730 GET_VREG(r2, r10) @ r2<- "this" ptr 8731 beq .LOP_INVOKE_DIRECT_JUMBO_resolve @ not resolved, do it now 8732.LOP_INVOKE_DIRECT_JUMBO_finish: 8733 cmp r2, #0 @ null "this" ref? 8734 bne common_invokeMethodJumbo @ no, continue on 8735 b common_errNullObject @ yes, throw exception 8736 8737/* ------------------------------ */ 8738 .balign 64 8739.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */ 8740/* File: armv5te/OP_INVOKE_STATIC_JUMBO.S */ 8741 /* 8742 * Handle a static method call. 8743 */ 8744 /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8745 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 8746 FETCH(r0, 1) @ r1<- aaaa (lo) 8747 FETCH(r1, 2) @ r1<- AAAA (hi) 8748 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8749 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8750 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 8751 cmp r0, #0 @ already resolved? 8752 EXPORT_PC() @ must export for invoke 8753 bne common_invokeMethodJumbo @ yes, continue on 87540: ldr r3, [rSELF, #offThread_method] @ r3<- self->method 8755 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8756 mov r2, #METHOD_STATIC @ resolver method type 8757 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8758 cmp r0, #0 @ got null? 8759 bne common_invokeMethodJumbo @ no, continue 8760 b common_exceptionThrown @ yes, handle exception 8761 8762/* ------------------------------ */ 8763 .balign 64 8764.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */ 8765/* File: armv5te/OP_INVOKE_INTERFACE_JUMBO.S */ 8766 /* 8767 * Handle an interface method call. 8768 */ 8769 /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8770 FETCH(r2, 4) @ r2<- CCCC 8771 FETCH(r0, 1) @ r0<- aaaa (lo) 8772 FETCH(r1, 2) @ r1<- AAAA (hi) 8773 EXPORT_PC() @ must export for invoke 8774 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8775 GET_VREG(r0, r2) @ r0<- first arg ("this") 8776 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- methodClassDex 8777 cmp r0, #0 @ null obj? 8778 ldr r2, [rSELF, #offThread_method] @ r2<- method 8779 beq common_errNullObject @ yes, fail 8780 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 8781 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 8782 cmp r0, #0 @ failed? 8783 beq common_exceptionThrown @ yes, handle exception 8784 b common_invokeMethodJumbo @ jump to common handler 8785 8786/* ------------------------------ */ 8787 .balign 64 8788.L_OP_UNUSED_27FF: /* 0x127 */ 8789/* File: armv5te/OP_UNUSED_27FF.S */ 8790/* File: armv5te/unused.S */ 8791 bl common_abort 8792 8793 8794/* ------------------------------ */ 8795 .balign 64 8796.L_OP_UNUSED_28FF: /* 0x128 */ 8797/* File: armv5te/OP_UNUSED_28FF.S */ 8798/* File: armv5te/unused.S */ 8799 bl common_abort 8800 8801 8802/* ------------------------------ */ 8803 .balign 64 8804.L_OP_UNUSED_29FF: /* 0x129 */ 8805/* File: armv5te/OP_UNUSED_29FF.S */ 8806/* File: armv5te/unused.S */ 8807 bl common_abort 8808 8809 8810/* ------------------------------ */ 8811 .balign 64 8812.L_OP_UNUSED_2AFF: /* 0x12a */ 8813/* File: armv5te/OP_UNUSED_2AFF.S */ 8814/* File: armv5te/unused.S */ 8815 bl common_abort 8816 8817 8818/* ------------------------------ */ 8819 .balign 64 8820.L_OP_UNUSED_2BFF: /* 0x12b */ 8821/* File: armv5te/OP_UNUSED_2BFF.S */ 8822/* File: armv5te/unused.S */ 8823 bl common_abort 8824 8825 8826/* ------------------------------ */ 8827 .balign 64 8828.L_OP_UNUSED_2CFF: /* 0x12c */ 8829/* File: armv5te/OP_UNUSED_2CFF.S */ 8830/* File: armv5te/unused.S */ 8831 bl common_abort 8832 8833 8834/* ------------------------------ */ 8835 .balign 64 8836.L_OP_UNUSED_2DFF: /* 0x12d */ 8837/* File: armv5te/OP_UNUSED_2DFF.S */ 8838/* File: armv5te/unused.S */ 8839 bl common_abort 8840 8841 8842/* ------------------------------ */ 8843 .balign 64 8844.L_OP_UNUSED_2EFF: /* 0x12e */ 8845/* File: armv5te/OP_UNUSED_2EFF.S */ 8846/* File: armv5te/unused.S */ 8847 bl common_abort 8848 8849 8850/* ------------------------------ */ 8851 .balign 64 8852.L_OP_UNUSED_2FFF: /* 0x12f */ 8853/* File: armv5te/OP_UNUSED_2FFF.S */ 8854/* File: armv5te/unused.S */ 8855 bl common_abort 8856 8857 8858/* ------------------------------ */ 8859 .balign 64 8860.L_OP_UNUSED_30FF: /* 0x130 */ 8861/* File: armv5te/OP_UNUSED_30FF.S */ 8862/* File: armv5te/unused.S */ 8863 bl common_abort 8864 8865 8866/* ------------------------------ */ 8867 .balign 64 8868.L_OP_UNUSED_31FF: /* 0x131 */ 8869/* File: armv5te/OP_UNUSED_31FF.S */ 8870/* File: armv5te/unused.S */ 8871 bl common_abort 8872 8873 8874/* ------------------------------ */ 8875 .balign 64 8876.L_OP_UNUSED_32FF: /* 0x132 */ 8877/* File: armv5te/OP_UNUSED_32FF.S */ 8878/* File: armv5te/unused.S */ 8879 bl common_abort 8880 8881 8882/* ------------------------------ */ 8883 .balign 64 8884.L_OP_UNUSED_33FF: /* 0x133 */ 8885/* File: armv5te/OP_UNUSED_33FF.S */ 8886/* File: armv5te/unused.S */ 8887 bl common_abort 8888 8889 8890/* ------------------------------ */ 8891 .balign 64 8892.L_OP_UNUSED_34FF: /* 0x134 */ 8893/* File: armv5te/OP_UNUSED_34FF.S */ 8894/* File: armv5te/unused.S */ 8895 bl common_abort 8896 8897 8898/* ------------------------------ */ 8899 .balign 64 8900.L_OP_UNUSED_35FF: /* 0x135 */ 8901/* File: armv5te/OP_UNUSED_35FF.S */ 8902/* File: armv5te/unused.S */ 8903 bl common_abort 8904 8905 8906/* ------------------------------ */ 8907 .balign 64 8908.L_OP_UNUSED_36FF: /* 0x136 */ 8909/* File: armv5te/OP_UNUSED_36FF.S */ 8910/* File: armv5te/unused.S */ 8911 bl common_abort 8912 8913 8914/* ------------------------------ */ 8915 .balign 64 8916.L_OP_UNUSED_37FF: /* 0x137 */ 8917/* File: armv5te/OP_UNUSED_37FF.S */ 8918/* File: armv5te/unused.S */ 8919 bl common_abort 8920 8921 8922/* ------------------------------ */ 8923 .balign 64 8924.L_OP_UNUSED_38FF: /* 0x138 */ 8925/* File: armv5te/OP_UNUSED_38FF.S */ 8926/* File: armv5te/unused.S */ 8927 bl common_abort 8928 8929 8930/* ------------------------------ */ 8931 .balign 64 8932.L_OP_UNUSED_39FF: /* 0x139 */ 8933/* File: armv5te/OP_UNUSED_39FF.S */ 8934/* File: armv5te/unused.S */ 8935 bl common_abort 8936 8937 8938/* ------------------------------ */ 8939 .balign 64 8940.L_OP_UNUSED_3AFF: /* 0x13a */ 8941/* File: armv5te/OP_UNUSED_3AFF.S */ 8942/* File: armv5te/unused.S */ 8943 bl common_abort 8944 8945 8946/* ------------------------------ */ 8947 .balign 64 8948.L_OP_UNUSED_3BFF: /* 0x13b */ 8949/* File: armv5te/OP_UNUSED_3BFF.S */ 8950/* File: armv5te/unused.S */ 8951 bl common_abort 8952 8953 8954/* ------------------------------ */ 8955 .balign 64 8956.L_OP_UNUSED_3CFF: /* 0x13c */ 8957/* File: armv5te/OP_UNUSED_3CFF.S */ 8958/* File: armv5te/unused.S */ 8959 bl common_abort 8960 8961 8962/* ------------------------------ */ 8963 .balign 64 8964.L_OP_UNUSED_3DFF: /* 0x13d */ 8965/* File: armv5te/OP_UNUSED_3DFF.S */ 8966/* File: armv5te/unused.S */ 8967 bl common_abort 8968 8969 8970/* ------------------------------ */ 8971 .balign 64 8972.L_OP_UNUSED_3EFF: /* 0x13e */ 8973/* File: armv5te/OP_UNUSED_3EFF.S */ 8974/* File: armv5te/unused.S */ 8975 bl common_abort 8976 8977 8978/* ------------------------------ */ 8979 .balign 64 8980.L_OP_UNUSED_3FFF: /* 0x13f */ 8981/* File: armv5te/OP_UNUSED_3FFF.S */ 8982/* File: armv5te/unused.S */ 8983 bl common_abort 8984 8985 8986/* ------------------------------ */ 8987 .balign 64 8988.L_OP_UNUSED_40FF: /* 0x140 */ 8989/* File: armv5te/OP_UNUSED_40FF.S */ 8990/* File: armv5te/unused.S */ 8991 bl common_abort 8992 8993 8994/* ------------------------------ */ 8995 .balign 64 8996.L_OP_UNUSED_41FF: /* 0x141 */ 8997/* File: armv5te/OP_UNUSED_41FF.S */ 8998/* File: armv5te/unused.S */ 8999 bl common_abort 9000 9001 9002/* ------------------------------ */ 9003 .balign 64 9004.L_OP_UNUSED_42FF: /* 0x142 */ 9005/* File: armv5te/OP_UNUSED_42FF.S */ 9006/* File: armv5te/unused.S */ 9007 bl common_abort 9008 9009 9010/* ------------------------------ */ 9011 .balign 64 9012.L_OP_UNUSED_43FF: /* 0x143 */ 9013/* File: armv5te/OP_UNUSED_43FF.S */ 9014/* File: armv5te/unused.S */ 9015 bl common_abort 9016 9017 9018/* ------------------------------ */ 9019 .balign 64 9020.L_OP_UNUSED_44FF: /* 0x144 */ 9021/* File: armv5te/OP_UNUSED_44FF.S */ 9022/* File: armv5te/unused.S */ 9023 bl common_abort 9024 9025 9026/* ------------------------------ */ 9027 .balign 64 9028.L_OP_UNUSED_45FF: /* 0x145 */ 9029/* File: armv5te/OP_UNUSED_45FF.S */ 9030/* File: armv5te/unused.S */ 9031 bl common_abort 9032 9033 9034/* ------------------------------ */ 9035 .balign 64 9036.L_OP_UNUSED_46FF: /* 0x146 */ 9037/* File: armv5te/OP_UNUSED_46FF.S */ 9038/* File: armv5te/unused.S */ 9039 bl common_abort 9040 9041 9042/* ------------------------------ */ 9043 .balign 64 9044.L_OP_UNUSED_47FF: /* 0x147 */ 9045/* File: armv5te/OP_UNUSED_47FF.S */ 9046/* File: armv5te/unused.S */ 9047 bl common_abort 9048 9049 9050/* ------------------------------ */ 9051 .balign 64 9052.L_OP_UNUSED_48FF: /* 0x148 */ 9053/* File: armv5te/OP_UNUSED_48FF.S */ 9054/* File: armv5te/unused.S */ 9055 bl common_abort 9056 9057 9058/* ------------------------------ */ 9059 .balign 64 9060.L_OP_UNUSED_49FF: /* 0x149 */ 9061/* File: armv5te/OP_UNUSED_49FF.S */ 9062/* File: armv5te/unused.S */ 9063 bl common_abort 9064 9065 9066/* ------------------------------ */ 9067 .balign 64 9068.L_OP_UNUSED_4AFF: /* 0x14a */ 9069/* File: armv5te/OP_UNUSED_4AFF.S */ 9070/* File: armv5te/unused.S */ 9071 bl common_abort 9072 9073 9074/* ------------------------------ */ 9075 .balign 64 9076.L_OP_UNUSED_4BFF: /* 0x14b */ 9077/* File: armv5te/OP_UNUSED_4BFF.S */ 9078/* File: armv5te/unused.S */ 9079 bl common_abort 9080 9081 9082/* ------------------------------ */ 9083 .balign 64 9084.L_OP_UNUSED_4CFF: /* 0x14c */ 9085/* File: armv5te/OP_UNUSED_4CFF.S */ 9086/* File: armv5te/unused.S */ 9087 bl common_abort 9088 9089 9090/* ------------------------------ */ 9091 .balign 64 9092.L_OP_UNUSED_4DFF: /* 0x14d */ 9093/* File: armv5te/OP_UNUSED_4DFF.S */ 9094/* File: armv5te/unused.S */ 9095 bl common_abort 9096 9097 9098/* ------------------------------ */ 9099 .balign 64 9100.L_OP_UNUSED_4EFF: /* 0x14e */ 9101/* File: armv5te/OP_UNUSED_4EFF.S */ 9102/* File: armv5te/unused.S */ 9103 bl common_abort 9104 9105 9106/* ------------------------------ */ 9107 .balign 64 9108.L_OP_UNUSED_4FFF: /* 0x14f */ 9109/* File: armv5te/OP_UNUSED_4FFF.S */ 9110/* File: armv5te/unused.S */ 9111 bl common_abort 9112 9113 9114/* ------------------------------ */ 9115 .balign 64 9116.L_OP_UNUSED_50FF: /* 0x150 */ 9117/* File: armv5te/OP_UNUSED_50FF.S */ 9118/* File: armv5te/unused.S */ 9119 bl common_abort 9120 9121 9122/* ------------------------------ */ 9123 .balign 64 9124.L_OP_UNUSED_51FF: /* 0x151 */ 9125/* File: armv5te/OP_UNUSED_51FF.S */ 9126/* File: armv5te/unused.S */ 9127 bl common_abort 9128 9129 9130/* ------------------------------ */ 9131 .balign 64 9132.L_OP_UNUSED_52FF: /* 0x152 */ 9133/* File: armv5te/OP_UNUSED_52FF.S */ 9134/* File: armv5te/unused.S */ 9135 bl common_abort 9136 9137 9138/* ------------------------------ */ 9139 .balign 64 9140.L_OP_UNUSED_53FF: /* 0x153 */ 9141/* File: armv5te/OP_UNUSED_53FF.S */ 9142/* File: armv5te/unused.S */ 9143 bl common_abort 9144 9145 9146/* ------------------------------ */ 9147 .balign 64 9148.L_OP_UNUSED_54FF: /* 0x154 */ 9149/* File: armv5te/OP_UNUSED_54FF.S */ 9150/* File: armv5te/unused.S */ 9151 bl common_abort 9152 9153 9154/* ------------------------------ */ 9155 .balign 64 9156.L_OP_UNUSED_55FF: /* 0x155 */ 9157/* File: armv5te/OP_UNUSED_55FF.S */ 9158/* File: armv5te/unused.S */ 9159 bl common_abort 9160 9161 9162/* ------------------------------ */ 9163 .balign 64 9164.L_OP_UNUSED_56FF: /* 0x156 */ 9165/* File: armv5te/OP_UNUSED_56FF.S */ 9166/* File: armv5te/unused.S */ 9167 bl common_abort 9168 9169 9170/* ------------------------------ */ 9171 .balign 64 9172.L_OP_UNUSED_57FF: /* 0x157 */ 9173/* File: armv5te/OP_UNUSED_57FF.S */ 9174/* File: armv5te/unused.S */ 9175 bl common_abort 9176 9177 9178/* ------------------------------ */ 9179 .balign 64 9180.L_OP_UNUSED_58FF: /* 0x158 */ 9181/* File: armv5te/OP_UNUSED_58FF.S */ 9182/* File: armv5te/unused.S */ 9183 bl common_abort 9184 9185 9186/* ------------------------------ */ 9187 .balign 64 9188.L_OP_UNUSED_59FF: /* 0x159 */ 9189/* File: armv5te/OP_UNUSED_59FF.S */ 9190/* File: armv5te/unused.S */ 9191 bl common_abort 9192 9193 9194/* ------------------------------ */ 9195 .balign 64 9196.L_OP_UNUSED_5AFF: /* 0x15a */ 9197/* File: armv5te/OP_UNUSED_5AFF.S */ 9198/* File: armv5te/unused.S */ 9199 bl common_abort 9200 9201 9202/* ------------------------------ */ 9203 .balign 64 9204.L_OP_UNUSED_5BFF: /* 0x15b */ 9205/* File: armv5te/OP_UNUSED_5BFF.S */ 9206/* File: armv5te/unused.S */ 9207 bl common_abort 9208 9209 9210/* ------------------------------ */ 9211 .balign 64 9212.L_OP_UNUSED_5CFF: /* 0x15c */ 9213/* File: armv5te/OP_UNUSED_5CFF.S */ 9214/* File: armv5te/unused.S */ 9215 bl common_abort 9216 9217 9218/* ------------------------------ */ 9219 .balign 64 9220.L_OP_UNUSED_5DFF: /* 0x15d */ 9221/* File: armv5te/OP_UNUSED_5DFF.S */ 9222/* File: armv5te/unused.S */ 9223 bl common_abort 9224 9225 9226/* ------------------------------ */ 9227 .balign 64 9228.L_OP_UNUSED_5EFF: /* 0x15e */ 9229/* File: armv5te/OP_UNUSED_5EFF.S */ 9230/* File: armv5te/unused.S */ 9231 bl common_abort 9232 9233 9234/* ------------------------------ */ 9235 .balign 64 9236.L_OP_UNUSED_5FFF: /* 0x15f */ 9237/* File: armv5te/OP_UNUSED_5FFF.S */ 9238/* File: armv5te/unused.S */ 9239 bl common_abort 9240 9241 9242/* ------------------------------ */ 9243 .balign 64 9244.L_OP_UNUSED_60FF: /* 0x160 */ 9245/* File: armv5te/OP_UNUSED_60FF.S */ 9246/* File: armv5te/unused.S */ 9247 bl common_abort 9248 9249 9250/* ------------------------------ */ 9251 .balign 64 9252.L_OP_UNUSED_61FF: /* 0x161 */ 9253/* File: armv5te/OP_UNUSED_61FF.S */ 9254/* File: armv5te/unused.S */ 9255 bl common_abort 9256 9257 9258/* ------------------------------ */ 9259 .balign 64 9260.L_OP_UNUSED_62FF: /* 0x162 */ 9261/* File: armv5te/OP_UNUSED_62FF.S */ 9262/* File: armv5te/unused.S */ 9263 bl common_abort 9264 9265 9266/* ------------------------------ */ 9267 .balign 64 9268.L_OP_UNUSED_63FF: /* 0x163 */ 9269/* File: armv5te/OP_UNUSED_63FF.S */ 9270/* File: armv5te/unused.S */ 9271 bl common_abort 9272 9273 9274/* ------------------------------ */ 9275 .balign 64 9276.L_OP_UNUSED_64FF: /* 0x164 */ 9277/* File: armv5te/OP_UNUSED_64FF.S */ 9278/* File: armv5te/unused.S */ 9279 bl common_abort 9280 9281 9282/* ------------------------------ */ 9283 .balign 64 9284.L_OP_UNUSED_65FF: /* 0x165 */ 9285/* File: armv5te/OP_UNUSED_65FF.S */ 9286/* File: armv5te/unused.S */ 9287 bl common_abort 9288 9289 9290/* ------------------------------ */ 9291 .balign 64 9292.L_OP_UNUSED_66FF: /* 0x166 */ 9293/* File: armv5te/OP_UNUSED_66FF.S */ 9294/* File: armv5te/unused.S */ 9295 bl common_abort 9296 9297 9298/* ------------------------------ */ 9299 .balign 64 9300.L_OP_UNUSED_67FF: /* 0x167 */ 9301/* File: armv5te/OP_UNUSED_67FF.S */ 9302/* File: armv5te/unused.S */ 9303 bl common_abort 9304 9305 9306/* ------------------------------ */ 9307 .balign 64 9308.L_OP_UNUSED_68FF: /* 0x168 */ 9309/* File: armv5te/OP_UNUSED_68FF.S */ 9310/* File: armv5te/unused.S */ 9311 bl common_abort 9312 9313 9314/* ------------------------------ */ 9315 .balign 64 9316.L_OP_UNUSED_69FF: /* 0x169 */ 9317/* File: armv5te/OP_UNUSED_69FF.S */ 9318/* File: armv5te/unused.S */ 9319 bl common_abort 9320 9321 9322/* ------------------------------ */ 9323 .balign 64 9324.L_OP_UNUSED_6AFF: /* 0x16a */ 9325/* File: armv5te/OP_UNUSED_6AFF.S */ 9326/* File: armv5te/unused.S */ 9327 bl common_abort 9328 9329 9330/* ------------------------------ */ 9331 .balign 64 9332.L_OP_UNUSED_6BFF: /* 0x16b */ 9333/* File: armv5te/OP_UNUSED_6BFF.S */ 9334/* File: armv5te/unused.S */ 9335 bl common_abort 9336 9337 9338/* ------------------------------ */ 9339 .balign 64 9340.L_OP_UNUSED_6CFF: /* 0x16c */ 9341/* File: armv5te/OP_UNUSED_6CFF.S */ 9342/* File: armv5te/unused.S */ 9343 bl common_abort 9344 9345 9346/* ------------------------------ */ 9347 .balign 64 9348.L_OP_UNUSED_6DFF: /* 0x16d */ 9349/* File: armv5te/OP_UNUSED_6DFF.S */ 9350/* File: armv5te/unused.S */ 9351 bl common_abort 9352 9353 9354/* ------------------------------ */ 9355 .balign 64 9356.L_OP_UNUSED_6EFF: /* 0x16e */ 9357/* File: armv5te/OP_UNUSED_6EFF.S */ 9358/* File: armv5te/unused.S */ 9359 bl common_abort 9360 9361 9362/* ------------------------------ */ 9363 .balign 64 9364.L_OP_UNUSED_6FFF: /* 0x16f */ 9365/* File: armv5te/OP_UNUSED_6FFF.S */ 9366/* File: armv5te/unused.S */ 9367 bl common_abort 9368 9369 9370/* ------------------------------ */ 9371 .balign 64 9372.L_OP_UNUSED_70FF: /* 0x170 */ 9373/* File: armv5te/OP_UNUSED_70FF.S */ 9374/* File: armv5te/unused.S */ 9375 bl common_abort 9376 9377 9378/* ------------------------------ */ 9379 .balign 64 9380.L_OP_UNUSED_71FF: /* 0x171 */ 9381/* File: armv5te/OP_UNUSED_71FF.S */ 9382/* File: armv5te/unused.S */ 9383 bl common_abort 9384 9385 9386/* ------------------------------ */ 9387 .balign 64 9388.L_OP_UNUSED_72FF: /* 0x172 */ 9389/* File: armv5te/OP_UNUSED_72FF.S */ 9390/* File: armv5te/unused.S */ 9391 bl common_abort 9392 9393 9394/* ------------------------------ */ 9395 .balign 64 9396.L_OP_UNUSED_73FF: /* 0x173 */ 9397/* File: armv5te/OP_UNUSED_73FF.S */ 9398/* File: armv5te/unused.S */ 9399 bl common_abort 9400 9401 9402/* ------------------------------ */ 9403 .balign 64 9404.L_OP_UNUSED_74FF: /* 0x174 */ 9405/* File: armv5te/OP_UNUSED_74FF.S */ 9406/* File: armv5te/unused.S */ 9407 bl common_abort 9408 9409 9410/* ------------------------------ */ 9411 .balign 64 9412.L_OP_UNUSED_75FF: /* 0x175 */ 9413/* File: armv5te/OP_UNUSED_75FF.S */ 9414/* File: armv5te/unused.S */ 9415 bl common_abort 9416 9417 9418/* ------------------------------ */ 9419 .balign 64 9420.L_OP_UNUSED_76FF: /* 0x176 */ 9421/* File: armv5te/OP_UNUSED_76FF.S */ 9422/* File: armv5te/unused.S */ 9423 bl common_abort 9424 9425 9426/* ------------------------------ */ 9427 .balign 64 9428.L_OP_UNUSED_77FF: /* 0x177 */ 9429/* File: armv5te/OP_UNUSED_77FF.S */ 9430/* File: armv5te/unused.S */ 9431 bl common_abort 9432 9433 9434/* ------------------------------ */ 9435 .balign 64 9436.L_OP_UNUSED_78FF: /* 0x178 */ 9437/* File: armv5te/OP_UNUSED_78FF.S */ 9438/* File: armv5te/unused.S */ 9439 bl common_abort 9440 9441 9442/* ------------------------------ */ 9443 .balign 64 9444.L_OP_UNUSED_79FF: /* 0x179 */ 9445/* File: armv5te/OP_UNUSED_79FF.S */ 9446/* File: armv5te/unused.S */ 9447 bl common_abort 9448 9449 9450/* ------------------------------ */ 9451 .balign 64 9452.L_OP_UNUSED_7AFF: /* 0x17a */ 9453/* File: armv5te/OP_UNUSED_7AFF.S */ 9454/* File: armv5te/unused.S */ 9455 bl common_abort 9456 9457 9458/* ------------------------------ */ 9459 .balign 64 9460.L_OP_UNUSED_7BFF: /* 0x17b */ 9461/* File: armv5te/OP_UNUSED_7BFF.S */ 9462/* File: armv5te/unused.S */ 9463 bl common_abort 9464 9465 9466/* ------------------------------ */ 9467 .balign 64 9468.L_OP_UNUSED_7CFF: /* 0x17c */ 9469/* File: armv5te/OP_UNUSED_7CFF.S */ 9470/* File: armv5te/unused.S */ 9471 bl common_abort 9472 9473 9474/* ------------------------------ */ 9475 .balign 64 9476.L_OP_UNUSED_7DFF: /* 0x17d */ 9477/* File: armv5te/OP_UNUSED_7DFF.S */ 9478/* File: armv5te/unused.S */ 9479 bl common_abort 9480 9481 9482/* ------------------------------ */ 9483 .balign 64 9484.L_OP_UNUSED_7EFF: /* 0x17e */ 9485/* File: armv5te/OP_UNUSED_7EFF.S */ 9486/* File: armv5te/unused.S */ 9487 bl common_abort 9488 9489 9490/* ------------------------------ */ 9491 .balign 64 9492.L_OP_UNUSED_7FFF: /* 0x17f */ 9493/* File: armv5te/OP_UNUSED_7FFF.S */ 9494/* File: armv5te/unused.S */ 9495 bl common_abort 9496 9497 9498/* ------------------------------ */ 9499 .balign 64 9500.L_OP_UNUSED_80FF: /* 0x180 */ 9501/* File: armv5te/OP_UNUSED_80FF.S */ 9502/* File: armv5te/unused.S */ 9503 bl common_abort 9504 9505 9506/* ------------------------------ */ 9507 .balign 64 9508.L_OP_UNUSED_81FF: /* 0x181 */ 9509/* File: armv5te/OP_UNUSED_81FF.S */ 9510/* File: armv5te/unused.S */ 9511 bl common_abort 9512 9513 9514/* ------------------------------ */ 9515 .balign 64 9516.L_OP_UNUSED_82FF: /* 0x182 */ 9517/* File: armv5te/OP_UNUSED_82FF.S */ 9518/* File: armv5te/unused.S */ 9519 bl common_abort 9520 9521 9522/* ------------------------------ */ 9523 .balign 64 9524.L_OP_UNUSED_83FF: /* 0x183 */ 9525/* File: armv5te/OP_UNUSED_83FF.S */ 9526/* File: armv5te/unused.S */ 9527 bl common_abort 9528 9529 9530/* ------------------------------ */ 9531 .balign 64 9532.L_OP_UNUSED_84FF: /* 0x184 */ 9533/* File: armv5te/OP_UNUSED_84FF.S */ 9534/* File: armv5te/unused.S */ 9535 bl common_abort 9536 9537 9538/* ------------------------------ */ 9539 .balign 64 9540.L_OP_UNUSED_85FF: /* 0x185 */ 9541/* File: armv5te/OP_UNUSED_85FF.S */ 9542/* File: armv5te/unused.S */ 9543 bl common_abort 9544 9545 9546/* ------------------------------ */ 9547 .balign 64 9548.L_OP_UNUSED_86FF: /* 0x186 */ 9549/* File: armv5te/OP_UNUSED_86FF.S */ 9550/* File: armv5te/unused.S */ 9551 bl common_abort 9552 9553 9554/* ------------------------------ */ 9555 .balign 64 9556.L_OP_UNUSED_87FF: /* 0x187 */ 9557/* File: armv5te/OP_UNUSED_87FF.S */ 9558/* File: armv5te/unused.S */ 9559 bl common_abort 9560 9561 9562/* ------------------------------ */ 9563 .balign 64 9564.L_OP_UNUSED_88FF: /* 0x188 */ 9565/* File: armv5te/OP_UNUSED_88FF.S */ 9566/* File: armv5te/unused.S */ 9567 bl common_abort 9568 9569 9570/* ------------------------------ */ 9571 .balign 64 9572.L_OP_UNUSED_89FF: /* 0x189 */ 9573/* File: armv5te/OP_UNUSED_89FF.S */ 9574/* File: armv5te/unused.S */ 9575 bl common_abort 9576 9577 9578/* ------------------------------ */ 9579 .balign 64 9580.L_OP_UNUSED_8AFF: /* 0x18a */ 9581/* File: armv5te/OP_UNUSED_8AFF.S */ 9582/* File: armv5te/unused.S */ 9583 bl common_abort 9584 9585 9586/* ------------------------------ */ 9587 .balign 64 9588.L_OP_UNUSED_8BFF: /* 0x18b */ 9589/* File: armv5te/OP_UNUSED_8BFF.S */ 9590/* File: armv5te/unused.S */ 9591 bl common_abort 9592 9593 9594/* ------------------------------ */ 9595 .balign 64 9596.L_OP_UNUSED_8CFF: /* 0x18c */ 9597/* File: armv5te/OP_UNUSED_8CFF.S */ 9598/* File: armv5te/unused.S */ 9599 bl common_abort 9600 9601 9602/* ------------------------------ */ 9603 .balign 64 9604.L_OP_UNUSED_8DFF: /* 0x18d */ 9605/* File: armv5te/OP_UNUSED_8DFF.S */ 9606/* File: armv5te/unused.S */ 9607 bl common_abort 9608 9609 9610/* ------------------------------ */ 9611 .balign 64 9612.L_OP_UNUSED_8EFF: /* 0x18e */ 9613/* File: armv5te/OP_UNUSED_8EFF.S */ 9614/* File: armv5te/unused.S */ 9615 bl common_abort 9616 9617 9618/* ------------------------------ */ 9619 .balign 64 9620.L_OP_UNUSED_8FFF: /* 0x18f */ 9621/* File: armv5te/OP_UNUSED_8FFF.S */ 9622/* File: armv5te/unused.S */ 9623 bl common_abort 9624 9625 9626/* ------------------------------ */ 9627 .balign 64 9628.L_OP_UNUSED_90FF: /* 0x190 */ 9629/* File: armv5te/OP_UNUSED_90FF.S */ 9630/* File: armv5te/unused.S */ 9631 bl common_abort 9632 9633 9634/* ------------------------------ */ 9635 .balign 64 9636.L_OP_UNUSED_91FF: /* 0x191 */ 9637/* File: armv5te/OP_UNUSED_91FF.S */ 9638/* File: armv5te/unused.S */ 9639 bl common_abort 9640 9641 9642/* ------------------------------ */ 9643 .balign 64 9644.L_OP_UNUSED_92FF: /* 0x192 */ 9645/* File: armv5te/OP_UNUSED_92FF.S */ 9646/* File: armv5te/unused.S */ 9647 bl common_abort 9648 9649 9650/* ------------------------------ */ 9651 .balign 64 9652.L_OP_UNUSED_93FF: /* 0x193 */ 9653/* File: armv5te/OP_UNUSED_93FF.S */ 9654/* File: armv5te/unused.S */ 9655 bl common_abort 9656 9657 9658/* ------------------------------ */ 9659 .balign 64 9660.L_OP_UNUSED_94FF: /* 0x194 */ 9661/* File: armv5te/OP_UNUSED_94FF.S */ 9662/* File: armv5te/unused.S */ 9663 bl common_abort 9664 9665 9666/* ------------------------------ */ 9667 .balign 64 9668.L_OP_UNUSED_95FF: /* 0x195 */ 9669/* File: armv5te/OP_UNUSED_95FF.S */ 9670/* File: armv5te/unused.S */ 9671 bl common_abort 9672 9673 9674/* ------------------------------ */ 9675 .balign 64 9676.L_OP_UNUSED_96FF: /* 0x196 */ 9677/* File: armv5te/OP_UNUSED_96FF.S */ 9678/* File: armv5te/unused.S */ 9679 bl common_abort 9680 9681 9682/* ------------------------------ */ 9683 .balign 64 9684.L_OP_UNUSED_97FF: /* 0x197 */ 9685/* File: armv5te/OP_UNUSED_97FF.S */ 9686/* File: armv5te/unused.S */ 9687 bl common_abort 9688 9689 9690/* ------------------------------ */ 9691 .balign 64 9692.L_OP_UNUSED_98FF: /* 0x198 */ 9693/* File: armv5te/OP_UNUSED_98FF.S */ 9694/* File: armv5te/unused.S */ 9695 bl common_abort 9696 9697 9698/* ------------------------------ */ 9699 .balign 64 9700.L_OP_UNUSED_99FF: /* 0x199 */ 9701/* File: armv5te/OP_UNUSED_99FF.S */ 9702/* File: armv5te/unused.S */ 9703 bl common_abort 9704 9705 9706/* ------------------------------ */ 9707 .balign 64 9708.L_OP_UNUSED_9AFF: /* 0x19a */ 9709/* File: armv5te/OP_UNUSED_9AFF.S */ 9710/* File: armv5te/unused.S */ 9711 bl common_abort 9712 9713 9714/* ------------------------------ */ 9715 .balign 64 9716.L_OP_UNUSED_9BFF: /* 0x19b */ 9717/* File: armv5te/OP_UNUSED_9BFF.S */ 9718/* File: armv5te/unused.S */ 9719 bl common_abort 9720 9721 9722/* ------------------------------ */ 9723 .balign 64 9724.L_OP_UNUSED_9CFF: /* 0x19c */ 9725/* File: armv5te/OP_UNUSED_9CFF.S */ 9726/* File: armv5te/unused.S */ 9727 bl common_abort 9728 9729 9730/* ------------------------------ */ 9731 .balign 64 9732.L_OP_UNUSED_9DFF: /* 0x19d */ 9733/* File: armv5te/OP_UNUSED_9DFF.S */ 9734/* File: armv5te/unused.S */ 9735 bl common_abort 9736 9737 9738/* ------------------------------ */ 9739 .balign 64 9740.L_OP_UNUSED_9EFF: /* 0x19e */ 9741/* File: armv5te/OP_UNUSED_9EFF.S */ 9742/* File: armv5te/unused.S */ 9743 bl common_abort 9744 9745 9746/* ------------------------------ */ 9747 .balign 64 9748.L_OP_UNUSED_9FFF: /* 0x19f */ 9749/* File: armv5te/OP_UNUSED_9FFF.S */ 9750/* File: armv5te/unused.S */ 9751 bl common_abort 9752 9753 9754/* ------------------------------ */ 9755 .balign 64 9756.L_OP_UNUSED_A0FF: /* 0x1a0 */ 9757/* File: armv5te/OP_UNUSED_A0FF.S */ 9758/* File: armv5te/unused.S */ 9759 bl common_abort 9760 9761 9762/* ------------------------------ */ 9763 .balign 64 9764.L_OP_UNUSED_A1FF: /* 0x1a1 */ 9765/* File: armv5te/OP_UNUSED_A1FF.S */ 9766/* File: armv5te/unused.S */ 9767 bl common_abort 9768 9769 9770/* ------------------------------ */ 9771 .balign 64 9772.L_OP_UNUSED_A2FF: /* 0x1a2 */ 9773/* File: armv5te/OP_UNUSED_A2FF.S */ 9774/* File: armv5te/unused.S */ 9775 bl common_abort 9776 9777 9778/* ------------------------------ */ 9779 .balign 64 9780.L_OP_UNUSED_A3FF: /* 0x1a3 */ 9781/* File: armv5te/OP_UNUSED_A3FF.S */ 9782/* File: armv5te/unused.S */ 9783 bl common_abort 9784 9785 9786/* ------------------------------ */ 9787 .balign 64 9788.L_OP_UNUSED_A4FF: /* 0x1a4 */ 9789/* File: armv5te/OP_UNUSED_A4FF.S */ 9790/* File: armv5te/unused.S */ 9791 bl common_abort 9792 9793 9794/* ------------------------------ */ 9795 .balign 64 9796.L_OP_UNUSED_A5FF: /* 0x1a5 */ 9797/* File: armv5te/OP_UNUSED_A5FF.S */ 9798/* File: armv5te/unused.S */ 9799 bl common_abort 9800 9801 9802/* ------------------------------ */ 9803 .balign 64 9804.L_OP_UNUSED_A6FF: /* 0x1a6 */ 9805/* File: armv5te/OP_UNUSED_A6FF.S */ 9806/* File: armv5te/unused.S */ 9807 bl common_abort 9808 9809 9810/* ------------------------------ */ 9811 .balign 64 9812.L_OP_UNUSED_A7FF: /* 0x1a7 */ 9813/* File: armv5te/OP_UNUSED_A7FF.S */ 9814/* File: armv5te/unused.S */ 9815 bl common_abort 9816 9817 9818/* ------------------------------ */ 9819 .balign 64 9820.L_OP_UNUSED_A8FF: /* 0x1a8 */ 9821/* File: armv5te/OP_UNUSED_A8FF.S */ 9822/* File: armv5te/unused.S */ 9823 bl common_abort 9824 9825 9826/* ------------------------------ */ 9827 .balign 64 9828.L_OP_UNUSED_A9FF: /* 0x1a9 */ 9829/* File: armv5te/OP_UNUSED_A9FF.S */ 9830/* File: armv5te/unused.S */ 9831 bl common_abort 9832 9833 9834/* ------------------------------ */ 9835 .balign 64 9836.L_OP_UNUSED_AAFF: /* 0x1aa */ 9837/* File: armv5te/OP_UNUSED_AAFF.S */ 9838/* File: armv5te/unused.S */ 9839 bl common_abort 9840 9841 9842/* ------------------------------ */ 9843 .balign 64 9844.L_OP_UNUSED_ABFF: /* 0x1ab */ 9845/* File: armv5te/OP_UNUSED_ABFF.S */ 9846/* File: armv5te/unused.S */ 9847 bl common_abort 9848 9849 9850/* ------------------------------ */ 9851 .balign 64 9852.L_OP_UNUSED_ACFF: /* 0x1ac */ 9853/* File: armv5te/OP_UNUSED_ACFF.S */ 9854/* File: armv5te/unused.S */ 9855 bl common_abort 9856 9857 9858/* ------------------------------ */ 9859 .balign 64 9860.L_OP_UNUSED_ADFF: /* 0x1ad */ 9861/* File: armv5te/OP_UNUSED_ADFF.S */ 9862/* File: armv5te/unused.S */ 9863 bl common_abort 9864 9865 9866/* ------------------------------ */ 9867 .balign 64 9868.L_OP_UNUSED_AEFF: /* 0x1ae */ 9869/* File: armv5te/OP_UNUSED_AEFF.S */ 9870/* File: armv5te/unused.S */ 9871 bl common_abort 9872 9873 9874/* ------------------------------ */ 9875 .balign 64 9876.L_OP_UNUSED_AFFF: /* 0x1af */ 9877/* File: armv5te/OP_UNUSED_AFFF.S */ 9878/* File: armv5te/unused.S */ 9879 bl common_abort 9880 9881 9882/* ------------------------------ */ 9883 .balign 64 9884.L_OP_UNUSED_B0FF: /* 0x1b0 */ 9885/* File: armv5te/OP_UNUSED_B0FF.S */ 9886/* File: armv5te/unused.S */ 9887 bl common_abort 9888 9889 9890/* ------------------------------ */ 9891 .balign 64 9892.L_OP_UNUSED_B1FF: /* 0x1b1 */ 9893/* File: armv5te/OP_UNUSED_B1FF.S */ 9894/* File: armv5te/unused.S */ 9895 bl common_abort 9896 9897 9898/* ------------------------------ */ 9899 .balign 64 9900.L_OP_UNUSED_B2FF: /* 0x1b2 */ 9901/* File: armv5te/OP_UNUSED_B2FF.S */ 9902/* File: armv5te/unused.S */ 9903 bl common_abort 9904 9905 9906/* ------------------------------ */ 9907 .balign 64 9908.L_OP_UNUSED_B3FF: /* 0x1b3 */ 9909/* File: armv5te/OP_UNUSED_B3FF.S */ 9910/* File: armv5te/unused.S */ 9911 bl common_abort 9912 9913 9914/* ------------------------------ */ 9915 .balign 64 9916.L_OP_UNUSED_B4FF: /* 0x1b4 */ 9917/* File: armv5te/OP_UNUSED_B4FF.S */ 9918/* File: armv5te/unused.S */ 9919 bl common_abort 9920 9921 9922/* ------------------------------ */ 9923 .balign 64 9924.L_OP_UNUSED_B5FF: /* 0x1b5 */ 9925/* File: armv5te/OP_UNUSED_B5FF.S */ 9926/* File: armv5te/unused.S */ 9927 bl common_abort 9928 9929 9930/* ------------------------------ */ 9931 .balign 64 9932.L_OP_UNUSED_B6FF: /* 0x1b6 */ 9933/* File: armv5te/OP_UNUSED_B6FF.S */ 9934/* File: armv5te/unused.S */ 9935 bl common_abort 9936 9937 9938/* ------------------------------ */ 9939 .balign 64 9940.L_OP_UNUSED_B7FF: /* 0x1b7 */ 9941/* File: armv5te/OP_UNUSED_B7FF.S */ 9942/* File: armv5te/unused.S */ 9943 bl common_abort 9944 9945 9946/* ------------------------------ */ 9947 .balign 64 9948.L_OP_UNUSED_B8FF: /* 0x1b8 */ 9949/* File: armv5te/OP_UNUSED_B8FF.S */ 9950/* File: armv5te/unused.S */ 9951 bl common_abort 9952 9953 9954/* ------------------------------ */ 9955 .balign 64 9956.L_OP_UNUSED_B9FF: /* 0x1b9 */ 9957/* File: armv5te/OP_UNUSED_B9FF.S */ 9958/* File: armv5te/unused.S */ 9959 bl common_abort 9960 9961 9962/* ------------------------------ */ 9963 .balign 64 9964.L_OP_UNUSED_BAFF: /* 0x1ba */ 9965/* File: armv5te/OP_UNUSED_BAFF.S */ 9966/* File: armv5te/unused.S */ 9967 bl common_abort 9968 9969 9970/* ------------------------------ */ 9971 .balign 64 9972.L_OP_UNUSED_BBFF: /* 0x1bb */ 9973/* File: armv5te/OP_UNUSED_BBFF.S */ 9974/* File: armv5te/unused.S */ 9975 bl common_abort 9976 9977 9978/* ------------------------------ */ 9979 .balign 64 9980.L_OP_UNUSED_BCFF: /* 0x1bc */ 9981/* File: armv5te/OP_UNUSED_BCFF.S */ 9982/* File: armv5te/unused.S */ 9983 bl common_abort 9984 9985 9986/* ------------------------------ */ 9987 .balign 64 9988.L_OP_UNUSED_BDFF: /* 0x1bd */ 9989/* File: armv5te/OP_UNUSED_BDFF.S */ 9990/* File: armv5te/unused.S */ 9991 bl common_abort 9992 9993 9994/* ------------------------------ */ 9995 .balign 64 9996.L_OP_UNUSED_BEFF: /* 0x1be */ 9997/* File: armv5te/OP_UNUSED_BEFF.S */ 9998/* File: armv5te/unused.S */ 9999 bl common_abort 10000 10001 10002/* ------------------------------ */ 10003 .balign 64 10004.L_OP_UNUSED_BFFF: /* 0x1bf */ 10005/* File: armv5te/OP_UNUSED_BFFF.S */ 10006/* File: armv5te/unused.S */ 10007 bl common_abort 10008 10009 10010/* ------------------------------ */ 10011 .balign 64 10012.L_OP_UNUSED_C0FF: /* 0x1c0 */ 10013/* File: armv5te/OP_UNUSED_C0FF.S */ 10014/* File: armv5te/unused.S */ 10015 bl common_abort 10016 10017 10018/* ------------------------------ */ 10019 .balign 64 10020.L_OP_UNUSED_C1FF: /* 0x1c1 */ 10021/* File: armv5te/OP_UNUSED_C1FF.S */ 10022/* File: armv5te/unused.S */ 10023 bl common_abort 10024 10025 10026/* ------------------------------ */ 10027 .balign 64 10028.L_OP_UNUSED_C2FF: /* 0x1c2 */ 10029/* File: armv5te/OP_UNUSED_C2FF.S */ 10030/* File: armv5te/unused.S */ 10031 bl common_abort 10032 10033 10034/* ------------------------------ */ 10035 .balign 64 10036.L_OP_UNUSED_C3FF: /* 0x1c3 */ 10037/* File: armv5te/OP_UNUSED_C3FF.S */ 10038/* File: armv5te/unused.S */ 10039 bl common_abort 10040 10041 10042/* ------------------------------ */ 10043 .balign 64 10044.L_OP_UNUSED_C4FF: /* 0x1c4 */ 10045/* File: armv5te/OP_UNUSED_C4FF.S */ 10046/* File: armv5te/unused.S */ 10047 bl common_abort 10048 10049 10050/* ------------------------------ */ 10051 .balign 64 10052.L_OP_UNUSED_C5FF: /* 0x1c5 */ 10053/* File: armv5te/OP_UNUSED_C5FF.S */ 10054/* File: armv5te/unused.S */ 10055 bl common_abort 10056 10057 10058/* ------------------------------ */ 10059 .balign 64 10060.L_OP_UNUSED_C6FF: /* 0x1c6 */ 10061/* File: armv5te/OP_UNUSED_C6FF.S */ 10062/* File: armv5te/unused.S */ 10063 bl common_abort 10064 10065 10066/* ------------------------------ */ 10067 .balign 64 10068.L_OP_UNUSED_C7FF: /* 0x1c7 */ 10069/* File: armv5te/OP_UNUSED_C7FF.S */ 10070/* File: armv5te/unused.S */ 10071 bl common_abort 10072 10073 10074/* ------------------------------ */ 10075 .balign 64 10076.L_OP_UNUSED_C8FF: /* 0x1c8 */ 10077/* File: armv5te/OP_UNUSED_C8FF.S */ 10078/* File: armv5te/unused.S */ 10079 bl common_abort 10080 10081 10082/* ------------------------------ */ 10083 .balign 64 10084.L_OP_UNUSED_C9FF: /* 0x1c9 */ 10085/* File: armv5te/OP_UNUSED_C9FF.S */ 10086/* File: armv5te/unused.S */ 10087 bl common_abort 10088 10089 10090/* ------------------------------ */ 10091 .balign 64 10092.L_OP_UNUSED_CAFF: /* 0x1ca */ 10093/* File: armv5te/OP_UNUSED_CAFF.S */ 10094/* File: armv5te/unused.S */ 10095 bl common_abort 10096 10097 10098/* ------------------------------ */ 10099 .balign 64 10100.L_OP_UNUSED_CBFF: /* 0x1cb */ 10101/* File: armv5te/OP_UNUSED_CBFF.S */ 10102/* File: armv5te/unused.S */ 10103 bl common_abort 10104 10105 10106/* ------------------------------ */ 10107 .balign 64 10108.L_OP_UNUSED_CCFF: /* 0x1cc */ 10109/* File: armv5te/OP_UNUSED_CCFF.S */ 10110/* File: armv5te/unused.S */ 10111 bl common_abort 10112 10113 10114/* ------------------------------ */ 10115 .balign 64 10116.L_OP_UNUSED_CDFF: /* 0x1cd */ 10117/* File: armv5te/OP_UNUSED_CDFF.S */ 10118/* File: armv5te/unused.S */ 10119 bl common_abort 10120 10121 10122/* ------------------------------ */ 10123 .balign 64 10124.L_OP_UNUSED_CEFF: /* 0x1ce */ 10125/* File: armv5te/OP_UNUSED_CEFF.S */ 10126/* File: armv5te/unused.S */ 10127 bl common_abort 10128 10129 10130/* ------------------------------ */ 10131 .balign 64 10132.L_OP_UNUSED_CFFF: /* 0x1cf */ 10133/* File: armv5te/OP_UNUSED_CFFF.S */ 10134/* File: armv5te/unused.S */ 10135 bl common_abort 10136 10137 10138/* ------------------------------ */ 10139 .balign 64 10140.L_OP_UNUSED_D0FF: /* 0x1d0 */ 10141/* File: armv5te/OP_UNUSED_D0FF.S */ 10142/* File: armv5te/unused.S */ 10143 bl common_abort 10144 10145 10146/* ------------------------------ */ 10147 .balign 64 10148.L_OP_UNUSED_D1FF: /* 0x1d1 */ 10149/* File: armv5te/OP_UNUSED_D1FF.S */ 10150/* File: armv5te/unused.S */ 10151 bl common_abort 10152 10153 10154/* ------------------------------ */ 10155 .balign 64 10156.L_OP_UNUSED_D2FF: /* 0x1d2 */ 10157/* File: armv5te/OP_UNUSED_D2FF.S */ 10158/* File: armv5te/unused.S */ 10159 bl common_abort 10160 10161 10162/* ------------------------------ */ 10163 .balign 64 10164.L_OP_UNUSED_D3FF: /* 0x1d3 */ 10165/* File: armv5te/OP_UNUSED_D3FF.S */ 10166/* File: armv5te/unused.S */ 10167 bl common_abort 10168 10169 10170/* ------------------------------ */ 10171 .balign 64 10172.L_OP_UNUSED_D4FF: /* 0x1d4 */ 10173/* File: armv5te/OP_UNUSED_D4FF.S */ 10174/* File: armv5te/unused.S */ 10175 bl common_abort 10176 10177 10178/* ------------------------------ */ 10179 .balign 64 10180.L_OP_UNUSED_D5FF: /* 0x1d5 */ 10181/* File: armv5te/OP_UNUSED_D5FF.S */ 10182/* File: armv5te/unused.S */ 10183 bl common_abort 10184 10185 10186/* ------------------------------ */ 10187 .balign 64 10188.L_OP_UNUSED_D6FF: /* 0x1d6 */ 10189/* File: armv5te/OP_UNUSED_D6FF.S */ 10190/* File: armv5te/unused.S */ 10191 bl common_abort 10192 10193 10194/* ------------------------------ */ 10195 .balign 64 10196.L_OP_UNUSED_D7FF: /* 0x1d7 */ 10197/* File: armv5te/OP_UNUSED_D7FF.S */ 10198/* File: armv5te/unused.S */ 10199 bl common_abort 10200 10201 10202/* ------------------------------ */ 10203 .balign 64 10204.L_OP_UNUSED_D8FF: /* 0x1d8 */ 10205/* File: armv5te/OP_UNUSED_D8FF.S */ 10206/* File: armv5te/unused.S */ 10207 bl common_abort 10208 10209 10210/* ------------------------------ */ 10211 .balign 64 10212.L_OP_UNUSED_D9FF: /* 0x1d9 */ 10213/* File: armv5te/OP_UNUSED_D9FF.S */ 10214/* File: armv5te/unused.S */ 10215 bl common_abort 10216 10217 10218/* ------------------------------ */ 10219 .balign 64 10220.L_OP_UNUSED_DAFF: /* 0x1da */ 10221/* File: armv5te/OP_UNUSED_DAFF.S */ 10222/* File: armv5te/unused.S */ 10223 bl common_abort 10224 10225 10226/* ------------------------------ */ 10227 .balign 64 10228.L_OP_UNUSED_DBFF: /* 0x1db */ 10229/* File: armv5te/OP_UNUSED_DBFF.S */ 10230/* File: armv5te/unused.S */ 10231 bl common_abort 10232 10233 10234/* ------------------------------ */ 10235 .balign 64 10236.L_OP_UNUSED_DCFF: /* 0x1dc */ 10237/* File: armv5te/OP_UNUSED_DCFF.S */ 10238/* File: armv5te/unused.S */ 10239 bl common_abort 10240 10241 10242/* ------------------------------ */ 10243 .balign 64 10244.L_OP_UNUSED_DDFF: /* 0x1dd */ 10245/* File: armv5te/OP_UNUSED_DDFF.S */ 10246/* File: armv5te/unused.S */ 10247 bl common_abort 10248 10249 10250/* ------------------------------ */ 10251 .balign 64 10252.L_OP_UNUSED_DEFF: /* 0x1de */ 10253/* File: armv5te/OP_UNUSED_DEFF.S */ 10254/* File: armv5te/unused.S */ 10255 bl common_abort 10256 10257 10258/* ------------------------------ */ 10259 .balign 64 10260.L_OP_UNUSED_DFFF: /* 0x1df */ 10261/* File: armv5te/OP_UNUSED_DFFF.S */ 10262/* File: armv5te/unused.S */ 10263 bl common_abort 10264 10265 10266/* ------------------------------ */ 10267 .balign 64 10268.L_OP_UNUSED_E0FF: /* 0x1e0 */ 10269/* File: armv5te/OP_UNUSED_E0FF.S */ 10270/* File: armv5te/unused.S */ 10271 bl common_abort 10272 10273 10274/* ------------------------------ */ 10275 .balign 64 10276.L_OP_UNUSED_E1FF: /* 0x1e1 */ 10277/* File: armv5te/OP_UNUSED_E1FF.S */ 10278/* File: armv5te/unused.S */ 10279 bl common_abort 10280 10281 10282/* ------------------------------ */ 10283 .balign 64 10284.L_OP_UNUSED_E2FF: /* 0x1e2 */ 10285/* File: armv5te/OP_UNUSED_E2FF.S */ 10286/* File: armv5te/unused.S */ 10287 bl common_abort 10288 10289 10290/* ------------------------------ */ 10291 .balign 64 10292.L_OP_UNUSED_E3FF: /* 0x1e3 */ 10293/* File: armv5te/OP_UNUSED_E3FF.S */ 10294/* File: armv5te/unused.S */ 10295 bl common_abort 10296 10297 10298/* ------------------------------ */ 10299 .balign 64 10300.L_OP_UNUSED_E4FF: /* 0x1e4 */ 10301/* File: armv5te/OP_UNUSED_E4FF.S */ 10302/* File: armv5te/unused.S */ 10303 bl common_abort 10304 10305 10306/* ------------------------------ */ 10307 .balign 64 10308.L_OP_UNUSED_E5FF: /* 0x1e5 */ 10309/* File: armv5te/OP_UNUSED_E5FF.S */ 10310/* File: armv5te/unused.S */ 10311 bl common_abort 10312 10313 10314/* ------------------------------ */ 10315 .balign 64 10316.L_OP_UNUSED_E6FF: /* 0x1e6 */ 10317/* File: armv5te/OP_UNUSED_E6FF.S */ 10318/* File: armv5te/unused.S */ 10319 bl common_abort 10320 10321 10322/* ------------------------------ */ 10323 .balign 64 10324.L_OP_UNUSED_E7FF: /* 0x1e7 */ 10325/* File: armv5te/OP_UNUSED_E7FF.S */ 10326/* File: armv5te/unused.S */ 10327 bl common_abort 10328 10329 10330/* ------------------------------ */ 10331 .balign 64 10332.L_OP_UNUSED_E8FF: /* 0x1e8 */ 10333/* File: armv5te/OP_UNUSED_E8FF.S */ 10334/* File: armv5te/unused.S */ 10335 bl common_abort 10336 10337 10338/* ------------------------------ */ 10339 .balign 64 10340.L_OP_UNUSED_E9FF: /* 0x1e9 */ 10341/* File: armv5te/OP_UNUSED_E9FF.S */ 10342/* File: armv5te/unused.S */ 10343 bl common_abort 10344 10345 10346/* ------------------------------ */ 10347 .balign 64 10348.L_OP_UNUSED_EAFF: /* 0x1ea */ 10349/* File: armv5te/OP_UNUSED_EAFF.S */ 10350/* File: armv5te/unused.S */ 10351 bl common_abort 10352 10353 10354/* ------------------------------ */ 10355 .balign 64 10356.L_OP_UNUSED_EBFF: /* 0x1eb */ 10357/* File: armv5te/OP_UNUSED_EBFF.S */ 10358/* File: armv5te/unused.S */ 10359 bl common_abort 10360 10361 10362/* ------------------------------ */ 10363 .balign 64 10364.L_OP_UNUSED_ECFF: /* 0x1ec */ 10365/* File: armv5te/OP_UNUSED_ECFF.S */ 10366/* File: armv5te/unused.S */ 10367 bl common_abort 10368 10369 10370/* ------------------------------ */ 10371 .balign 64 10372.L_OP_UNUSED_EDFF: /* 0x1ed */ 10373/* File: armv5te/OP_UNUSED_EDFF.S */ 10374/* File: armv5te/unused.S */ 10375 bl common_abort 10376 10377 10378/* ------------------------------ */ 10379 .balign 64 10380.L_OP_UNUSED_EEFF: /* 0x1ee */ 10381/* File: armv5te/OP_UNUSED_EEFF.S */ 10382/* File: armv5te/unused.S */ 10383 bl common_abort 10384 10385 10386/* ------------------------------ */ 10387 .balign 64 10388.L_OP_UNUSED_EFFF: /* 0x1ef */ 10389/* File: armv5te/OP_UNUSED_EFFF.S */ 10390/* File: armv5te/unused.S */ 10391 bl common_abort 10392 10393 10394/* ------------------------------ */ 10395 .balign 64 10396.L_OP_UNUSED_F0FF: /* 0x1f0 */ 10397/* File: armv5te/OP_UNUSED_F0FF.S */ 10398/* File: armv5te/unused.S */ 10399 bl common_abort 10400 10401 10402/* ------------------------------ */ 10403 .balign 64 10404.L_OP_UNUSED_F1FF: /* 0x1f1 */ 10405/* File: armv5te/OP_UNUSED_F1FF.S */ 10406/* File: armv5te/unused.S */ 10407 bl common_abort 10408 10409 10410/* ------------------------------ */ 10411 .balign 64 10412.L_OP_UNUSED_F2FF: /* 0x1f2 */ 10413/* File: armv5te/OP_UNUSED_F2FF.S */ 10414/* File: armv5te/unused.S */ 10415 bl common_abort 10416 10417 10418/* ------------------------------ */ 10419 .balign 64 10420.L_OP_UNUSED_F3FF: /* 0x1f3 */ 10421/* File: armv5te/OP_UNUSED_F3FF.S */ 10422/* File: armv5te/unused.S */ 10423 bl common_abort 10424 10425 10426/* ------------------------------ */ 10427 .balign 64 10428.L_OP_UNUSED_F4FF: /* 0x1f4 */ 10429/* File: armv5te/OP_UNUSED_F4FF.S */ 10430/* File: armv5te/unused.S */ 10431 bl common_abort 10432 10433 10434/* ------------------------------ */ 10435 .balign 64 10436.L_OP_UNUSED_F5FF: /* 0x1f5 */ 10437/* File: armv5te/OP_UNUSED_F5FF.S */ 10438/* File: armv5te/unused.S */ 10439 bl common_abort 10440 10441 10442/* ------------------------------ */ 10443 .balign 64 10444.L_OP_UNUSED_F6FF: /* 0x1f6 */ 10445/* File: armv5te/OP_UNUSED_F6FF.S */ 10446/* File: armv5te/unused.S */ 10447 bl common_abort 10448 10449 10450/* ------------------------------ */ 10451 .balign 64 10452.L_OP_UNUSED_F7FF: /* 0x1f7 */ 10453/* File: armv5te/OP_UNUSED_F7FF.S */ 10454/* File: armv5te/unused.S */ 10455 bl common_abort 10456 10457 10458/* ------------------------------ */ 10459 .balign 64 10460.L_OP_UNUSED_F8FF: /* 0x1f8 */ 10461/* File: armv5te/OP_UNUSED_F8FF.S */ 10462/* File: armv5te/unused.S */ 10463 bl common_abort 10464 10465 10466/* ------------------------------ */ 10467 .balign 64 10468.L_OP_UNUSED_F9FF: /* 0x1f9 */ 10469/* File: armv5te/OP_UNUSED_F9FF.S */ 10470/* File: armv5te/unused.S */ 10471 bl common_abort 10472 10473 10474/* ------------------------------ */ 10475 .balign 64 10476.L_OP_UNUSED_FAFF: /* 0x1fa */ 10477/* File: armv5te/OP_UNUSED_FAFF.S */ 10478/* File: armv5te/unused.S */ 10479 bl common_abort 10480 10481 10482/* ------------------------------ */ 10483 .balign 64 10484.L_OP_UNUSED_FBFF: /* 0x1fb */ 10485/* File: armv5te/OP_UNUSED_FBFF.S */ 10486/* File: armv5te/unused.S */ 10487 bl common_abort 10488 10489 10490/* ------------------------------ */ 10491 .balign 64 10492.L_OP_UNUSED_FCFF: /* 0x1fc */ 10493/* File: armv5te/OP_UNUSED_FCFF.S */ 10494/* File: armv5te/unused.S */ 10495 bl common_abort 10496 10497 10498/* ------------------------------ */ 10499 .balign 64 10500.L_OP_UNUSED_FDFF: /* 0x1fd */ 10501/* File: armv5te/OP_UNUSED_FDFF.S */ 10502/* File: armv5te/unused.S */ 10503 bl common_abort 10504 10505 10506/* ------------------------------ */ 10507 .balign 64 10508.L_OP_UNUSED_FEFF: /* 0x1fe */ 10509/* File: armv5te/OP_UNUSED_FEFF.S */ 10510/* File: armv5te/unused.S */ 10511 bl common_abort 10512 10513 10514/* ------------------------------ */ 10515 .balign 64 10516.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */ 10517/* File: armv5te/OP_THROW_VERIFICATION_ERROR_JUMBO.S */ 10518 /* 10519 * Handle a jumbo throw-verification-error instruction. This throws an 10520 * exception for an error discovered during verification. The 10521 * exception is indicated by BBBB, with some detail provided by AAAAAAAA. 10522 */ 10523 /* exop BBBB, Class@AAAAAAAA */ 10524 FETCH(r1, 1) @ r1<- aaaa (lo) 10525 FETCH(r2, 2) @ r2<- AAAA (hi) 10526 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 10527 orr r2, r1, r2, lsl #16 @ r2<- AAAAaaaa 10528 EXPORT_PC() @ export the PC 10529 FETCH(r1, 3) @ r1<- BBBB 10530 bl dvmThrowVerificationError @ always throws 10531 b common_exceptionThrown @ handle exception 10532 10533 10534 .balign 64 10535 .size .L_OP_NOP, .-.L_OP_NOP 10536 .global dvmAsmInstructionEnd 10537dvmAsmInstructionEnd: 10538 10539/* 10540 * =========================================================================== 10541 * Sister implementations 10542 * =========================================================================== 10543 */ 10544 .global dvmAsmSisterStart 10545 .type dvmAsmSisterStart, %function 10546 .text 10547 .balign 4 10548dvmAsmSisterStart: 10549 10550/* continuation for OP_CONST_STRING */ 10551 10552 /* 10553 * Continuation if the String has not yet been resolved. 10554 * r1: BBBB (String ref) 10555 * r9: target register 10556 */ 10557.LOP_CONST_STRING_resolve: 10558 EXPORT_PC() 10559 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 10560 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10561 bl dvmResolveString @ r0<- String reference 10562 cmp r0, #0 @ failed? 10563 beq common_exceptionThrown @ yup, handle the exception 10564 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10565 GET_INST_OPCODE(ip) @ extract opcode from rINST 10566 SET_VREG(r0, r9) @ vAA<- r0 10567 GOTO_OPCODE(ip) @ jump to next instruction 10568 10569/* continuation for OP_CONST_STRING_JUMBO */ 10570 10571 /* 10572 * Continuation if the String has not yet been resolved. 10573 * r1: BBBBBBBB (String ref) 10574 * r9: target register 10575 */ 10576.LOP_CONST_STRING_JUMBO_resolve: 10577 EXPORT_PC() 10578 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 10579 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10580 bl dvmResolveString @ r0<- String reference 10581 cmp r0, #0 @ failed? 10582 beq common_exceptionThrown @ yup, handle the exception 10583 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 10584 GET_INST_OPCODE(ip) @ extract opcode from rINST 10585 SET_VREG(r0, r9) @ vAA<- r0 10586 GOTO_OPCODE(ip) @ jump to next instruction 10587 10588/* continuation for OP_CONST_CLASS */ 10589 10590 /* 10591 * Continuation if the Class has not yet been resolved. 10592 * r1: BBBB (Class ref) 10593 * r9: target register 10594 */ 10595.LOP_CONST_CLASS_resolve: 10596 EXPORT_PC() 10597 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 10598 mov r2, #1 @ r2<- true 10599 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10600 bl dvmResolveClass @ r0<- Class reference 10601 cmp r0, #0 @ failed? 10602 beq common_exceptionThrown @ yup, handle the exception 10603 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10604 GET_INST_OPCODE(ip) @ extract opcode from rINST 10605 SET_VREG(r0, r9) @ vAA<- r0 10606 GOTO_OPCODE(ip) @ jump to next instruction 10607 10608/* continuation for OP_CHECK_CAST */ 10609 10610 /* 10611 * Trivial test failed, need to perform full check. This is common. 10612 * r0 holds obj->clazz 10613 * r1 holds desired class resolved from BBBB 10614 * r9 holds object 10615 */ 10616.LOP_CHECK_CAST_fullcheck: 10617 mov r10, r1 @ avoid ClassObject getting clobbered 10618 bl dvmInstanceofNonTrivial @ r0<- boolean result 10619 cmp r0, #0 @ failed? 10620 bne .LOP_CHECK_CAST_okay @ no, success 10621 10622 @ A cast has failed. We need to throw a ClassCastException. 10623 EXPORT_PC() @ about to throw 10624 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 10625 mov r1, r10 @ r1<- desired class 10626 bl dvmThrowClassCastException 10627 b common_exceptionThrown 10628 10629 /* 10630 * Resolution required. This is the least-likely path. 10631 * 10632 * r2 holds BBBB 10633 * r9 holds object 10634 */ 10635.LOP_CHECK_CAST_resolve: 10636 EXPORT_PC() @ resolve() could throw 10637 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 10638 mov r1, r2 @ r1<- BBBB 10639 mov r2, #0 @ r2<- false 10640 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 10641 bl dvmResolveClass @ r0<- resolved ClassObject ptr 10642 cmp r0, #0 @ got null? 10643 beq common_exceptionThrown @ yes, handle exception 10644 mov r1, r0 @ r1<- class resolved from BBB 10645 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 10646 b .LOP_CHECK_CAST_resolved @ pick up where we left off 10647 10648/* continuation for OP_INSTANCE_OF */ 10649 10650 /* 10651 * Trivial test failed, need to perform full check. This is common. 10652 * r0 holds obj->clazz 10653 * r1 holds class resolved from BBBB 10654 * r9 holds A 10655 */ 10656.LOP_INSTANCE_OF_fullcheck: 10657 bl dvmInstanceofNonTrivial @ r0<- boolean result 10658 @ fall through to OP_INSTANCE_OF_store 10659 10660 /* 10661 * r0 holds boolean result 10662 * r9 holds A 10663 */ 10664.LOP_INSTANCE_OF_store: 10665 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10666 SET_VREG(r0, r9) @ vA<- r0 10667 GET_INST_OPCODE(ip) @ extract opcode from rINST 10668 GOTO_OPCODE(ip) @ jump to next instruction 10669 10670 /* 10671 * Trivial test succeeded, save and bail. 10672 * r9 holds A 10673 */ 10674.LOP_INSTANCE_OF_trivial: 10675 mov r0, #1 @ indicate success 10676 @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper 10677 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10678 SET_VREG(r0, r9) @ vA<- r0 10679 GET_INST_OPCODE(ip) @ extract opcode from rINST 10680 GOTO_OPCODE(ip) @ jump to next instruction 10681 10682 /* 10683 * Resolution required. This is the least-likely path. 10684 * 10685 * r3 holds BBBB 10686 * r9 holds A 10687 */ 10688.LOP_INSTANCE_OF_resolve: 10689 EXPORT_PC() @ resolve() could throw 10690 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 10691 mov r1, r3 @ r1<- BBBB 10692 mov r2, #1 @ r2<- true 10693 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10694 bl dvmResolveClass @ r0<- resolved ClassObject ptr 10695 cmp r0, #0 @ got null? 10696 beq common_exceptionThrown @ yes, handle exception 10697 mov r1, r0 @ r1<- class resolved from BBB 10698 mov r3, rINST, lsr #12 @ r3<- B 10699 GET_VREG(r0, r3) @ r0<- vB (object) 10700 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 10701 b .LOP_INSTANCE_OF_resolved @ pick up where we left off 10702 10703/* continuation for OP_NEW_INSTANCE */ 10704 10705 .balign 32 @ minimize cache lines 10706.LOP_NEW_INSTANCE_finish: @ r0=new object 10707 mov r3, rINST, lsr #8 @ r3<- AA 10708 cmp r0, #0 @ failed? 10709 beq common_exceptionThrown @ yes, handle the exception 10710 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10711 GET_INST_OPCODE(ip) @ extract opcode from rINST 10712 SET_VREG(r0, r3) @ vAA<- r0 10713 GOTO_OPCODE(ip) @ jump to next instruction 10714 10715 /* 10716 * Class initialization required. 10717 * 10718 * r0 holds class object 10719 */ 10720.LOP_NEW_INSTANCE_needinit: 10721 mov r9, r0 @ save r0 10722 bl dvmInitClass @ initialize class 10723 cmp r0, #0 @ check boolean result 10724 mov r0, r9 @ restore r0 10725 bne .LOP_NEW_INSTANCE_initialized @ success, continue 10726 b common_exceptionThrown @ failed, deal with init exception 10727 10728 /* 10729 * Resolution required. This is the least-likely path. 10730 * 10731 * r1 holds BBBB 10732 */ 10733.LOP_NEW_INSTANCE_resolve: 10734 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 10735 mov r2, #0 @ r2<- false 10736 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 10737 bl dvmResolveClass @ r0<- resolved ClassObject ptr 10738 cmp r0, #0 @ got null? 10739 bne .LOP_NEW_INSTANCE_resolved @ no, continue 10740 b common_exceptionThrown @ yes, handle exception 10741 10742.LstrInstantiationErrorPtr: 10743 .word .LstrInstantiationError 10744 10745/* continuation for OP_NEW_ARRAY */ 10746 10747 10748 /* 10749 * Resolve class. (This is an uncommon case.) 10750 * 10751 * r1 holds array length 10752 * r2 holds class ref CCCC 10753 */ 10754.LOP_NEW_ARRAY_resolve: 10755 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 10756 mov r9, r1 @ r9<- length (save) 10757 mov r1, r2 @ r1<- CCCC 10758 mov r2, #0 @ r2<- false 10759 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 10760 bl dvmResolveClass @ r0<- call(clazz, ref) 10761 cmp r0, #0 @ got null? 10762 mov r1, r9 @ r1<- length (restore) 10763 beq common_exceptionThrown @ yes, handle exception 10764 @ fall through to OP_NEW_ARRAY_finish 10765 10766 /* 10767 * Finish allocation. 10768 * 10769 * r0 holds class 10770 * r1 holds array length 10771 */ 10772.LOP_NEW_ARRAY_finish: 10773 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 10774 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 10775 cmp r0, #0 @ failed? 10776 mov r2, rINST, lsr #8 @ r2<- A+ 10777 beq common_exceptionThrown @ yes, handle the exception 10778 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10779 and r2, r2, #15 @ r2<- A 10780 GET_INST_OPCODE(ip) @ extract opcode from rINST 10781 SET_VREG(r0, r2) @ vA<- r0 10782 GOTO_OPCODE(ip) @ jump to next instruction 10783 10784/* continuation for OP_FILLED_NEW_ARRAY */ 10785 10786 /* 10787 * On entry: 10788 * r0 holds array class 10789 * r10 holds AA or BA 10790 */ 10791.LOP_FILLED_NEW_ARRAY_continue: 10792 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 10793 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 10794 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 10795 .if 0 10796 mov r1, r10 @ r1<- AA (length) 10797 .else 10798 mov r1, r10, lsr #4 @ r1<- B (length) 10799 .endif 10800 cmp rINST, #'I' @ array of ints? 10801 cmpne rINST, #'L' @ array of objects? 10802 cmpne rINST, #'[' @ array of arrays? 10803 mov r9, r1 @ save length in r9 10804 bne .LOP_FILLED_NEW_ARRAY_notimpl @ no, not handled yet 10805 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 10806 cmp r0, #0 @ null return? 10807 beq common_exceptionThrown @ alloc failed, handle exception 10808 10809 FETCH(r1, 2) @ r1<- FEDC or CCCC 10810 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 10811 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 10812 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 10813 subs r9, r9, #1 @ length--, check for neg 10814 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 10815 bmi 2f @ was zero, bail 10816 10817 @ copy values from registers into the array 10818 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 10819 .if 0 10820 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 108211: ldr r3, [r2], #4 @ r3<- *r2++ 10822 subs r9, r9, #1 @ count-- 10823 str r3, [r0], #4 @ *contents++ = vX 10824 bpl 1b 10825 @ continue at 2 10826 .else 10827 cmp r9, #4 @ length was initially 5? 10828 and r2, r10, #15 @ r2<- A 10829 bne 1f @ <= 4 args, branch 10830 GET_VREG(r3, r2) @ r3<- vA 10831 sub r9, r9, #1 @ count-- 10832 str r3, [r0, #16] @ contents[4] = vA 108331: and r2, r1, #15 @ r2<- F/E/D/C 10834 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 10835 mov r1, r1, lsr #4 @ r1<- next reg in low 4 10836 subs r9, r9, #1 @ count-- 10837 str r3, [r0], #4 @ *contents++ = vX 10838 bpl 1b 10839 @ continue at 2 10840 .endif 10841 108422: 10843 ldr r0, [rSELF, #offThread_retval] @ r0<- object 10844 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 10845 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 10846 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 10847 cmp r1, #'I' @ Is int array? 10848 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 10849 GOTO_OPCODE(ip) @ execute it 10850 10851 /* 10852 * Throw an exception indicating that we have not implemented this 10853 * mode of filled-new-array. 10854 */ 10855.LOP_FILLED_NEW_ARRAY_notimpl: 10856 ldr r0, .L_strInternalError 10857 ldr r1, .L_strFilledNewArrayNotImpl 10858 bl dvmThrowException 10859 b common_exceptionThrown 10860 10861 .if (!0) @ define in one or the other, not both 10862.L_strFilledNewArrayNotImpl: 10863 .word .LstrFilledNewArrayNotImpl 10864.L_strInternalError: 10865 .word .LstrInternalError 10866 .endif 10867 10868/* continuation for OP_FILLED_NEW_ARRAY_RANGE */ 10869 10870 /* 10871 * On entry: 10872 * r0 holds array class 10873 * r10 holds AA or BA 10874 */ 10875.LOP_FILLED_NEW_ARRAY_RANGE_continue: 10876 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 10877 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 10878 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 10879 .if 1 10880 mov r1, r10 @ r1<- AA (length) 10881 .else 10882 mov r1, r10, lsr #4 @ r1<- B (length) 10883 .endif 10884 cmp rINST, #'I' @ array of ints? 10885 cmpne rINST, #'L' @ array of objects? 10886 cmpne rINST, #'[' @ array of arrays? 10887 mov r9, r1 @ save length in r9 10888 bne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl @ no, not handled yet 10889 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 10890 cmp r0, #0 @ null return? 10891 beq common_exceptionThrown @ alloc failed, handle exception 10892 10893 FETCH(r1, 2) @ r1<- FEDC or CCCC 10894 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 10895 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 10896 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 10897 subs r9, r9, #1 @ length--, check for neg 10898 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 10899 bmi 2f @ was zero, bail 10900 10901 @ copy values from registers into the array 10902 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 10903 .if 1 10904 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 109051: ldr r3, [r2], #4 @ r3<- *r2++ 10906 subs r9, r9, #1 @ count-- 10907 str r3, [r0], #4 @ *contents++ = vX 10908 bpl 1b 10909 @ continue at 2 10910 .else 10911 cmp r9, #4 @ length was initially 5? 10912 and r2, r10, #15 @ r2<- A 10913 bne 1f @ <= 4 args, branch 10914 GET_VREG(r3, r2) @ r3<- vA 10915 sub r9, r9, #1 @ count-- 10916 str r3, [r0, #16] @ contents[4] = vA 109171: and r2, r1, #15 @ r2<- F/E/D/C 10918 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 10919 mov r1, r1, lsr #4 @ r1<- next reg in low 4 10920 subs r9, r9, #1 @ count-- 10921 str r3, [r0], #4 @ *contents++ = vX 10922 bpl 1b 10923 @ continue at 2 10924 .endif 10925 109262: 10927 ldr r0, [rSELF, #offThread_retval] @ r0<- object 10928 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 10929 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 10930 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 10931 cmp r1, #'I' @ Is int array? 10932 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 10933 GOTO_OPCODE(ip) @ execute it 10934 10935 /* 10936 * Throw an exception indicating that we have not implemented this 10937 * mode of filled-new-array. 10938 */ 10939.LOP_FILLED_NEW_ARRAY_RANGE_notimpl: 10940 ldr r0, .L_strInternalError 10941 ldr r1, .L_strFilledNewArrayNotImpl 10942 bl dvmThrowException 10943 b common_exceptionThrown 10944 10945 .if (!1) @ define in one or the other, not both 10946.L_strFilledNewArrayNotImpl: 10947 .word .LstrFilledNewArrayNotImpl 10948.L_strInternalError: 10949 .word .LstrInternalError 10950 .endif 10951 10952/* continuation for OP_CMPL_FLOAT */ 10953.LOP_CMPL_FLOAT_finish: 10954 SET_VREG(r0, r9) @ vAA<- r0 10955 GOTO_OPCODE(ip) @ jump to next instruction 10956 10957/* continuation for OP_CMPG_FLOAT */ 10958.LOP_CMPG_FLOAT_finish: 10959 SET_VREG(r0, r9) @ vAA<- r0 10960 GOTO_OPCODE(ip) @ jump to next instruction 10961 10962/* continuation for OP_CMPL_DOUBLE */ 10963.LOP_CMPL_DOUBLE_finish: 10964 SET_VREG(r0, r9) @ vAA<- r0 10965 GOTO_OPCODE(ip) @ jump to next instruction 10966 10967/* continuation for OP_CMPG_DOUBLE */ 10968.LOP_CMPG_DOUBLE_finish: 10969 SET_VREG(r0, r9) @ vAA<- r0 10970 GOTO_OPCODE(ip) @ jump to next instruction 10971 10972/* continuation for OP_CMP_LONG */ 10973 10974.LOP_CMP_LONG_less: 10975 mvn r1, #0 @ r1<- -1 10976 @ Want to cond code the next mov so we can avoid branch, but don't see it; 10977 @ instead, we just replicate the tail end. 10978 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10979 SET_VREG(r1, r9) @ vAA<- r1 10980 GET_INST_OPCODE(ip) @ extract opcode from rINST 10981 GOTO_OPCODE(ip) @ jump to next instruction 10982 10983.LOP_CMP_LONG_greater: 10984 mov r1, #1 @ r1<- 1 10985 @ fall through to _finish 10986 10987.LOP_CMP_LONG_finish: 10988 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10989 SET_VREG(r1, r9) @ vAA<- r1 10990 GET_INST_OPCODE(ip) @ extract opcode from rINST 10991 GOTO_OPCODE(ip) @ jump to next instruction 10992 10993/* continuation for OP_AGET_WIDE */ 10994 10995.LOP_AGET_WIDE_finish: 10996 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10997 ldrd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 10998 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 10999 GET_INST_OPCODE(ip) @ extract opcode from rINST 11000 stmia r9, {r2-r3} @ vAA/vAA+1<- r2/r3 11001 GOTO_OPCODE(ip) @ jump to next instruction 11002 11003/* continuation for OP_APUT_WIDE */ 11004 11005.LOP_APUT_WIDE_finish: 11006 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11007 ldmia r9, {r2-r3} @ r2/r3<- vAA/vAA+1 11008 GET_INST_OPCODE(ip) @ extract opcode from rINST 11009 strd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 11010 GOTO_OPCODE(ip) @ jump to next instruction 11011 11012/* continuation for OP_APUT_OBJECT */ 11013 /* 11014 * On entry: 11015 * rINST = vBB (arrayObj) 11016 * r9 = vAA (obj) 11017 * r10 = offset into array (vBB + vCC * width) 11018 */ 11019.LOP_APUT_OBJECT_finish: 11020 cmp r9, #0 @ storing null reference? 11021 beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks 11022 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 11023 ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz 11024 bl dvmCanPutArrayElement @ test object type vs. array type 11025 cmp r0, #0 @ okay? 11026 beq .LOP_APUT_OBJECT_throw @ no 11027 mov r1, rINST @ r1<- arrayObj 11028 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11029 ldr r2, [rSELF, #offThread_cardTable] @ get biased CT base 11030 add r10, #offArrayObject_contents @ r0<- pointer to slot 11031 GET_INST_OPCODE(ip) @ extract opcode from rINST 11032 str r9, [r10] @ vBB[vCC]<- vAA 11033 strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head 11034 GOTO_OPCODE(ip) @ jump to next instruction 11035.LOP_APUT_OBJECT_skip_check: 11036 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11037 GET_INST_OPCODE(ip) @ extract opcode from rINST 11038 str r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA 11039 GOTO_OPCODE(ip) @ jump to next instruction 11040.LOP_APUT_OBJECT_throw: 11041 @ The types don't match. We need to throw an ArrayStoreException. 11042 ldr r0, [r9, #offObject_clazz] 11043 ldr r1, [rINST, #offObject_clazz] 11044 EXPORT_PC() 11045 bl dvmThrowArrayStoreException 11046 b common_exceptionThrown 11047 11048/* continuation for OP_IGET */ 11049 11050 /* 11051 * Currently: 11052 * r0 holds resolved field 11053 * r9 holds object 11054 */ 11055.LOP_IGET_finish: 11056 @bl common_squeak0 11057 cmp r9, #0 @ check object for null 11058 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11059 beq common_errNullObject @ object was null 11060 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11061 ubfx r2, rINST, #8, #4 @ r2<- A 11062 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11063 GET_INST_OPCODE(ip) @ extract opcode from rINST 11064 SET_VREG(r0, r2) @ fp[A]<- r0 11065 GOTO_OPCODE(ip) @ jump to next instruction 11066 11067/* continuation for OP_IGET_WIDE */ 11068 11069 /* 11070 * Currently: 11071 * r0 holds resolved field 11072 * r9 holds object 11073 */ 11074.LOP_IGET_WIDE_finish: 11075 cmp r9, #0 @ check object for null 11076 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11077 beq common_errNullObject @ object was null 11078 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 11079 ubfx r2, rINST, #8, #4 @ r2<- A 11080 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11081 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 11082 GET_INST_OPCODE(ip) @ extract opcode from rINST 11083 stmia r3, {r0-r1} @ fp[A]<- r0/r1 11084 GOTO_OPCODE(ip) @ jump to next instruction 11085 11086/* continuation for OP_IGET_OBJECT */ 11087 11088 /* 11089 * Currently: 11090 * r0 holds resolved field 11091 * r9 holds object 11092 */ 11093.LOP_IGET_OBJECT_finish: 11094 @bl common_squeak0 11095 cmp r9, #0 @ check object for null 11096 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11097 beq common_errNullObject @ object was null 11098 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11099 @ no-op @ acquiring load 11100 mov r2, rINST, lsr #8 @ r2<- A+ 11101 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11102 and r2, r2, #15 @ r2<- A 11103 GET_INST_OPCODE(ip) @ extract opcode from rINST 11104 SET_VREG(r0, r2) @ fp[A]<- r0 11105 GOTO_OPCODE(ip) @ jump to next instruction 11106 11107/* continuation for OP_IGET_BOOLEAN */ 11108 11109 /* 11110 * Currently: 11111 * r0 holds resolved field 11112 * r9 holds object 11113 */ 11114.LOP_IGET_BOOLEAN_finish: 11115 @bl common_squeak1 11116 cmp r9, #0 @ check object for null 11117 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11118 beq common_errNullObject @ object was null 11119 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11120 @ no-op @ acquiring load 11121 mov r2, rINST, lsr #8 @ r2<- A+ 11122 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11123 and r2, r2, #15 @ r2<- A 11124 GET_INST_OPCODE(ip) @ extract opcode from rINST 11125 SET_VREG(r0, r2) @ fp[A]<- r0 11126 GOTO_OPCODE(ip) @ jump to next instruction 11127 11128/* continuation for OP_IGET_BYTE */ 11129 11130 /* 11131 * Currently: 11132 * r0 holds resolved field 11133 * r9 holds object 11134 */ 11135.LOP_IGET_BYTE_finish: 11136 @bl common_squeak2 11137 cmp r9, #0 @ check object for null 11138 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11139 beq common_errNullObject @ object was null 11140 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11141 @ no-op @ acquiring load 11142 mov r2, rINST, lsr #8 @ r2<- A+ 11143 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11144 and r2, r2, #15 @ r2<- A 11145 GET_INST_OPCODE(ip) @ extract opcode from rINST 11146 SET_VREG(r0, r2) @ fp[A]<- r0 11147 GOTO_OPCODE(ip) @ jump to next instruction 11148 11149/* continuation for OP_IGET_CHAR */ 11150 11151 /* 11152 * Currently: 11153 * r0 holds resolved field 11154 * r9 holds object 11155 */ 11156.LOP_IGET_CHAR_finish: 11157 @bl common_squeak3 11158 cmp r9, #0 @ check object for null 11159 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11160 beq common_errNullObject @ object was null 11161 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11162 @ no-op @ acquiring load 11163 mov r2, rINST, lsr #8 @ r2<- A+ 11164 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11165 and r2, r2, #15 @ r2<- A 11166 GET_INST_OPCODE(ip) @ extract opcode from rINST 11167 SET_VREG(r0, r2) @ fp[A]<- r0 11168 GOTO_OPCODE(ip) @ jump to next instruction 11169 11170/* continuation for OP_IGET_SHORT */ 11171 11172 /* 11173 * Currently: 11174 * r0 holds resolved field 11175 * r9 holds object 11176 */ 11177.LOP_IGET_SHORT_finish: 11178 @bl common_squeak4 11179 cmp r9, #0 @ check object for null 11180 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11181 beq common_errNullObject @ object was null 11182 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11183 @ no-op @ acquiring load 11184 mov r2, rINST, lsr #8 @ r2<- A+ 11185 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11186 and r2, r2, #15 @ r2<- A 11187 GET_INST_OPCODE(ip) @ extract opcode from rINST 11188 SET_VREG(r0, r2) @ fp[A]<- r0 11189 GOTO_OPCODE(ip) @ jump to next instruction 11190 11191/* continuation for OP_IPUT */ 11192 11193 /* 11194 * Currently: 11195 * r0 holds resolved field 11196 * r9 holds object 11197 */ 11198.LOP_IPUT_finish: 11199 @bl common_squeak0 11200 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11201 ubfx r1, rINST, #8, #4 @ r1<- A 11202 cmp r9, #0 @ check object for null 11203 GET_VREG(r0, r1) @ r0<- fp[A] 11204 beq common_errNullObject @ object was null 11205 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11206 GET_INST_OPCODE(ip) @ extract opcode from rINST 11207 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11208 GOTO_OPCODE(ip) @ jump to next instruction 11209 11210/* continuation for OP_IPUT_WIDE */ 11211 11212 /* 11213 * Currently: 11214 * r0 holds resolved field 11215 * r9 holds object 11216 */ 11217.LOP_IPUT_WIDE_finish: 11218 ubfx r2, rINST, #8, #4 @ r2<- A 11219 cmp r9, #0 @ check object for null 11220 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11221 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 11222 beq common_errNullObject @ object was null 11223 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11224 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 11225 GET_INST_OPCODE(ip) @ extract opcode from rINST 11226 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0 11227 GOTO_OPCODE(ip) @ jump to next instruction 11228 11229/* continuation for OP_IPUT_OBJECT */ 11230 11231 /* 11232 * Currently: 11233 * r0 holds resolved field 11234 * r9 holds object 11235 */ 11236.LOP_IPUT_OBJECT_finish: 11237 @bl common_squeak0 11238 mov r1, rINST, lsr #8 @ r1<- A+ 11239 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11240 and r1, r1, #15 @ r1<- A 11241 cmp r9, #0 @ check object for null 11242 GET_VREG(r0, r1) @ r0<- fp[A] 11243 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 11244 beq common_errNullObject @ object was null 11245 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11246 GET_INST_OPCODE(ip) @ extract opcode from rINST 11247 @ no-op @ releasing store 11248 str r0, [r9, r3] @ obj.field (32 bits)<- r0 11249 cmp r0, #0 @ stored a null reference? 11250 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 11251 GOTO_OPCODE(ip) @ jump to next instruction 11252 11253/* continuation for OP_IPUT_BOOLEAN */ 11254 11255 /* 11256 * Currently: 11257 * r0 holds resolved field 11258 * r9 holds object 11259 */ 11260.LOP_IPUT_BOOLEAN_finish: 11261 @bl common_squeak1 11262 mov r1, rINST, lsr #8 @ r1<- A+ 11263 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11264 and r1, r1, #15 @ r1<- A 11265 cmp r9, #0 @ check object for null 11266 GET_VREG(r0, r1) @ r0<- fp[A] 11267 beq common_errNullObject @ object was null 11268 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11269 GET_INST_OPCODE(ip) @ extract opcode from rINST 11270 @ no-op @ releasing store 11271 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11272 GOTO_OPCODE(ip) @ jump to next instruction 11273 11274/* continuation for OP_IPUT_BYTE */ 11275 11276 /* 11277 * Currently: 11278 * r0 holds resolved field 11279 * r9 holds object 11280 */ 11281.LOP_IPUT_BYTE_finish: 11282 @bl common_squeak2 11283 mov r1, rINST, lsr #8 @ r1<- A+ 11284 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11285 and r1, r1, #15 @ r1<- A 11286 cmp r9, #0 @ check object for null 11287 GET_VREG(r0, r1) @ r0<- fp[A] 11288 beq common_errNullObject @ object was null 11289 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11290 GET_INST_OPCODE(ip) @ extract opcode from rINST 11291 @ no-op @ releasing store 11292 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11293 GOTO_OPCODE(ip) @ jump to next instruction 11294 11295/* continuation for OP_IPUT_CHAR */ 11296 11297 /* 11298 * Currently: 11299 * r0 holds resolved field 11300 * r9 holds object 11301 */ 11302.LOP_IPUT_CHAR_finish: 11303 @bl common_squeak3 11304 mov r1, rINST, lsr #8 @ r1<- A+ 11305 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11306 and r1, r1, #15 @ r1<- A 11307 cmp r9, #0 @ check object for null 11308 GET_VREG(r0, r1) @ r0<- fp[A] 11309 beq common_errNullObject @ object was null 11310 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11311 GET_INST_OPCODE(ip) @ extract opcode from rINST 11312 @ no-op @ releasing store 11313 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11314 GOTO_OPCODE(ip) @ jump to next instruction 11315 11316/* continuation for OP_IPUT_SHORT */ 11317 11318 /* 11319 * Currently: 11320 * r0 holds resolved field 11321 * r9 holds object 11322 */ 11323.LOP_IPUT_SHORT_finish: 11324 @bl common_squeak4 11325 mov r1, rINST, lsr #8 @ r1<- A+ 11326 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11327 and r1, r1, #15 @ r1<- A 11328 cmp r9, #0 @ check object for null 11329 GET_VREG(r0, r1) @ r0<- fp[A] 11330 beq common_errNullObject @ object was null 11331 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11332 GET_INST_OPCODE(ip) @ extract opcode from rINST 11333 @ no-op @ releasing store 11334 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11335 GOTO_OPCODE(ip) @ jump to next instruction 11336 11337/* continuation for OP_SGET */ 11338 11339 /* 11340 * Continuation if the field has not yet been resolved. 11341 * r1: BBBB field ref 11342 */ 11343.LOP_SGET_resolve: 11344 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11345 EXPORT_PC() @ resolve() could throw, so export now 11346 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11347 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11348 cmp r0, #0 @ success? 11349 bne .LOP_SGET_finish @ yes, finish 11350 b common_exceptionThrown @ no, handle exception 11351 11352/* continuation for OP_SGET_WIDE */ 11353 11354 /* 11355 * Continuation if the field has not yet been resolved. 11356 * r1: BBBB field ref 11357 * 11358 * Returns StaticField pointer in r0. 11359 */ 11360.LOP_SGET_WIDE_resolve: 11361 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11362 EXPORT_PC() @ resolve() could throw, so export now 11363 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11364 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11365 cmp r0, #0 @ success? 11366 bne .LOP_SGET_WIDE_finish @ yes, finish 11367 b common_exceptionThrown @ no, handle exception 11368 11369/* continuation for OP_SGET_OBJECT */ 11370 11371 /* 11372 * Continuation if the field has not yet been resolved. 11373 * r1: BBBB field ref 11374 */ 11375.LOP_SGET_OBJECT_resolve: 11376 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11377 EXPORT_PC() @ resolve() could throw, so export now 11378 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11379 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11380 cmp r0, #0 @ success? 11381 bne .LOP_SGET_OBJECT_finish @ yes, finish 11382 b common_exceptionThrown @ no, handle exception 11383 11384/* continuation for OP_SGET_BOOLEAN */ 11385 11386 /* 11387 * Continuation if the field has not yet been resolved. 11388 * r1: BBBB field ref 11389 */ 11390.LOP_SGET_BOOLEAN_resolve: 11391 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11392 EXPORT_PC() @ resolve() could throw, so export now 11393 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11394 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11395 cmp r0, #0 @ success? 11396 bne .LOP_SGET_BOOLEAN_finish @ yes, finish 11397 b common_exceptionThrown @ no, handle exception 11398 11399/* continuation for OP_SGET_BYTE */ 11400 11401 /* 11402 * Continuation if the field has not yet been resolved. 11403 * r1: BBBB field ref 11404 */ 11405.LOP_SGET_BYTE_resolve: 11406 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11407 EXPORT_PC() @ resolve() could throw, so export now 11408 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11409 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11410 cmp r0, #0 @ success? 11411 bne .LOP_SGET_BYTE_finish @ yes, finish 11412 b common_exceptionThrown @ no, handle exception 11413 11414/* continuation for OP_SGET_CHAR */ 11415 11416 /* 11417 * Continuation if the field has not yet been resolved. 11418 * r1: BBBB field ref 11419 */ 11420.LOP_SGET_CHAR_resolve: 11421 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11422 EXPORT_PC() @ resolve() could throw, so export now 11423 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11424 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11425 cmp r0, #0 @ success? 11426 bne .LOP_SGET_CHAR_finish @ yes, finish 11427 b common_exceptionThrown @ no, handle exception 11428 11429/* continuation for OP_SGET_SHORT */ 11430 11431 /* 11432 * Continuation if the field has not yet been resolved. 11433 * r1: BBBB field ref 11434 */ 11435.LOP_SGET_SHORT_resolve: 11436 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11437 EXPORT_PC() @ resolve() could throw, so export now 11438 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11439 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11440 cmp r0, #0 @ success? 11441 bne .LOP_SGET_SHORT_finish @ yes, finish 11442 b common_exceptionThrown @ no, handle exception 11443 11444/* continuation for OP_SPUT */ 11445 11446 /* 11447 * Continuation if the field has not yet been resolved. 11448 * r1: BBBB field ref 11449 */ 11450.LOP_SPUT_resolve: 11451 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11452 EXPORT_PC() @ resolve() could throw, so export now 11453 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11454 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11455 cmp r0, #0 @ success? 11456 bne .LOP_SPUT_finish @ yes, finish 11457 b common_exceptionThrown @ no, handle exception 11458 11459/* continuation for OP_SPUT_WIDE */ 11460 11461 /* 11462 * Continuation if the field has not yet been resolved. 11463 * r1: BBBB field ref 11464 * r9: &fp[AA] 11465 * 11466 * Returns StaticField pointer in r2. 11467 */ 11468.LOP_SPUT_WIDE_resolve: 11469 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11470 EXPORT_PC() @ resolve() could throw, so export now 11471 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11472 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11473 cmp r0, #0 @ success? 11474 mov r2, r0 @ copy to r2 11475 bne .LOP_SPUT_WIDE_finish @ yes, finish 11476 b common_exceptionThrown @ no, handle exception 11477 11478/* continuation for OP_SPUT_OBJECT */ 11479.LOP_SPUT_OBJECT_finish: @ field ptr in r0 11480 mov r2, rINST, lsr #8 @ r2<- AA 11481 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11482 GET_VREG(r1, r2) @ r1<- fp[AA] 11483 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 11484 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 11485 GET_INST_OPCODE(ip) @ extract opcode from rINST 11486 @ no-op @ releasing store 11487 str r1, [r0, #offStaticField_value] @ field<- vAA 11488 cmp r1, #0 @ stored a null object? 11489 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 11490 GOTO_OPCODE(ip) @ jump to next instruction 11491 11492/* continuation for OP_SPUT_BOOLEAN */ 11493 11494 /* 11495 * Continuation if the field has not yet been resolved. 11496 * r1: BBBB field ref 11497 */ 11498.LOP_SPUT_BOOLEAN_resolve: 11499 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11500 EXPORT_PC() @ resolve() could throw, so export now 11501 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11502 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11503 cmp r0, #0 @ success? 11504 bne .LOP_SPUT_BOOLEAN_finish @ yes, finish 11505 b common_exceptionThrown @ no, handle exception 11506 11507/* continuation for OP_SPUT_BYTE */ 11508 11509 /* 11510 * Continuation if the field has not yet been resolved. 11511 * r1: BBBB field ref 11512 */ 11513.LOP_SPUT_BYTE_resolve: 11514 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11515 EXPORT_PC() @ resolve() could throw, so export now 11516 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11517 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11518 cmp r0, #0 @ success? 11519 bne .LOP_SPUT_BYTE_finish @ yes, finish 11520 b common_exceptionThrown @ no, handle exception 11521 11522/* continuation for OP_SPUT_CHAR */ 11523 11524 /* 11525 * Continuation if the field has not yet been resolved. 11526 * r1: BBBB field ref 11527 */ 11528.LOP_SPUT_CHAR_resolve: 11529 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11530 EXPORT_PC() @ resolve() could throw, so export now 11531 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11532 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11533 cmp r0, #0 @ success? 11534 bne .LOP_SPUT_CHAR_finish @ yes, finish 11535 b common_exceptionThrown @ no, handle exception 11536 11537/* continuation for OP_SPUT_SHORT */ 11538 11539 /* 11540 * Continuation if the field has not yet been resolved. 11541 * r1: BBBB field ref 11542 */ 11543.LOP_SPUT_SHORT_resolve: 11544 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11545 EXPORT_PC() @ resolve() could throw, so export now 11546 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11547 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11548 cmp r0, #0 @ success? 11549 bne .LOP_SPUT_SHORT_finish @ yes, finish 11550 b common_exceptionThrown @ no, handle exception 11551 11552/* continuation for OP_INVOKE_VIRTUAL */ 11553 11554 /* 11555 * At this point: 11556 * r0 = resolved base method 11557 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 11558 */ 11559.LOP_INVOKE_VIRTUAL_continue: 11560 GET_VREG(r1, r10) @ r1<- "this" ptr 11561 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11562 cmp r1, #0 @ is "this" null? 11563 beq common_errNullObject @ null "this", throw exception 11564 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 11565 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 11566 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 11567 bl common_invokeMethodNoRange @ continue on 11568 11569/* continuation for OP_INVOKE_SUPER */ 11570 11571 /* 11572 * At this point: 11573 * r0 = resolved base method 11574 * r9 = method->clazz 11575 */ 11576.LOP_INVOKE_SUPER_continue: 11577 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 11578 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11579 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 11580 EXPORT_PC() @ must export for invoke 11581 cmp r2, r3 @ compare (methodIndex, vtableCount) 11582 bcs .LOP_INVOKE_SUPER_nsm @ method not present in superclass 11583 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 11584 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 11585 bl common_invokeMethodNoRange @ continue on 11586 11587.LOP_INVOKE_SUPER_resolve: 11588 mov r0, r9 @ r0<- method->clazz 11589 mov r2, #METHOD_VIRTUAL @ resolver method type 11590 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11591 cmp r0, #0 @ got null? 11592 bne .LOP_INVOKE_SUPER_continue @ no, continue 11593 b common_exceptionThrown @ yes, handle exception 11594 11595 /* 11596 * Throw a NoSuchMethodError with the method name as the message. 11597 * r0 = resolved base method 11598 */ 11599.LOP_INVOKE_SUPER_nsm: 11600 ldr r1, [r0, #offMethod_name] @ r1<- method name 11601 b common_errNoSuchMethod 11602 11603/* continuation for OP_INVOKE_DIRECT */ 11604 11605 /* 11606 * On entry: 11607 * r1 = reference (BBBB or CCCC) 11608 * r10 = "this" register 11609 */ 11610.LOP_INVOKE_DIRECT_resolve: 11611 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 11612 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 11613 mov r2, #METHOD_DIRECT @ resolver method type 11614 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11615 cmp r0, #0 @ got null? 11616 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 11617 bne .LOP_INVOKE_DIRECT_finish @ no, continue 11618 b common_exceptionThrown @ yes, handle exception 11619 11620/* continuation for OP_INVOKE_VIRTUAL_RANGE */ 11621 11622 /* 11623 * At this point: 11624 * r0 = resolved base method 11625 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 11626 */ 11627.LOP_INVOKE_VIRTUAL_RANGE_continue: 11628 GET_VREG(r1, r10) @ r1<- "this" ptr 11629 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11630 cmp r1, #0 @ is "this" null? 11631 beq common_errNullObject @ null "this", throw exception 11632 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 11633 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 11634 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 11635 bl common_invokeMethodRange @ continue on 11636 11637/* continuation for OP_INVOKE_SUPER_RANGE */ 11638 11639 /* 11640 * At this point: 11641 * r0 = resolved base method 11642 * r9 = method->clazz 11643 */ 11644.LOP_INVOKE_SUPER_RANGE_continue: 11645 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 11646 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11647 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 11648 EXPORT_PC() @ must export for invoke 11649 cmp r2, r3 @ compare (methodIndex, vtableCount) 11650 bcs .LOP_INVOKE_SUPER_RANGE_nsm @ method not present in superclass 11651 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 11652 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 11653 bl common_invokeMethodRange @ continue on 11654 11655.LOP_INVOKE_SUPER_RANGE_resolve: 11656 mov r0, r9 @ r0<- method->clazz 11657 mov r2, #METHOD_VIRTUAL @ resolver method type 11658 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11659 cmp r0, #0 @ got null? 11660 bne .LOP_INVOKE_SUPER_RANGE_continue @ no, continue 11661 b common_exceptionThrown @ yes, handle exception 11662 11663 /* 11664 * Throw a NoSuchMethodError with the method name as the message. 11665 * r0 = resolved base method 11666 */ 11667.LOP_INVOKE_SUPER_RANGE_nsm: 11668 ldr r1, [r0, #offMethod_name] @ r1<- method name 11669 b common_errNoSuchMethod 11670 11671/* continuation for OP_INVOKE_DIRECT_RANGE */ 11672 11673 /* 11674 * On entry: 11675 * r1 = reference (BBBB or CCCC) 11676 * r10 = "this" register 11677 */ 11678.LOP_INVOKE_DIRECT_RANGE_resolve: 11679 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 11680 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 11681 mov r2, #METHOD_DIRECT @ resolver method type 11682 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11683 cmp r0, #0 @ got null? 11684 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 11685 bne .LOP_INVOKE_DIRECT_RANGE_finish @ no, continue 11686 b common_exceptionThrown @ yes, handle exception 11687 11688/* continuation for OP_FLOAT_TO_LONG */ 11689/* 11690 * Convert the float in r0 to a long in r0/r1. 11691 * 11692 * We have to clip values to long min/max per the specification. The 11693 * expected common case is a "reasonable" value that converts directly 11694 * to modest integer. The EABI convert function isn't doing this for us. 11695 */ 11696f2l_doconv: 11697 stmfd sp!, {r4, lr} 11698 mov r1, #0x5f000000 @ (float)maxlong 11699 mov r4, r0 11700 bl __aeabi_fcmpge @ is arg >= maxlong? 11701 cmp r0, #0 @ nonzero == yes 11702 mvnne r0, #0 @ return maxlong (7fffffff) 11703 mvnne r1, #0x80000000 11704 ldmnefd sp!, {r4, pc} 11705 11706 mov r0, r4 @ recover arg 11707 mov r1, #0xdf000000 @ (float)minlong 11708 bl __aeabi_fcmple @ is arg <= minlong? 11709 cmp r0, #0 @ nonzero == yes 11710 movne r0, #0 @ return minlong (80000000) 11711 movne r1, #0x80000000 11712 ldmnefd sp!, {r4, pc} 11713 11714 mov r0, r4 @ recover arg 11715 mov r1, r4 11716 bl __aeabi_fcmpeq @ is arg == self? 11717 cmp r0, #0 @ zero == no 11718 moveq r1, #0 @ return zero for NaN 11719 ldmeqfd sp!, {r4, pc} 11720 11721 mov r0, r4 @ recover arg 11722 bl __aeabi_f2lz @ convert float to long 11723 ldmfd sp!, {r4, pc} 11724 11725/* continuation for OP_DOUBLE_TO_LONG */ 11726/* 11727 * Convert the double in r0/r1 to a long in r0/r1. 11728 * 11729 * We have to clip values to long min/max per the specification. The 11730 * expected common case is a "reasonable" value that converts directly 11731 * to modest integer. The EABI convert function isn't doing this for us. 11732 */ 11733d2l_doconv: 11734 stmfd sp!, {r4, r5, lr} @ save regs 11735 mov r3, #0x43000000 @ maxlong, as a double (high word) 11736 add r3, #0x00e00000 @ 0x43e00000 11737 mov r2, #0 @ maxlong, as a double (low word) 11738 sub sp, sp, #4 @ align for EABI 11739 mov r4, r0 @ save a copy of r0 11740 mov r5, r1 @ and r1 11741 bl __aeabi_dcmpge @ is arg >= maxlong? 11742 cmp r0, #0 @ nonzero == yes 11743 mvnne r0, #0 @ return maxlong (7fffffffffffffff) 11744 mvnne r1, #0x80000000 11745 bne 1f 11746 11747 mov r0, r4 @ recover arg 11748 mov r1, r5 11749 mov r3, #0xc3000000 @ minlong, as a double (high word) 11750 add r3, #0x00e00000 @ 0xc3e00000 11751 mov r2, #0 @ minlong, as a double (low word) 11752 bl __aeabi_dcmple @ is arg <= minlong? 11753 cmp r0, #0 @ nonzero == yes 11754 movne r0, #0 @ return minlong (8000000000000000) 11755 movne r1, #0x80000000 11756 bne 1f 11757 11758 mov r0, r4 @ recover arg 11759 mov r1, r5 11760 mov r2, r4 @ compare against self 11761 mov r3, r5 11762 bl __aeabi_dcmpeq @ is arg == self? 11763 cmp r0, #0 @ zero == no 11764 moveq r1, #0 @ return zero for NaN 11765 beq 1f 11766 11767 mov r0, r4 @ recover arg 11768 mov r1, r5 11769 bl __aeabi_d2lz @ convert double to long 11770 117711: 11772 add sp, sp, #4 11773 ldmfd sp!, {r4, r5, pc} 11774 11775/* continuation for OP_MUL_LONG */ 11776 11777.LOP_MUL_LONG_finish: 11778 GET_INST_OPCODE(ip) @ extract opcode from rINST 11779 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 11780 GOTO_OPCODE(ip) @ jump to next instruction 11781 11782/* continuation for OP_SHL_LONG */ 11783 11784.LOP_SHL_LONG_finish: 11785 mov r0, r0, asl r2 @ r0<- r0 << r2 11786 GET_INST_OPCODE(ip) @ extract opcode from rINST 11787 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11788 GOTO_OPCODE(ip) @ jump to next instruction 11789 11790/* continuation for OP_SHR_LONG */ 11791 11792.LOP_SHR_LONG_finish: 11793 mov r1, r1, asr r2 @ r1<- r1 >> r2 11794 GET_INST_OPCODE(ip) @ extract opcode from rINST 11795 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11796 GOTO_OPCODE(ip) @ jump to next instruction 11797 11798/* continuation for OP_USHR_LONG */ 11799 11800.LOP_USHR_LONG_finish: 11801 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 11802 GET_INST_OPCODE(ip) @ extract opcode from rINST 11803 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11804 GOTO_OPCODE(ip) @ jump to next instruction 11805 11806/* continuation for OP_SHL_LONG_2ADDR */ 11807 11808.LOP_SHL_LONG_2ADDR_finish: 11809 GET_INST_OPCODE(ip) @ extract opcode from rINST 11810 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11811 GOTO_OPCODE(ip) @ jump to next instruction 11812 11813/* continuation for OP_SHR_LONG_2ADDR */ 11814 11815.LOP_SHR_LONG_2ADDR_finish: 11816 GET_INST_OPCODE(ip) @ extract opcode from rINST 11817 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11818 GOTO_OPCODE(ip) @ jump to next instruction 11819 11820/* continuation for OP_USHR_LONG_2ADDR */ 11821 11822.LOP_USHR_LONG_2ADDR_finish: 11823 GET_INST_OPCODE(ip) @ extract opcode from rINST 11824 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11825 GOTO_OPCODE(ip) @ jump to next instruction 11826 11827/* continuation for OP_IGET_VOLATILE */ 11828 11829 /* 11830 * Currently: 11831 * r0 holds resolved field 11832 * r9 holds object 11833 */ 11834.LOP_IGET_VOLATILE_finish: 11835 @bl common_squeak0 11836 cmp r9, #0 @ check object for null 11837 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11838 beq common_errNullObject @ object was null 11839 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11840 SMP_DMB @ acquiring load 11841 mov r2, rINST, lsr #8 @ r2<- A+ 11842 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11843 and r2, r2, #15 @ r2<- A 11844 GET_INST_OPCODE(ip) @ extract opcode from rINST 11845 SET_VREG(r0, r2) @ fp[A]<- r0 11846 GOTO_OPCODE(ip) @ jump to next instruction 11847 11848/* continuation for OP_IPUT_VOLATILE */ 11849 11850 /* 11851 * Currently: 11852 * r0 holds resolved field 11853 * r9 holds object 11854 */ 11855.LOP_IPUT_VOLATILE_finish: 11856 @bl common_squeak0 11857 mov r1, rINST, lsr #8 @ r1<- A+ 11858 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11859 and r1, r1, #15 @ r1<- A 11860 cmp r9, #0 @ check object for null 11861 GET_VREG(r0, r1) @ r0<- fp[A] 11862 beq common_errNullObject @ object was null 11863 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11864 GET_INST_OPCODE(ip) @ extract opcode from rINST 11865 SMP_DMB @ releasing store 11866 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11867 GOTO_OPCODE(ip) @ jump to next instruction 11868 11869/* continuation for OP_SGET_VOLATILE */ 11870 11871 /* 11872 * Continuation if the field has not yet been resolved. 11873 * r1: BBBB field ref 11874 */ 11875.LOP_SGET_VOLATILE_resolve: 11876 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11877 EXPORT_PC() @ resolve() could throw, so export now 11878 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11879 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11880 cmp r0, #0 @ success? 11881 bne .LOP_SGET_VOLATILE_finish @ yes, finish 11882 b common_exceptionThrown @ no, handle exception 11883 11884/* continuation for OP_SPUT_VOLATILE */ 11885 11886 /* 11887 * Continuation if the field has not yet been resolved. 11888 * r1: BBBB field ref 11889 */ 11890.LOP_SPUT_VOLATILE_resolve: 11891 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11892 EXPORT_PC() @ resolve() could throw, so export now 11893 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11894 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11895 cmp r0, #0 @ success? 11896 bne .LOP_SPUT_VOLATILE_finish @ yes, finish 11897 b common_exceptionThrown @ no, handle exception 11898 11899/* continuation for OP_IGET_OBJECT_VOLATILE */ 11900 11901 /* 11902 * Currently: 11903 * r0 holds resolved field 11904 * r9 holds object 11905 */ 11906.LOP_IGET_OBJECT_VOLATILE_finish: 11907 @bl common_squeak0 11908 cmp r9, #0 @ check object for null 11909 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11910 beq common_errNullObject @ object was null 11911 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11912 SMP_DMB @ acquiring load 11913 mov r2, rINST, lsr #8 @ r2<- A+ 11914 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11915 and r2, r2, #15 @ r2<- A 11916 GET_INST_OPCODE(ip) @ extract opcode from rINST 11917 SET_VREG(r0, r2) @ fp[A]<- r0 11918 GOTO_OPCODE(ip) @ jump to next instruction 11919 11920/* continuation for OP_IGET_WIDE_VOLATILE */ 11921 11922 /* 11923 * Currently: 11924 * r0 holds resolved field 11925 * r9 holds object 11926 */ 11927.LOP_IGET_WIDE_VOLATILE_finish: 11928 cmp r9, #0 @ check object for null 11929 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11930 beq common_errNullObject @ object was null 11931 .if 1 11932 add r0, r9, r3 @ r0<- address of field 11933 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 11934 .else 11935 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 11936 .endif 11937 mov r2, rINST, lsr #8 @ r2<- A+ 11938 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11939 and r2, r2, #15 @ r2<- A 11940 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 11941 GET_INST_OPCODE(ip) @ extract opcode from rINST 11942 stmia r3, {r0-r1} @ fp[A]<- r0/r1 11943 GOTO_OPCODE(ip) @ jump to next instruction 11944 11945/* continuation for OP_IPUT_WIDE_VOLATILE */ 11946 11947 /* 11948 * Currently: 11949 * r0 holds resolved field 11950 * r9 holds object 11951 */ 11952.LOP_IPUT_WIDE_VOLATILE_finish: 11953 mov r2, rINST, lsr #8 @ r2<- A+ 11954 cmp r9, #0 @ check object for null 11955 and r2, r2, #15 @ r2<- A 11956 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11957 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 11958 beq common_errNullObject @ object was null 11959 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11960 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 11961 GET_INST_OPCODE(r10) @ extract opcode from rINST 11962 .if 1 11963 add r2, r9, r3 @ r2<- target address 11964 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 11965 .else 11966 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 11967 .endif 11968 GOTO_OPCODE(r10) @ jump to next instruction 11969 11970/* continuation for OP_SGET_WIDE_VOLATILE */ 11971 11972 /* 11973 * Continuation if the field has not yet been resolved. 11974 * r1: BBBB field ref 11975 * 11976 * Returns StaticField pointer in r0. 11977 */ 11978.LOP_SGET_WIDE_VOLATILE_resolve: 11979 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11980 EXPORT_PC() @ resolve() could throw, so export now 11981 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11982 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11983 cmp r0, #0 @ success? 11984 bne .LOP_SGET_WIDE_VOLATILE_finish @ yes, finish 11985 b common_exceptionThrown @ no, handle exception 11986 11987/* continuation for OP_SPUT_WIDE_VOLATILE */ 11988 11989 /* 11990 * Continuation if the field has not yet been resolved. 11991 * r1: BBBB field ref 11992 * r9: &fp[AA] 11993 * 11994 * Returns StaticField pointer in r2. 11995 */ 11996.LOP_SPUT_WIDE_VOLATILE_resolve: 11997 ldr r2, [rSELF, #offThread_method] @ r2<- current method 11998 EXPORT_PC() @ resolve() could throw, so export now 11999 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12000 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12001 cmp r0, #0 @ success? 12002 mov r2, r0 @ copy to r2 12003 bne .LOP_SPUT_WIDE_VOLATILE_finish @ yes, finish 12004 b common_exceptionThrown @ no, handle exception 12005 12006/* continuation for OP_EXECUTE_INLINE */ 12007 12008 /* 12009 * Extract args, call function. 12010 * r0 = #of args (0-4) 12011 * r10 = call index 12012 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 12013 * 12014 * Other ideas: 12015 * - Use a jump table from the main piece to jump directly into the 12016 * AND/LDR pairs. Costs a data load, saves a branch. 12017 * - Have five separate pieces that do the loading, so we can work the 12018 * interleave a little better. Increases code size. 12019 */ 12020.LOP_EXECUTE_INLINE_continue: 12021 rsb r0, r0, #4 @ r0<- 4-r0 12022 FETCH(r9, 2) @ r9<- FEDC 12023 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 12024 bl common_abort @ (skipped due to ARM prefetch) 120254: and ip, r9, #0xf000 @ isolate F 12026 ldr r3, [rFP, ip, lsr #10] @ r3<- vF (shift right 12, left 2) 120273: and ip, r9, #0x0f00 @ isolate E 12028 ldr r2, [rFP, ip, lsr #6] @ r2<- vE 120292: and ip, r9, #0x00f0 @ isolate D 12030 ldr r1, [rFP, ip, lsr #2] @ r1<- vD 120311: and ip, r9, #0x000f @ isolate C 12032 ldr r0, [rFP, ip, lsl #2] @ r0<- vC 120330: 12034 ldr r9, .LOP_EXECUTE_INLINE_table @ table of InlineOperation 12035 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 12036 @ (not reached) 12037 12038.LOP_EXECUTE_INLINE_table: 12039 .word gDvmInlineOpsTable 12040 12041/* continuation for OP_EXECUTE_INLINE_RANGE */ 12042 12043 /* 12044 * Extract args, call function. 12045 * r0 = #of args (0-4) 12046 * r10 = call index 12047 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 12048 */ 12049.LOP_EXECUTE_INLINE_RANGE_continue: 12050 rsb r0, r0, #4 @ r0<- 4-r0 12051 FETCH(r9, 2) @ r9<- CCCC 12052 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 12053 bl common_abort @ (skipped due to ARM prefetch) 120544: add ip, r9, #3 @ base+3 12055 GET_VREG(r3, ip) @ r3<- vBase[3] 120563: add ip, r9, #2 @ base+2 12057 GET_VREG(r2, ip) @ r2<- vBase[2] 120582: add ip, r9, #1 @ base+1 12059 GET_VREG(r1, ip) @ r1<- vBase[1] 120601: add ip, r9, #0 @ (nop) 12061 GET_VREG(r0, ip) @ r0<- vBase[0] 120620: 12063 ldr r9, .LOP_EXECUTE_INLINE_RANGE_table @ table of InlineOperation 12064 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 12065 @ (not reached) 12066 12067.LOP_EXECUTE_INLINE_RANGE_table: 12068 .word gDvmInlineOpsTable 12069 12070/* continuation for OP_IPUT_OBJECT_VOLATILE */ 12071 12072 /* 12073 * Currently: 12074 * r0 holds resolved field 12075 * r9 holds object 12076 */ 12077.LOP_IPUT_OBJECT_VOLATILE_finish: 12078 @bl common_squeak0 12079 mov r1, rINST, lsr #8 @ r1<- A+ 12080 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12081 and r1, r1, #15 @ r1<- A 12082 cmp r9, #0 @ check object for null 12083 GET_VREG(r0, r1) @ r0<- fp[A] 12084 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 12085 beq common_errNullObject @ object was null 12086 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12087 GET_INST_OPCODE(ip) @ extract opcode from rINST 12088 SMP_DMB @ releasing store 12089 str r0, [r9, r3] @ obj.field (32 bits)<- r0 12090 cmp r0, #0 @ stored a null reference? 12091 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 12092 GOTO_OPCODE(ip) @ jump to next instruction 12093 12094/* continuation for OP_SGET_OBJECT_VOLATILE */ 12095 12096 /* 12097 * Continuation if the field has not yet been resolved. 12098 * r1: BBBB field ref 12099 */ 12100.LOP_SGET_OBJECT_VOLATILE_resolve: 12101 ldr r2, [rSELF, #offThread_method] @ r2<- current method 12102 EXPORT_PC() @ resolve() could throw, so export now 12103 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12104 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12105 cmp r0, #0 @ success? 12106 bne .LOP_SGET_OBJECT_VOLATILE_finish @ yes, finish 12107 b common_exceptionThrown @ no, handle exception 12108 12109/* continuation for OP_SPUT_OBJECT_VOLATILE */ 12110.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0 12111 mov r2, rINST, lsr #8 @ r2<- AA 12112 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12113 GET_VREG(r1, r2) @ r1<- fp[AA] 12114 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 12115 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 12116 GET_INST_OPCODE(ip) @ extract opcode from rINST 12117 SMP_DMB @ releasing store 12118 str r1, [r0, #offStaticField_value] @ field<- vAA 12119 cmp r1, #0 @ stored a null object? 12120 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 12121 GOTO_OPCODE(ip) @ jump to next instruction 12122 12123/* continuation for OP_CONST_CLASS_JUMBO */ 12124 12125 /* 12126 * Continuation if the Class has not yet been resolved. 12127 * r1: AAAAAAAA (Class ref) 12128 * r9: target register 12129 */ 12130.LOP_CONST_CLASS_JUMBO_resolve: 12131 EXPORT_PC() 12132 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 12133 mov r2, #1 @ r2<- true 12134 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 12135 bl dvmResolveClass @ r0<- Class reference 12136 cmp r0, #0 @ failed? 12137 beq common_exceptionThrown @ yup, handle the exception 12138 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12139 GET_INST_OPCODE(ip) @ extract opcode from rINST 12140 SET_VREG(r0, r9) @ vBBBB<- r0 12141 GOTO_OPCODE(ip) @ jump to next instruction 12142 12143/* continuation for OP_CHECK_CAST_JUMBO */ 12144 12145 /* 12146 * Trivial test failed, need to perform full check. This is common. 12147 * r0 holds obj->clazz 12148 * r1 holds desired class resolved from AAAAAAAA 12149 * r9 holds object 12150 */ 12151.LOP_CHECK_CAST_JUMBO_fullcheck: 12152 mov r10, r1 @ avoid ClassObject getting clobbered 12153 bl dvmInstanceofNonTrivial @ r0<- boolean result 12154 cmp r0, #0 @ failed? 12155 bne .LOP_CHECK_CAST_JUMBO_okay @ no, success 12156 12157 @ A cast has failed. We need to throw a ClassCastException. 12158 EXPORT_PC() @ about to throw 12159 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 12160 mov r1, r10 @ r1<- desired class 12161 bl dvmThrowClassCastException 12162 b common_exceptionThrown 12163 12164 /* 12165 * Advance PC and get the next opcode. 12166 */ 12167.LOP_CHECK_CAST_JUMBO_okay: 12168 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12169 GET_INST_OPCODE(ip) @ extract opcode from rINST 12170 GOTO_OPCODE(ip) @ jump to next instruction 12171 12172 /* 12173 * Resolution required. This is the least-likely path. 12174 * 12175 * r2 holds AAAAAAAA 12176 * r9 holds object 12177 */ 12178.LOP_CHECK_CAST_JUMBO_resolve: 12179 EXPORT_PC() @ resolve() could throw 12180 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 12181 mov r1, r2 @ r1<- AAAAAAAA 12182 mov r2, #0 @ r2<- false 12183 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12184 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12185 cmp r0, #0 @ got null? 12186 beq common_exceptionThrown @ yes, handle exception 12187 mov r1, r0 @ r1<- class resolved from AAAAAAAA 12188 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 12189 b .LOP_CHECK_CAST_JUMBO_resolved @ pick up where we left off 12190 12191/* continuation for OP_INSTANCE_OF_JUMBO */ 12192 12193 /* 12194 * Class resolved, determine type of check necessary. This is common. 12195 * r0 holds obj->clazz 12196 * r1 holds class resolved from AAAAAAAA 12197 * r9 holds BBBB 12198 */ 12199.LOP_INSTANCE_OF_JUMBO_resolved: 12200 cmp r0, r1 @ same class (trivial success)? 12201 beq .LOP_INSTANCE_OF_JUMBO_trivial @ yes, trivial finish 12202 @ fall through to OP_INSTANCE_OF_JUMBO_fullcheck 12203 12204 /* 12205 * Trivial test failed, need to perform full check. This is common. 12206 * r0 holds obj->clazz 12207 * r1 holds class resolved from AAAAAAAA 12208 * r9 holds BBBB 12209 */ 12210.LOP_INSTANCE_OF_JUMBO_fullcheck: 12211 bl dvmInstanceofNonTrivial @ r0<- boolean result 12212 @ fall through to OP_INSTANCE_OF_JUMBO_store 12213 12214 /* 12215 * r0 holds boolean result 12216 * r9 holds BBBB 12217 */ 12218.LOP_INSTANCE_OF_JUMBO_store: 12219 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12220 SET_VREG(r0, r9) @ vBBBB<- r0 12221 GET_INST_OPCODE(ip) @ extract opcode from rINST 12222 GOTO_OPCODE(ip) @ jump to next instruction 12223 12224 /* 12225 * Trivial test succeeded, save and bail. 12226 * r9 holds BBBB 12227 */ 12228.LOP_INSTANCE_OF_JUMBO_trivial: 12229 mov r0, #1 @ indicate success 12230 @ could b OP_INSTANCE_OF_JUMBO_store, but copying is faster and cheaper 12231 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12232 SET_VREG(r0, r9) @ vBBBB<- r0 12233 GET_INST_OPCODE(ip) @ extract opcode from rINST 12234 GOTO_OPCODE(ip) @ jump to next instruction 12235 12236 /* 12237 * Resolution required. This is the least-likely path. 12238 * 12239 * r3 holds AAAAAAAA 12240 * r9 holds BBBB 12241 */ 12242 12243.LOP_INSTANCE_OF_JUMBO_resolve: 12244 EXPORT_PC() @ resolve() could throw 12245 ldr r0, [rSELF, #offThread_method] @ r0<- self->method 12246 mov r1, r3 @ r1<- AAAAAAAA 12247 mov r2, #1 @ r2<- true 12248 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 12249 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12250 cmp r0, #0 @ got null? 12251 beq common_exceptionThrown @ yes, handle exception 12252 FETCH(r3, 4) @ r3<- vCCCC 12253 mov r1, r0 @ r1<- class resolved from AAAAAAAA 12254 GET_VREG(r0, r3) @ r0<- vCCCC (object) 12255 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 12256 b .LOP_INSTANCE_OF_JUMBO_resolved @ pick up where we left off 12257 12258/* continuation for OP_NEW_INSTANCE_JUMBO */ 12259 12260 .balign 32 @ minimize cache lines 12261.LOP_NEW_INSTANCE_JUMBO_finish: @ r0=new object 12262 FETCH(r3, 3) @ r3<- BBBB 12263 cmp r0, #0 @ failed? 12264 beq common_exceptionThrown @ yes, handle the exception 12265 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12266 GET_INST_OPCODE(ip) @ extract opcode from rINST 12267 SET_VREG(r0, r3) @ vBBBB<- r0 12268 GOTO_OPCODE(ip) @ jump to next instruction 12269 12270 /* 12271 * Class initialization required. 12272 * 12273 * r0 holds class object 12274 */ 12275.LOP_NEW_INSTANCE_JUMBO_needinit: 12276 mov r9, r0 @ save r0 12277 bl dvmInitClass @ initialize class 12278 cmp r0, #0 @ check boolean result 12279 mov r0, r9 @ restore r0 12280 bne .LOP_NEW_INSTANCE_JUMBO_initialized @ success, continue 12281 b common_exceptionThrown @ failed, deal with init exception 12282 12283 /* 12284 * Resolution required. This is the least-likely path. 12285 * 12286 * r1 holds AAAAAAAA 12287 */ 12288.LOP_NEW_INSTANCE_JUMBO_resolve: 12289 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 12290 mov r2, #0 @ r2<- false 12291 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12292 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12293 cmp r0, #0 @ got null? 12294 bne .LOP_NEW_INSTANCE_JUMBO_resolved @ no, continue 12295 b common_exceptionThrown @ yes, handle exception 12296 12297/* continuation for OP_NEW_ARRAY_JUMBO */ 12298 12299 12300 /* 12301 * Resolve class. (This is an uncommon case.) 12302 * 12303 * r1 holds array length 12304 * r2 holds class ref AAAAAAAA 12305 */ 12306.LOP_NEW_ARRAY_JUMBO_resolve: 12307 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 12308 mov r9, r1 @ r9<- length (save) 12309 mov r1, r2 @ r1<- AAAAAAAA 12310 mov r2, #0 @ r2<- false 12311 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12312 bl dvmResolveClass @ r0<- call(clazz, ref) 12313 cmp r0, #0 @ got null? 12314 mov r1, r9 @ r1<- length (restore) 12315 beq common_exceptionThrown @ yes, handle exception 12316 @ fall through to OP_NEW_ARRAY_JUMBO_finish 12317 12318 /* 12319 * Finish allocation. 12320 * 12321 * r0 holds class 12322 * r1 holds array length 12323 */ 12324.LOP_NEW_ARRAY_JUMBO_finish: 12325 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 12326 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 12327 cmp r0, #0 @ failed? 12328 FETCH(r2, 3) @ r2<- vBBBB 12329 beq common_exceptionThrown @ yes, handle the exception 12330 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12331 GET_INST_OPCODE(ip) @ extract opcode from rINST 12332 SET_VREG(r0, r2) @ vBBBB<- r0 12333 GOTO_OPCODE(ip) @ jump to next instruction 12334 12335/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */ 12336 12337 /* 12338 * On entry: 12339 * r0 holds array class 12340 */ 12341.LOP_FILLED_NEW_ARRAY_JUMBO_continue: 12342 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 12343 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 12344 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 12345 FETCH(r1, 3) @ r1<- BBBB (length) 12346 cmp rINST, #'I' @ array of ints? 12347 cmpne rINST, #'L' @ array of objects? 12348 cmpne rINST, #'[' @ array of arrays? 12349 mov r9, r1 @ save length in r9 12350 bne .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl @ no, not handled yet 12351 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 12352 cmp r0, #0 @ null return? 12353 beq common_exceptionThrown @ alloc failed, handle exception 12354 12355 FETCH(r1, 4) @ r1<- CCCC 12356 str r0, [rSELF, #offThread_retval] @ retval.l <- new array 12357 str rINST, [rSELF, #offThread_retval+4] @ retval.h <- type 12358 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 12359 subs r9, r9, #1 @ length--, check for neg 12360 FETCH_ADVANCE_INST(5) @ advance to next instr, load rINST 12361 bmi 2f @ was zero, bail 12362 12363 @ copy values from registers into the array 12364 @ r0=array, r1=CCCC, r9=BBBB (length) 12365 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 123661: ldr r3, [r2], #4 @ r3<- *r2++ 12367 subs r9, r9, #1 @ count-- 12368 str r3, [r0], #4 @ *contents++ = vX 12369 bpl 1b 12370 123712: ldr r0, [rSELF, #offThread_retval] @ r0<- object 12372 ldr r1, [rSELF, #offThread_retval+4] @ r1<- type 12373 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 12374 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 12375 cmp r1, #'I' @ Is int array? 12376 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 12377 GOTO_OPCODE(ip) @ execute it 12378 12379 /* 12380 * Throw an exception indicating that we have not implemented this 12381 * mode of filled-new-array. 12382 */ 12383.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl: 12384 ldr r0, .L_strInternalError 12385 ldr r1, .L_strFilledNewArrayNotImpl 12386 bl dvmThrowException 12387 b common_exceptionThrown 12388 12389/* continuation for OP_IGET_JUMBO */ 12390 12391 /* 12392 * Currently: 12393 * r0 holds resolved field 12394 * r9 holds object 12395 */ 12396.LOP_IGET_JUMBO_resolved: 12397 cmp r0, #0 @ resolution unsuccessful? 12398 beq common_exceptionThrown @ yes, throw exception 12399 @ fall through to OP_IGET_JUMBO_finish 12400 12401 /* 12402 * Currently: 12403 * r0 holds resolved field 12404 * r9 holds object 12405 */ 12406.LOP_IGET_JUMBO_finish: 12407 @bl common_squeak0 12408 cmp r9, #0 @ check object for null 12409 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12410 beq common_errNullObject @ object was null 12411 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12412 @ no-op @ acquiring load 12413 FETCH(r2, 3) @ r2<- BBBB 12414 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12415 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12416 GET_INST_OPCODE(ip) @ extract opcode from rINST 12417 GOTO_OPCODE(ip) @ jump to next instruction 12418 12419/* continuation for OP_IGET_WIDE_JUMBO */ 12420 12421 /* 12422 * Currently: 12423 * r0 holds resolved field 12424 * r9 holds object 12425 */ 12426.LOP_IGET_WIDE_JUMBO_resolved: 12427 cmp r0, #0 @ resolution unsuccessful? 12428 beq common_exceptionThrown @ yes, throw exception 12429 @ fall through to OP_IGET_WIDE_JUMBO_finish 12430 12431 /* 12432 * Currently: 12433 * r0 holds resolved field 12434 * r9 holds object 12435 */ 12436.LOP_IGET_WIDE_JUMBO_finish: 12437 cmp r9, #0 @ check object for null 12438 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12439 beq common_errNullObject @ object was null 12440 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 12441 FETCH(r2, 3) @ r2<- BBBB 12442 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12443 add r3, rFP, r2, lsl #2 @ r3<- &fp[BBBB] 12444 GET_INST_OPCODE(ip) @ extract opcode from rINST 12445 stmia r3, {r0-r1} @ fp[BBBB]<- r0/r1 12446 GOTO_OPCODE(ip) @ jump to next instruction 12447 12448/* continuation for OP_IGET_OBJECT_JUMBO */ 12449 12450 /* 12451 * Currently: 12452 * r0 holds resolved field 12453 * r9 holds object 12454 */ 12455.LOP_IGET_OBJECT_JUMBO_resolved: 12456 cmp r0, #0 @ resolution unsuccessful? 12457 beq common_exceptionThrown @ yes, throw exception 12458 @ fall through to OP_IGET_OBJECT_JUMBO_finish 12459 12460 /* 12461 * Currently: 12462 * r0 holds resolved field 12463 * r9 holds object 12464 */ 12465.LOP_IGET_OBJECT_JUMBO_finish: 12466 @bl common_squeak0 12467 cmp r9, #0 @ check object for null 12468 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12469 beq common_errNullObject @ object was null 12470 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12471 @ no-op @ acquiring load 12472 FETCH(r2, 3) @ r2<- BBBB 12473 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12474 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12475 GET_INST_OPCODE(ip) @ extract opcode from rINST 12476 GOTO_OPCODE(ip) @ jump to next instruction 12477 12478/* continuation for OP_IGET_BOOLEAN_JUMBO */ 12479 12480 /* 12481 * Currently: 12482 * r0 holds resolved field 12483 * r9 holds object 12484 */ 12485.LOP_IGET_BOOLEAN_JUMBO_resolved: 12486 cmp r0, #0 @ resolution unsuccessful? 12487 beq common_exceptionThrown @ yes, throw exception 12488 @ fall through to OP_IGET_BOOLEAN_JUMBO_finish 12489 12490 /* 12491 * Currently: 12492 * r0 holds resolved field 12493 * r9 holds object 12494 */ 12495.LOP_IGET_BOOLEAN_JUMBO_finish: 12496 @bl common_squeak1 12497 cmp r9, #0 @ check object for null 12498 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12499 beq common_errNullObject @ object was null 12500 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12501 @ no-op @ acquiring load 12502 FETCH(r2, 3) @ r2<- BBBB 12503 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12504 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12505 GET_INST_OPCODE(ip) @ extract opcode from rINST 12506 GOTO_OPCODE(ip) @ jump to next instruction 12507 12508/* continuation for OP_IGET_BYTE_JUMBO */ 12509 12510 /* 12511 * Currently: 12512 * r0 holds resolved field 12513 * r9 holds object 12514 */ 12515.LOP_IGET_BYTE_JUMBO_resolved: 12516 cmp r0, #0 @ resolution unsuccessful? 12517 beq common_exceptionThrown @ yes, throw exception 12518 @ fall through to OP_IGET_BYTE_JUMBO_finish 12519 12520 /* 12521 * Currently: 12522 * r0 holds resolved field 12523 * r9 holds object 12524 */ 12525.LOP_IGET_BYTE_JUMBO_finish: 12526 @bl common_squeak2 12527 cmp r9, #0 @ check object for null 12528 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12529 beq common_errNullObject @ object was null 12530 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12531 @ no-op @ acquiring load 12532 FETCH(r2, 3) @ r2<- BBBB 12533 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12534 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12535 GET_INST_OPCODE(ip) @ extract opcode from rINST 12536 GOTO_OPCODE(ip) @ jump to next instruction 12537 12538/* continuation for OP_IGET_CHAR_JUMBO */ 12539 12540 /* 12541 * Currently: 12542 * r0 holds resolved field 12543 * r9 holds object 12544 */ 12545.LOP_IGET_CHAR_JUMBO_resolved: 12546 cmp r0, #0 @ resolution unsuccessful? 12547 beq common_exceptionThrown @ yes, throw exception 12548 @ fall through to OP_IGET_CHAR_JUMBO_finish 12549 12550 /* 12551 * Currently: 12552 * r0 holds resolved field 12553 * r9 holds object 12554 */ 12555.LOP_IGET_CHAR_JUMBO_finish: 12556 @bl common_squeak3 12557 cmp r9, #0 @ check object for null 12558 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12559 beq common_errNullObject @ object was null 12560 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12561 @ no-op @ acquiring load 12562 FETCH(r2, 3) @ r2<- BBBB 12563 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12564 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12565 GET_INST_OPCODE(ip) @ extract opcode from rINST 12566 GOTO_OPCODE(ip) @ jump to next instruction 12567 12568/* continuation for OP_IGET_SHORT_JUMBO */ 12569 12570 /* 12571 * Currently: 12572 * r0 holds resolved field 12573 * r9 holds object 12574 */ 12575.LOP_IGET_SHORT_JUMBO_resolved: 12576 cmp r0, #0 @ resolution unsuccessful? 12577 beq common_exceptionThrown @ yes, throw exception 12578 @ fall through to OP_IGET_SHORT_JUMBO_finish 12579 12580 /* 12581 * Currently: 12582 * r0 holds resolved field 12583 * r9 holds object 12584 */ 12585.LOP_IGET_SHORT_JUMBO_finish: 12586 @bl common_squeak4 12587 cmp r9, #0 @ check object for null 12588 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12589 beq common_errNullObject @ object was null 12590 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12591 @ no-op @ acquiring load 12592 FETCH(r2, 3) @ r2<- BBBB 12593 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12594 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12595 GET_INST_OPCODE(ip) @ extract opcode from rINST 12596 GOTO_OPCODE(ip) @ jump to next instruction 12597 12598/* continuation for OP_IPUT_JUMBO */ 12599 12600 /* 12601 * Currently: 12602 * r0 holds resolved field 12603 * r9 holds object 12604 */ 12605.LOP_IPUT_JUMBO_resolved: 12606 cmp r0, #0 @ resolution unsuccessful? 12607 beq common_exceptionThrown @ yes, throw exception 12608 @ fall through to OP_IPUT_JUMBO_finish 12609 12610 /* 12611 * Currently: 12612 * r0 holds resolved field 12613 * r9 holds object 12614 */ 12615.LOP_IPUT_JUMBO_finish: 12616 @bl common_squeak0 12617 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12618 FETCH(r1, 3) @ r1<- BBBB 12619 cmp r9, #0 @ check object for null 12620 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12621 beq common_errNullObject @ object was null 12622 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12623 GET_INST_OPCODE(ip) @ extract opcode from rINST 12624 @ no-op @ releasing store 12625 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12626 GOTO_OPCODE(ip) @ jump to next instruction 12627 12628/* continuation for OP_IPUT_WIDE_JUMBO */ 12629 12630 /* 12631 * Currently: 12632 * r0 holds resolved field 12633 * r9 holds object 12634 */ 12635.LOP_IPUT_WIDE_JUMBO_resolved: 12636 cmp r0, #0 @ resolution unsuccessful? 12637 beq common_exceptionThrown @ yes, throw exception 12638 @ fall through to OP_IPUT_WIDE_JUMBO_finish 12639 12640 /* 12641 * Currently: 12642 * r0 holds resolved field 12643 * r9 holds object 12644 */ 12645.LOP_IPUT_WIDE_JUMBO_finish: 12646 cmp r9, #0 @ check object for null 12647 FETCH(r2, 3) @ r1<- BBBB 12648 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12649 add r2, rFP, r2, lsl #2 @ r3<- &fp[BBBB] 12650 beq common_errNullObject @ object was null 12651 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12652 ldmia r2, {r0-r1} @ r0/r1<- fp[BBBB] 12653 GET_INST_OPCODE(r10) @ extract opcode from rINST 12654 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 12655 GOTO_OPCODE(r10) @ jump to next instruction 12656 12657/* continuation for OP_IPUT_OBJECT_JUMBO */ 12658 12659 /* 12660 * Currently: 12661 * r0 holds resolved field 12662 * r9 holds object 12663 */ 12664.LOP_IPUT_OBJECT_JUMBO_resolved: 12665 cmp r0, #0 @ resolution unsuccessful? 12666 beq common_exceptionThrown @ yes, throw exception 12667 @ fall through to OP_IPUT_OBJECT_JUMBO_finish 12668 12669 /* 12670 * Currently: 12671 * r0 holds resolved field 12672 * r9 holds object 12673 */ 12674.LOP_IPUT_OBJECT_JUMBO_finish: 12675 @bl common_squeak0 12676 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12677 FETCH(r1, 3) @ r1<- BBBB 12678 cmp r9, #0 @ check object for null 12679 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12680 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 12681 beq common_errNullObject @ object was null 12682 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12683 GET_INST_OPCODE(ip) @ extract opcode from rINST 12684 @ no-op @ releasing store 12685 str r0, [r9, r3] @ obj.field (32 bits)<- r0 12686 cmp r0, #0 @ stored a null reference? 12687 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 12688 GOTO_OPCODE(ip) @ jump to next instruction 12689 12690/* continuation for OP_IPUT_BOOLEAN_JUMBO */ 12691 12692 /* 12693 * Currently: 12694 * r0 holds resolved field 12695 * r9 holds object 12696 */ 12697.LOP_IPUT_BOOLEAN_JUMBO_resolved: 12698 cmp r0, #0 @ resolution unsuccessful? 12699 beq common_exceptionThrown @ yes, throw exception 12700 @ fall through to OP_IPUT_BOOLEAN_JUMBO_finish 12701 12702 /* 12703 * Currently: 12704 * r0 holds resolved field 12705 * r9 holds object 12706 */ 12707.LOP_IPUT_BOOLEAN_JUMBO_finish: 12708 @bl common_squeak1 12709 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12710 FETCH(r1, 3) @ r1<- BBBB 12711 cmp r9, #0 @ check object for null 12712 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12713 beq common_errNullObject @ object was null 12714 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12715 GET_INST_OPCODE(ip) @ extract opcode from rINST 12716 @ no-op @ releasing store 12717 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12718 GOTO_OPCODE(ip) @ jump to next instruction 12719 12720/* continuation for OP_IPUT_BYTE_JUMBO */ 12721 12722 /* 12723 * Currently: 12724 * r0 holds resolved field 12725 * r9 holds object 12726 */ 12727.LOP_IPUT_BYTE_JUMBO_resolved: 12728 cmp r0, #0 @ resolution unsuccessful? 12729 beq common_exceptionThrown @ yes, throw exception 12730 @ fall through to OP_IPUT_BYTE_JUMBO_finish 12731 12732 /* 12733 * Currently: 12734 * r0 holds resolved field 12735 * r9 holds object 12736 */ 12737.LOP_IPUT_BYTE_JUMBO_finish: 12738 @bl common_squeak2 12739 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12740 FETCH(r1, 3) @ r1<- BBBB 12741 cmp r9, #0 @ check object for null 12742 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12743 beq common_errNullObject @ object was null 12744 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12745 GET_INST_OPCODE(ip) @ extract opcode from rINST 12746 @ no-op @ releasing store 12747 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12748 GOTO_OPCODE(ip) @ jump to next instruction 12749 12750/* continuation for OP_IPUT_CHAR_JUMBO */ 12751 12752 /* 12753 * Currently: 12754 * r0 holds resolved field 12755 * r9 holds object 12756 */ 12757.LOP_IPUT_CHAR_JUMBO_resolved: 12758 cmp r0, #0 @ resolution unsuccessful? 12759 beq common_exceptionThrown @ yes, throw exception 12760 @ fall through to OP_IPUT_CHAR_JUMBO_finish 12761 12762 /* 12763 * Currently: 12764 * r0 holds resolved field 12765 * r9 holds object 12766 */ 12767.LOP_IPUT_CHAR_JUMBO_finish: 12768 @bl common_squeak3 12769 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12770 FETCH(r1, 3) @ r1<- BBBB 12771 cmp r9, #0 @ check object for null 12772 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12773 beq common_errNullObject @ object was null 12774 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12775 GET_INST_OPCODE(ip) @ extract opcode from rINST 12776 @ no-op @ releasing store 12777 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12778 GOTO_OPCODE(ip) @ jump to next instruction 12779 12780/* continuation for OP_IPUT_SHORT_JUMBO */ 12781 12782 /* 12783 * Currently: 12784 * r0 holds resolved field 12785 * r9 holds object 12786 */ 12787.LOP_IPUT_SHORT_JUMBO_resolved: 12788 cmp r0, #0 @ resolution unsuccessful? 12789 beq common_exceptionThrown @ yes, throw exception 12790 @ fall through to OP_IPUT_SHORT_JUMBO_finish 12791 12792 /* 12793 * Currently: 12794 * r0 holds resolved field 12795 * r9 holds object 12796 */ 12797.LOP_IPUT_SHORT_JUMBO_finish: 12798 @bl common_squeak4 12799 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12800 FETCH(r1, 3) @ r1<- BBBB 12801 cmp r9, #0 @ check object for null 12802 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12803 beq common_errNullObject @ object was null 12804 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12805 GET_INST_OPCODE(ip) @ extract opcode from rINST 12806 @ no-op @ releasing store 12807 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12808 GOTO_OPCODE(ip) @ jump to next instruction 12809 12810/* continuation for OP_SGET_JUMBO */ 12811 12812 /* 12813 * Continuation if the field has not yet been resolved. 12814 * r1: AAAAAAAA field ref 12815 */ 12816.LOP_SGET_JUMBO_resolve: 12817 ldr r2, [rSELF, #offThread_method] @ r2<- current method 12818 EXPORT_PC() @ resolve() could throw, so export now 12819 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12820 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12821 cmp r0, #0 @ success? 12822 bne .LOP_SGET_JUMBO_finish @ yes, finish 12823 b common_exceptionThrown @ no, handle exception 12824 12825/* continuation for OP_SGET_WIDE_JUMBO */ 12826 12827 /* 12828 * Continuation if the field has not yet been resolved. 12829 * r1: BBBB field ref 12830 * 12831 * Returns StaticField pointer in r0. 12832 */ 12833.LOP_SGET_WIDE_JUMBO_resolve: 12834 ldr r2, [rSELF, #offThread_method] @ r2<- current method 12835 EXPORT_PC() @ resolve() could throw, so export now 12836 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12837 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12838 cmp r0, #0 @ success? 12839 bne .LOP_SGET_WIDE_JUMBO_finish @ yes, finish 12840 b common_exceptionThrown @ no, handle exception 12841 12842/* continuation for OP_SGET_OBJECT_JUMBO */ 12843 12844 /* 12845 * Continuation if the field has not yet been resolved. 12846 * r1: AAAAAAAA field ref 12847 */ 12848.LOP_SGET_OBJECT_JUMBO_resolve: 12849 ldr r2, [rSELF, #offThread_method] @ r2<- current method 12850 EXPORT_PC() @ resolve() could throw, so export now 12851 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12852 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12853 cmp r0, #0 @ success? 12854 bne .LOP_SGET_OBJECT_JUMBO_finish @ yes, finish 12855 b common_exceptionThrown @ no, handle exception 12856 12857/* continuation for OP_SGET_BOOLEAN_JUMBO */ 12858 12859 /* 12860 * Continuation if the field has not yet been resolved. 12861 * r1: AAAAAAAA field ref 12862 */ 12863.LOP_SGET_BOOLEAN_JUMBO_resolve: 12864 ldr r2, [rSELF, #offThread_method] @ r2<- current method 12865 EXPORT_PC() @ resolve() could throw, so export now 12866 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12867 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12868 cmp r0, #0 @ success? 12869 bne .LOP_SGET_BOOLEAN_JUMBO_finish @ yes, finish 12870 b common_exceptionThrown @ no, handle exception 12871 12872/* continuation for OP_SGET_BYTE_JUMBO */ 12873 12874 /* 12875 * Continuation if the field has not yet been resolved. 12876 * r1: AAAAAAAA field ref 12877 */ 12878.LOP_SGET_BYTE_JUMBO_resolve: 12879 ldr r2, [rSELF, #offThread_method] @ r2<- current method 12880 EXPORT_PC() @ resolve() could throw, so export now 12881 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12882 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12883 cmp r0, #0 @ success? 12884 bne .LOP_SGET_BYTE_JUMBO_finish @ yes, finish 12885 b common_exceptionThrown @ no, handle exception 12886 12887/* continuation for OP_SGET_CHAR_JUMBO */ 12888 12889 /* 12890 * Continuation if the field has not yet been resolved. 12891 * r1: AAAAAAAA field ref 12892 */ 12893.LOP_SGET_CHAR_JUMBO_resolve: 12894 ldr r2, [rSELF, #offThread_method] @ r2<- current method 12895 EXPORT_PC() @ resolve() could throw, so export now 12896 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12897 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12898 cmp r0, #0 @ success? 12899 bne .LOP_SGET_CHAR_JUMBO_finish @ yes, finish 12900 b common_exceptionThrown @ no, handle exception 12901 12902/* continuation for OP_SGET_SHORT_JUMBO */ 12903 12904 /* 12905 * Continuation if the field has not yet been resolved. 12906 * r1: AAAAAAAA field ref 12907 */ 12908.LOP_SGET_SHORT_JUMBO_resolve: 12909 ldr r2, [rSELF, #offThread_method] @ r2<- current method 12910 EXPORT_PC() @ resolve() could throw, so export now 12911 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12912 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12913 cmp r0, #0 @ success? 12914 bne .LOP_SGET_SHORT_JUMBO_finish @ yes, finish 12915 b common_exceptionThrown @ no, handle exception 12916 12917/* continuation for OP_SPUT_JUMBO */ 12918 12919 /* 12920 * Continuation if the field has not yet been resolved. 12921 * r1: AAAAAAAA field ref 12922 */ 12923.LOP_SPUT_JUMBO_resolve: 12924 ldr r2, [rSELF, #offThread_method] @ r2<- current method 12925 EXPORT_PC() @ resolve() could throw, so export now 12926 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12927 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12928 cmp r0, #0 @ success? 12929 bne .LOP_SPUT_JUMBO_finish @ yes, finish 12930 b common_exceptionThrown @ no, handle exception 12931 12932/* continuation for OP_SPUT_WIDE_JUMBO */ 12933 12934 /* 12935 * Continuation if the field has not yet been resolved. 12936 * r1: BBBB field ref 12937 * r9: &fp[AA] 12938 * 12939 * Returns StaticField pointer in r2. 12940 */ 12941.LOP_SPUT_WIDE_JUMBO_resolve: 12942 ldr r2, [rSELF, #offThread_method] @ r2<- current method 12943 EXPORT_PC() @ resolve() could throw, so export now 12944 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12945 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12946 cmp r0, #0 @ success? 12947 mov r2, r0 @ copy to r2 12948 bne .LOP_SPUT_WIDE_JUMBO_finish @ yes, finish 12949 b common_exceptionThrown @ no, handle exception 12950 12951/* continuation for OP_SPUT_OBJECT_JUMBO */ 12952 12953.LOP_SPUT_OBJECT_JUMBO_finish: @ field ptr in r0 12954 FETCH(r2, 3) @ r2<- BBBB 12955 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12956 GET_VREG(r1, r2) @ r1<- fp[BBBB] 12957 ldr r2, [rSELF, #offThread_cardTable] @ r2<- card table base 12958 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 12959 GET_INST_OPCODE(ip) @ extract opcode from rINST 12960 @ no-op @ releasing store 12961 str r1, [r0, #offStaticField_value] @ field<- vBBBB 12962 cmp r1, #0 @ stored a null object? 12963 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 12964 GOTO_OPCODE(ip) @ jump to next instruction 12965 12966/* continuation for OP_SPUT_BOOLEAN_JUMBO */ 12967 12968 /* 12969 * Continuation if the field has not yet been resolved. 12970 * r1: AAAAAAAA field ref 12971 */ 12972.LOP_SPUT_BOOLEAN_JUMBO_resolve: 12973 ldr r2, [rSELF, #offThread_method] @ r2<- current method 12974 EXPORT_PC() @ resolve() could throw, so export now 12975 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12976 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12977 cmp r0, #0 @ success? 12978 bne .LOP_SPUT_BOOLEAN_JUMBO_finish @ yes, finish 12979 b common_exceptionThrown @ no, handle exception 12980 12981/* continuation for OP_SPUT_BYTE_JUMBO */ 12982 12983 /* 12984 * Continuation if the field has not yet been resolved. 12985 * r1: AAAAAAAA field ref 12986 */ 12987.LOP_SPUT_BYTE_JUMBO_resolve: 12988 ldr r2, [rSELF, #offThread_method] @ r2<- current method 12989 EXPORT_PC() @ resolve() could throw, so export now 12990 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12991 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12992 cmp r0, #0 @ success? 12993 bne .LOP_SPUT_BYTE_JUMBO_finish @ yes, finish 12994 b common_exceptionThrown @ no, handle exception 12995 12996/* continuation for OP_SPUT_CHAR_JUMBO */ 12997 12998 /* 12999 * Continuation if the field has not yet been resolved. 13000 * r1: AAAAAAAA field ref 13001 */ 13002.LOP_SPUT_CHAR_JUMBO_resolve: 13003 ldr r2, [rSELF, #offThread_method] @ r2<- current method 13004 EXPORT_PC() @ resolve() could throw, so export now 13005 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13006 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13007 cmp r0, #0 @ success? 13008 bne .LOP_SPUT_CHAR_JUMBO_finish @ yes, finish 13009 b common_exceptionThrown @ no, handle exception 13010 13011/* continuation for OP_SPUT_SHORT_JUMBO */ 13012 13013 /* 13014 * Continuation if the field has not yet been resolved. 13015 * r1: AAAAAAAA field ref 13016 */ 13017.LOP_SPUT_SHORT_JUMBO_resolve: 13018 ldr r2, [rSELF, #offThread_method] @ r2<- current method 13019 EXPORT_PC() @ resolve() could throw, so export now 13020 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13021 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13022 cmp r0, #0 @ success? 13023 bne .LOP_SPUT_SHORT_JUMBO_finish @ yes, finish 13024 b common_exceptionThrown @ no, handle exception 13025 13026/* continuation for OP_INVOKE_VIRTUAL_JUMBO */ 13027 13028 /* 13029 * At this point: 13030 * r0 = resolved base method 13031 */ 13032.LOP_INVOKE_VIRTUAL_JUMBO_continue: 13033 FETCH(r10, 4) @ r10<- CCCC 13034 GET_VREG(r1, r10) @ r1<- "this" ptr 13035 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 13036 cmp r1, #0 @ is "this" null? 13037 beq common_errNullObject @ null "this", throw exception 13038 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 13039 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 13040 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 13041 bl common_invokeMethodJumbo @ continue on 13042 13043/* continuation for OP_INVOKE_SUPER_JUMBO */ 13044 13045 /* 13046 * At this point: 13047 * r0 = resolved base method 13048 * r9 = method->clazz 13049 */ 13050.LOP_INVOKE_SUPER_JUMBO_continue: 13051 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 13052 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 13053 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 13054 EXPORT_PC() @ must export for invoke 13055 cmp r2, r3 @ compare (methodIndex, vtableCount) 13056 bcs .LOP_INVOKE_SUPER_JUMBO_nsm @ method not present in superclass 13057 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 13058 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 13059 bl common_invokeMethodJumbo @ continue on 13060 13061.LOP_INVOKE_SUPER_JUMBO_resolve: 13062 mov r0, r9 @ r0<- method->clazz 13063 mov r2, #METHOD_VIRTUAL @ resolver method type 13064 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 13065 cmp r0, #0 @ got null? 13066 bne .LOP_INVOKE_SUPER_JUMBO_continue @ no, continue 13067 b common_exceptionThrown @ yes, handle exception 13068 13069 /* 13070 * Throw a NoSuchMethodError with the method name as the message. 13071 * r0 = resolved base method 13072 */ 13073.LOP_INVOKE_SUPER_JUMBO_nsm: 13074 ldr r1, [r0, #offMethod_name] @ r1<- method name 13075 b common_errNoSuchMethod 13076 13077/* continuation for OP_INVOKE_DIRECT_JUMBO */ 13078 13079 /* 13080 * On entry: 13081 * r1 = reference (CCCC) 13082 * r10 = "this" register 13083 */ 13084.LOP_INVOKE_DIRECT_JUMBO_resolve: 13085 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 13086 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 13087 mov r2, #METHOD_DIRECT @ resolver method type 13088 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 13089 cmp r0, #0 @ got null? 13090 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 13091 bne .LOP_INVOKE_DIRECT_JUMBO_finish @ no, continue 13092 b common_exceptionThrown @ yes, handle exception 13093 13094 .size dvmAsmSisterStart, .-dvmAsmSisterStart 13095 .global dvmAsmSisterEnd 13096dvmAsmSisterEnd: 13097 13098/* File: armv5te/footer.S */ 13099 13100/* 13101 * =========================================================================== 13102 * Common subroutines and data 13103 * =========================================================================== 13104 */ 13105 13106 13107 13108 .text 13109 .align 2 13110 13111#if defined(WITH_JIT) 13112#if defined(WITH_SELF_VERIFICATION) 13113 .global dvmJitToInterpPunt 13114dvmJitToInterpPunt: 13115 mov r2,#kSVSPunt @ r2<- interpreter entry point 13116 mov r3, #0 13117 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 13118 b jitSVShadowRunEnd @ doesn't return 13119 13120 .global dvmJitToInterpSingleStep 13121dvmJitToInterpSingleStep: 13122 str lr,[rSELF,#offThread_jitResumeNPC] 13123 str r1,[rSELF,#offThread_jitResumeDPC] 13124 mov r2,#kSVSSingleStep @ r2<- interpreter entry point 13125 b jitSVShadowRunEnd @ doesn't return 13126 13127 .global dvmJitToInterpNoChainNoProfile 13128dvmJitToInterpNoChainNoProfile: 13129 mov r0,rPC @ pass our target PC 13130 mov r2,#kSVSNoProfile @ r2<- interpreter entry point 13131 mov r3, #0 @ 0 means !inJitCodeCache 13132 str r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 13133 b jitSVShadowRunEnd @ doesn't return 13134 13135 .global dvmJitToInterpTraceSelectNoChain 13136dvmJitToInterpTraceSelectNoChain: 13137 mov r0,rPC @ pass our target PC 13138 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 13139 mov r3, #0 @ 0 means !inJitCodeCache 13140 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 13141 b jitSVShadowRunEnd @ doesn't return 13142 13143 .global dvmJitToInterpTraceSelect 13144dvmJitToInterpTraceSelect: 13145 ldr r0,[lr, #-1] @ pass our target PC 13146 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 13147 mov r3, #0 @ 0 means !inJitCodeCache 13148 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 13149 b jitSVShadowRunEnd @ doesn't return 13150 13151 .global dvmJitToInterpBackwardBranch 13152dvmJitToInterpBackwardBranch: 13153 ldr r0,[lr, #-1] @ pass our target PC 13154 mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point 13155 mov r3, #0 @ 0 means !inJitCodeCache 13156 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 13157 b jitSVShadowRunEnd @ doesn't return 13158 13159 .global dvmJitToInterpNormal 13160dvmJitToInterpNormal: 13161 ldr r0,[lr, #-1] @ pass our target PC 13162 mov r2,#kSVSNormal @ r2<- interpreter entry point 13163 mov r3, #0 @ 0 means !inJitCodeCache 13164 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 13165 b jitSVShadowRunEnd @ doesn't return 13166 13167 .global dvmJitToInterpNoChain 13168dvmJitToInterpNoChain: 13169 mov r0,rPC @ pass our target PC 13170 mov r2,#kSVSNoChain @ r2<- interpreter entry point 13171 mov r3, #0 @ 0 means !inJitCodeCache 13172 str r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 13173 b jitSVShadowRunEnd @ doesn't return 13174#else 13175/* 13176 * Return from the translation cache to the interpreter when the compiler is 13177 * having issues translating/executing a Dalvik instruction. We have to skip 13178 * the code cache lookup otherwise it is possible to indefinitely bouce 13179 * between the interpreter and the code cache if the instruction that fails 13180 * to be compiled happens to be at a trace start. 13181 */ 13182 .global dvmJitToInterpPunt 13183dvmJitToInterpPunt: 13184 mov rPC, r0 13185#if defined(WITH_JIT_TUNING) 13186 mov r0,lr 13187 bl dvmBumpPunt; 13188#endif 13189 EXPORT_PC() 13190 mov r0, #0 13191 str r0, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land 13192 adrl rIBASE, dvmAsmInstructionStart 13193 FETCH_INST() 13194 GET_INST_OPCODE(ip) 13195 GOTO_OPCODE(ip) 13196 13197/* 13198 * Return to the interpreter to handle a single instruction. 13199 * On entry: 13200 * r0 <= PC 13201 * r1 <= PC of resume instruction 13202 * lr <= resume point in translation 13203 */ 13204 .global dvmJitToInterpSingleStep 13205dvmJitToInterpSingleStep: 13206 str lr,[rSELF,#offThread_jitResumeNPC] 13207 str r1,[rSELF,#offThread_jitResumeDPC] 13208 mov r1,#kInterpEntryInstr 13209 @ enum is 4 byte in aapcs-EABI 13210 str r1, [rSELF, #offThread_entryPoint] 13211 mov rPC,r0 13212 EXPORT_PC() 13213 13214 adrl rIBASE, dvmAsmInstructionStart 13215 mov r2,#kJitSingleStep @ Ask for single step and then revert 13216 str r2,[rSELF,#offThread_jitState] 13217 mov r1,#1 @ set changeInterp to bail to debug interp 13218 b common_gotoBail 13219 13220/* 13221 * Return from the translation cache and immediately request 13222 * a translation for the exit target. Commonly used for callees. 13223 */ 13224 .global dvmJitToInterpTraceSelectNoChain 13225dvmJitToInterpTraceSelectNoChain: 13226#if defined(WITH_JIT_TUNING) 13227 bl dvmBumpNoChain 13228#endif 13229 mov r0,rPC 13230 bl dvmJitGetTraceAddr @ Is there a translation? 13231 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13232 mov r1, rPC @ arg1 of translation may need this 13233 mov lr, #0 @ in case target is HANDLER_INTERPRET 13234 cmp r0,#0 @ !0 means translation exists 13235 bxne r0 @ continue native execution if so 13236 b 2f @ branch over to use the interpreter 13237 13238/* 13239 * Return from the translation cache and immediately request 13240 * a translation for the exit target. Commonly used following 13241 * invokes. 13242 */ 13243 .global dvmJitToInterpTraceSelect 13244dvmJitToInterpTraceSelect: 13245 ldr rPC,[lr, #-1] @ get our target PC 13246 add rINST,lr,#-5 @ save start of chain branch 13247 add rINST, #-4 @ .. which is 9 bytes back 13248 mov r0,rPC 13249 bl dvmJitGetTraceAddr @ Is there a translation? 13250 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13251 cmp r0,#0 13252 beq 2f 13253 mov r1,rINST 13254 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 13255 mov r1, rPC @ arg1 of translation may need this 13256 mov lr, #0 @ in case target is HANDLER_INTERPRET 13257 cmp r0,#0 @ successful chain? 13258 bxne r0 @ continue native execution 13259 b toInterpreter @ didn't chain - resume with interpreter 13260 13261/* No translation, so request one if profiling isn't disabled*/ 132622: 13263 adrl rIBASE, dvmAsmInstructionStart 13264 GET_JIT_PROF_TABLE(r0) 13265 FETCH_INST() 13266 cmp r0, #0 13267 movne r2,#kJitTSelectRequestHot @ ask for trace selection 13268 bne common_selectTrace 13269 GET_INST_OPCODE(ip) 13270 GOTO_OPCODE(ip) 13271 13272/* 13273 * Return from the translation cache to the interpreter. 13274 * The return was done with a BLX from thumb mode, and 13275 * the following 32-bit word contains the target rPC value. 13276 * Note that lr (r14) will have its low-order bit set to denote 13277 * its thumb-mode origin. 13278 * 13279 * We'll need to stash our lr origin away, recover the new 13280 * target and then check to see if there is a translation available 13281 * for our new target. If so, we do a translation chain and 13282 * go back to native execution. Otherwise, it's back to the 13283 * interpreter (after treating this entry as a potential 13284 * trace start). 13285 */ 13286 .global dvmJitToInterpNormal 13287dvmJitToInterpNormal: 13288 ldr rPC,[lr, #-1] @ get our target PC 13289 add rINST,lr,#-5 @ save start of chain branch 13290 add rINST,#-4 @ .. which is 9 bytes back 13291#if defined(WITH_JIT_TUNING) 13292 bl dvmBumpNormal 13293#endif 13294 mov r0,rPC 13295 bl dvmJitGetTraceAddr @ Is there a translation? 13296 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13297 cmp r0,#0 13298 beq toInterpreter @ go if not, otherwise do chain 13299 mov r1,rINST 13300 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 13301 mov r1, rPC @ arg1 of translation may need this 13302 mov lr, #0 @ in case target is HANDLER_INTERPRET 13303 cmp r0,#0 @ successful chain? 13304 bxne r0 @ continue native execution 13305 b toInterpreter @ didn't chain - resume with interpreter 13306 13307/* 13308 * Return from the translation cache to the interpreter to do method invocation. 13309 * Check if translation exists for the callee, but don't chain to it. 13310 */ 13311 .global dvmJitToInterpNoChainNoProfile 13312dvmJitToInterpNoChainNoProfile: 13313#if defined(WITH_JIT_TUNING) 13314 bl dvmBumpNoChain 13315#endif 13316 mov r0,rPC 13317 bl dvmJitGetTraceAddr @ Is there a translation? 13318 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13319 mov r1, rPC @ arg1 of translation may need this 13320 mov lr, #0 @ in case target is HANDLER_INTERPRET 13321 cmp r0,#0 13322 bxne r0 @ continue native execution if so 13323 EXPORT_PC() 13324 adrl rIBASE, dvmAsmInstructionStart 13325 FETCH_INST() 13326 GET_INST_OPCODE(ip) @ extract opcode from rINST 13327 GOTO_OPCODE(ip) @ jump to next instruction 13328 13329/* 13330 * Return from the translation cache to the interpreter to do method invocation. 13331 * Check if translation exists for the callee, but don't chain to it. 13332 */ 13333 .global dvmJitToInterpNoChain 13334dvmJitToInterpNoChain: 13335#if defined(WITH_JIT_TUNING) 13336 bl dvmBumpNoChain 13337#endif 13338 mov r0,rPC 13339 bl dvmJitGetTraceAddr @ Is there a translation? 13340 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13341 mov r1, rPC @ arg1 of translation may need this 13342 mov lr, #0 @ in case target is HANDLER_INTERPRET 13343 cmp r0,#0 13344 bxne r0 @ continue native execution if so 13345#endif 13346 13347/* 13348 * No translation, restore interpreter regs and start interpreting. 13349 * rSELF & rFP were preserved in the translated code, and rPC has 13350 * already been restored by the time we get here. We'll need to set 13351 * up rIBASE & rINST, and load the address of the JitTable into r0. 13352 */ 13353toInterpreter: 13354 EXPORT_PC() 13355 adrl rIBASE, dvmAsmInstructionStart 13356 FETCH_INST() 13357 GET_JIT_PROF_TABLE(r0) 13358 @ NOTE: intended fallthrough 13359 13360/* 13361 * Common code to update potential trace start counter, and initiate 13362 * a trace-build if appropriate. On entry, rPC should point to the 13363 * next instruction to execute, and rINST should be already loaded with 13364 * the next opcode word, and r0 holds a pointer to the jit profile 13365 * table (pJitProfTable). 13366 */ 13367common_testUpdateProfile: 13368 cmp r0,#0 13369 GET_INST_OPCODE(ip) 13370 GOTO_OPCODE_IFEQ(ip) @ if not profiling, fallthrough otherwise */ 13371 13372common_updateProfile: 13373 eor r3,rPC,rPC,lsr #12 @ cheap, but fast hash function 13374 lsl r3,r3,#(32 - JIT_PROF_SIZE_LOG_2) @ shift out excess bits 13375 ldrb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter 13376 GET_INST_OPCODE(ip) 13377 subs r1,r1,#1 @ decrement counter 13378 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it 13379 GOTO_OPCODE_IFNE(ip) @ if not threshold, fallthrough otherwise */ 13380 13381/* 13382 * Here, we switch to the debug interpreter to request 13383 * trace selection. First, though, check to see if there 13384 * is already a native translation in place (and, if so, 13385 * jump to it now). 13386 */ 13387 13388 GET_JIT_THRESHOLD(r1) 13389 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter 13390 EXPORT_PC() 13391 mov r0,rPC 13392 bl dvmJitGetTraceAddr @ r0<- dvmJitGetTraceAddr(rPC) 13393 str r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13394 mov r1, rPC @ arg1 of translation may need this 13395 mov lr, #0 @ in case target is HANDLER_INTERPRET 13396 cmp r0,#0 13397#if !defined(WITH_SELF_VERIFICATION) 13398 bxne r0 @ jump to the translation 13399 mov r2,#kJitTSelectRequest @ ask for trace selection 13400 @ fall-through to common_selectTrace 13401#else 13402 moveq r2,#kJitTSelectRequest @ ask for trace selection 13403 beq common_selectTrace 13404 /* 13405 * At this point, we have a target translation. However, if 13406 * that translation is actually the interpret-only pseudo-translation 13407 * we want to treat it the same as no translation. 13408 */ 13409 mov r10, r0 @ save target 13410 bl dvmCompilerGetInterpretTemplate 13411 cmp r0, r10 @ special case? 13412 bne jitSVShadowRunStart @ set up self verification shadow space 13413 @ Need to clear the inJitCodeCache flag 13414 mov r3, #0 @ 0 means not in the JIT code cache 13415 str r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land 13416 GET_INST_OPCODE(ip) 13417 GOTO_OPCODE(ip) 13418 /* no return */ 13419#endif 13420 13421/* 13422 * On entry: 13423 * r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot 13424 */ 13425common_selectTrace: 13426 13427 str r2,[rSELF,#offThread_jitState] 13428 mov r2,#kInterpEntryInstr @ normal entry reason 13429 str r2,[rSELF,#offThread_entryPoint] 13430 mov r1,#1 @ set changeInterp 13431 b common_gotoBail 13432 13433#if defined(WITH_SELF_VERIFICATION) 13434/* 13435 * Save PC and registers to shadow memory for self verification mode 13436 * before jumping to native translation. 13437 * On entry: 13438 * rPC, rFP, rSELF: the values that they should contain 13439 * r10: the address of the target translation. 13440 */ 13441jitSVShadowRunStart: 13442 mov r0,rPC @ r0<- program counter 13443 mov r1,rFP @ r1<- frame pointer 13444 mov r2,rSELF @ r2<- self (Thread) pointer 13445 mov r3,r10 @ r3<- target translation 13446 bl dvmSelfVerificationSaveState @ save registers to shadow space 13447 ldr rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space 13448 bx r10 @ jump to the translation 13449 13450/* 13451 * Restore PC, registers, and interpreter state to original values 13452 * before jumping back to the interpreter. 13453 */ 13454jitSVShadowRunEnd: 13455 mov r1,rFP @ pass ending fp 13456 mov r3,rSELF @ pass self ptr for convenience 13457 bl dvmSelfVerificationRestoreState @ restore pc and fp values 13458 ldr rPC,[rSELF,#offThread_pc] @ restore PC 13459 ldr rFP,[rSELF,#offThread_fp] @ restore FP 13460 ldr r1,[r0,#offShadowSpace_svState] @ get self verification state 13461 cmp r1,#0 @ check for punt condition 13462 beq 1f 13463 mov r2,#kJitSelfVerification @ ask for self verification 13464 str r2,[rSELF,#offThread_jitState] 13465 mov r2,#kInterpEntryInstr @ normal entry reason 13466 str r2,[rSELF,#offThread_entryPoint] 13467 mov r1,#1 @ set changeInterp 13468 b common_gotoBail 13469 134701: @ exit to interpreter without check 13471 EXPORT_PC() 13472 adrl rIBASE, dvmAsmInstructionStart 13473 FETCH_INST() 13474 GET_INST_OPCODE(ip) 13475 GOTO_OPCODE(ip) 13476#endif 13477 13478#endif 13479 13480/* 13481 * Common code when a backward branch is taken. 13482 * 13483 * TODO: we could avoid a branch by just setting r0 and falling through 13484 * into the common_periodicChecks code, and having a test on r0 at the 13485 * end determine if we should return to the caller or update & branch to 13486 * the next instr. 13487 * 13488 * On entry: 13489 * r9 is PC adjustment *in bytes* 13490 */ 13491common_backwardBranch: 13492 mov r0, #kInterpEntryInstr 13493 bl common_periodicChecks 13494#if defined(WITH_JIT) 13495 GET_JIT_PROF_TABLE(r0) 13496 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 13497 cmp r0,#0 13498 bne common_updateProfile 13499 GET_INST_OPCODE(ip) 13500 GOTO_OPCODE(ip) 13501#else 13502 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 13503 GET_INST_OPCODE(ip) @ extract opcode from rINST 13504 GOTO_OPCODE(ip) @ jump to next instruction 13505#endif 13506 13507 13508/* 13509 * Need to see if the thread needs to be suspended or debugger/profiler 13510 * activity has begun. If so, we suspend the thread or side-exit to 13511 * the debug interpreter as appropriate. 13512 * 13513 * The common case is no activity on any of these, so we want to figure 13514 * that out quickly. If something is up, we can then sort out what. 13515 * 13516 * We want to be fast if the VM was built without debugger or profiler 13517 * support, but we also need to recognize that the system is usually 13518 * shipped with both of these enabled. 13519 * 13520 * TODO: reduce this so we're just checking a single location. 13521 * 13522 * On entry: 13523 * r0 is reentry type, e.g. kInterpEntryInstr (for debugger/profiling) 13524 * r9 is trampoline PC adjustment *in bytes* 13525 */ 13526common_periodicChecks: 13527/* TUNING - make this a direct load when interpBreak moved to Thread */ 13528 ldr r1, [rSELF, #offThread_pInterpBreak] @ r3<- &interpBreak 13529 /* speculatively thread-specific suspend count */ 13530 ldr ip, [rSELF, #offThread_suspendCount] 13531 ldr r1, [r1] @ r1<- interpBreak 13532 cmp r1, #0 @ anything unusual? 13533 bxeq lr @ return if not 13534 /* 13535 * One or more interesting events have happened. Figure out what. 13536 * 13537 * r0 still holds the reentry type. 13538 */ 13539 cmp ip, #0 @ want suspend? 13540 beq 3f @ no, must be something else 13541 13542 stmfd sp!, {r0, lr} @ preserve r0 and lr 13543#if defined(WITH_JIT) 13544 /* 13545 * Refresh the Jit's cached copy of profile table pointer. This pointer 13546 * doubles as the Jit's on/off switch. 13547 */ 13548 ldr r3, [rSELF, #offThread_ppJitProfTable] @ r3<-&gDvmJit.pJitProfTable 13549 mov r0, rSELF @ r0<- self 13550 ldr r3, [r3] @ r3 <- pJitProfTable 13551 EXPORT_PC() @ need for precise GC 13552 str r3, [rSELF, #offThread_pJitProfTable] @ refresh Jit's on/off switch 13553#else 13554 mov r0, rSELF @ r0<- self 13555 EXPORT_PC() @ need for precise GC 13556#endif 13557 bl dvmCheckSuspendPending @ do full check, suspend if necessary 13558 ldmfd sp!, {r0, lr} @ restore r0 and lr 13559 13560 /* 13561 * Reload the interpBreak flags - they may have changed while we 13562 * were suspended. 13563 */ 13564/* TUNING - direct load when InterpBreak moved to Thread */ 13565 ldr r1, [rSELF, #offThread_pInterpBreak] @ r1<- &interpBreak 13566 ldr r1, [r1] @ r1<- interpBreak 135673: 13568 /* 13569 * TODO: this code is too fragile. Need a general mechanism 13570 * to identify what actions to take by submode. Some profiling modes 13571 * (instruction count) need to single-step, while method tracing 13572 * may not. Debugging with breakpoints can run unfettered, but 13573 * source-level single-stepping requires Dalvik singlestepping. 13574 * GC may require a one-shot action and then full-speed resumption. 13575 */ 13576 ands r1, #(kSubModeDebuggerActive | kSubModeEmulatorTrace | kSubModeInstCounting) 13577 bxeq lr @ nothing to do, return 13578 13579 @ debugger/profiler enabled, bail out; self->entryPoint was set above 13580 str r0, [rSELF, #offThread_entryPoint] @ store r0, need for debug/prof 13581 add rPC, rPC, r9 @ update rPC 13582 mov r1, #1 @ "want switch" = true 13583 b common_gotoBail @ side exit 13584 13585 13586/* 13587 * The equivalent of "goto bail", this calls through the "bail handler". 13588 * 13589 * State registers will be saved to the "thread" area before bailing. 13590 * 13591 * On entry: 13592 * r1 is "bool changeInterp", indicating if we want to switch to the 13593 * other interpreter or just bail all the way out 13594 */ 13595common_gotoBail: 13596 SAVE_PC_FP_TO_SELF() @ export state to "thread" 13597 mov r0, rSELF @ r0<- self ptr 13598 b dvmMterpStdBail @ call(self, changeInterp) 13599 13600 @add r1, r1, #1 @ using (boolean+1) 13601 @add r0, rSELF, #offThread_jmpBuf @ r0<- &self->jmpBuf 13602 @bl _longjmp @ does not return 13603 @bl common_abort 13604 13605 13606/* 13607 * Common code for jumbo method invocation. 13608 * NOTE: this adjusts rPC to account for the difference in instruction width. 13609 * As a result, the savedPc in the stack frame will not be wholly accurate. So 13610 * long as that is only used for source file line number calculations, we're 13611 * okay. 13612 * 13613 * On entry: 13614 * r0 is "Method* methodToCall", the method we're trying to call 13615 */ 13616common_invokeMethodJumbo: 13617.LinvokeNewJumbo: 13618 @ prepare to copy args to "outs" area of current frame 13619 add rPC, rPC, #4 @ adjust pc to make return consistent 13620 FETCH(r2, 1) @ r2<- BBBB (arg count) 13621 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 13622 cmp r2, #0 @ no args? 13623 beq .LinvokeArgsDone @ if no args, skip the rest 13624 FETCH(r1, 2) @ r1<- CCCC 13625 b .LinvokeRangeArgs @ handle args like invoke range 13626 13627/* 13628 * Common code for method invocation with range. 13629 * 13630 * On entry: 13631 * r0 is "Method* methodToCall", the method we're trying to call 13632 */ 13633common_invokeMethodRange: 13634.LinvokeNewRange: 13635 @ prepare to copy args to "outs" area of current frame 13636 movs r2, rINST, lsr #8 @ r2<- AA (arg count) -- test for zero 13637 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 13638 beq .LinvokeArgsDone @ if no args, skip the rest 13639 FETCH(r1, 2) @ r1<- CCCC 13640 13641.LinvokeRangeArgs: 13642 @ r0=methodToCall, r1=CCCC, r2=count, r10=outs 13643 @ (very few methods have > 10 args; could unroll for common cases) 13644 add r3, rFP, r1, lsl #2 @ r3<- &fp[CCCC] 13645 sub r10, r10, r2, lsl #2 @ r10<- "outs" area, for call args 136461: ldr r1, [r3], #4 @ val = *fp++ 13647 subs r2, r2, #1 @ count-- 13648 str r1, [r10], #4 @ *outs++ = val 13649 bne 1b @ ...while count != 0 13650 b .LinvokeArgsDone 13651 13652/* 13653 * Common code for method invocation without range. 13654 * 13655 * On entry: 13656 * r0 is "Method* methodToCall", the method we're trying to call 13657 */ 13658common_invokeMethodNoRange: 13659.LinvokeNewNoRange: 13660 @ prepare to copy args to "outs" area of current frame 13661 movs r2, rINST, lsr #12 @ r2<- B (arg count) -- test for zero 13662 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 13663 FETCH(r1, 2) @ r1<- GFED (load here to hide latency) 13664 beq .LinvokeArgsDone 13665 13666 @ r0=methodToCall, r1=GFED, r2=count, r10=outs 13667.LinvokeNonRange: 13668 rsb r2, r2, #5 @ r2<- 5-r2 13669 add pc, pc, r2, lsl #4 @ computed goto, 4 instrs each 13670 bl common_abort @ (skipped due to ARM prefetch) 136715: and ip, rINST, #0x0f00 @ isolate A 13672 ldr r2, [rFP, ip, lsr #6] @ r2<- vA (shift right 8, left 2) 13673 mov r0, r0 @ nop 13674 str r2, [r10, #-4]! @ *--outs = vA 136754: and ip, r1, #0xf000 @ isolate G 13676 ldr r2, [rFP, ip, lsr #10] @ r2<- vG (shift right 12, left 2) 13677 mov r0, r0 @ nop 13678 str r2, [r10, #-4]! @ *--outs = vG 136793: and ip, r1, #0x0f00 @ isolate F 13680 ldr r2, [rFP, ip, lsr #6] @ r2<- vF 13681 mov r0, r0 @ nop 13682 str r2, [r10, #-4]! @ *--outs = vF 136832: and ip, r1, #0x00f0 @ isolate E 13684 ldr r2, [rFP, ip, lsr #2] @ r2<- vE 13685 mov r0, r0 @ nop 13686 str r2, [r10, #-4]! @ *--outs = vE 136871: and ip, r1, #0x000f @ isolate D 13688 ldr r2, [rFP, ip, lsl #2] @ r2<- vD 13689 mov r0, r0 @ nop 13690 str r2, [r10, #-4]! @ *--outs = vD 136910: @ fall through to .LinvokeArgsDone 13692 13693.LinvokeArgsDone: @ r0=methodToCall 13694 ldrh r9, [r0, #offMethod_registersSize] @ r9<- methodToCall->regsSize 13695 ldrh r3, [r0, #offMethod_outsSize] @ r3<- methodToCall->outsSize 13696 ldr r2, [r0, #offMethod_insns] @ r2<- method->insns 13697 ldr rINST, [r0, #offMethod_clazz] @ rINST<- method->clazz 13698 @ find space for the new stack frame, check for overflow 13699 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area 13700 sub r1, r1, r9, lsl #2 @ r1<- newFp (old savearea - regsSize) 13701 SAVEAREA_FROM_FP(r10, r1) @ r10<- newSaveArea 13702@ bl common_dumpRegs 13703 ldr r9, [rSELF, #offThread_interpStackEnd] @ r9<- interpStackEnd 13704 sub r3, r10, r3, lsl #2 @ r3<- bottom (newsave - outsSize) 13705 cmp r3, r9 @ bottom < interpStackEnd? 13706 ldr lr, [rSELF, #offThread_pInterpBreak] 13707 ldr r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags 13708 blo .LstackOverflow @ yes, this frame will overflow stack 13709 13710 @ set up newSaveArea 13711 ldr lr, [lr] @ lr<- active submodes 13712#ifdef EASY_GDB 13713 SAVEAREA_FROM_FP(ip, rFP) @ ip<- stack save area 13714 str ip, [r10, #offStackSaveArea_prevSave] 13715#endif 13716 str rFP, [r10, #offStackSaveArea_prevFrame] 13717 str rPC, [r10, #offStackSaveArea_savedPc] 13718#if defined(WITH_JIT) 13719 mov r9, #0 13720 str r9, [r10, #offStackSaveArea_returnAddr] 13721#endif 13722 ands lr, #kSubModeMethodTrace @ method tracing? 13723 beq 1f @ skip if not 13724 stmfd sp!, {r0-r3} @ preserve r0-r3 13725 mov r1, r6 13726 @ r0=methodToCall, r1=rSELF 13727 bl dvmFastMethodTraceEnter 13728 ldmfd sp!, {r0-r3} @ restore r0-r3 137291: 13730 str r0, [r10, #offStackSaveArea_method] 13731 tst r3, #ACC_NATIVE 13732 bne .LinvokeNative 13733 13734 /* 13735 stmfd sp!, {r0-r3} 13736 bl common_printNewline 13737 mov r0, rFP 13738 mov r1, #0 13739 bl dvmDumpFp 13740 ldmfd sp!, {r0-r3} 13741 stmfd sp!, {r0-r3} 13742 mov r0, r1 13743 mov r1, r10 13744 bl dvmDumpFp 13745 bl common_printNewline 13746 ldmfd sp!, {r0-r3} 13747 */ 13748 13749 ldrh r9, [r2] @ r9 <- load INST from new PC 13750 ldr r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex 13751 mov rPC, r2 @ publish new rPC 13752 13753 @ Update state values for the new method 13754 @ r0=methodToCall, r1=newFp, r3=newMethodClass, r9=newINST 13755 str r0, [rSELF, #offThread_method] @ self->method = methodToCall 13756 str r3, [rSELF, #offThread_methodClassDex] @ self->methodClassDex = ... 13757#if defined(WITH_JIT) 13758 GET_JIT_PROF_TABLE(r0) 13759 mov rFP, r1 @ fp = newFp 13760 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 13761 mov rINST, r9 @ publish new rINST 13762 str r1, [rSELF, #offThread_curFrame] @ self->curFrame = newFp 13763 cmp r0,#0 13764 bne common_updateProfile 13765 GOTO_OPCODE(ip) @ jump to next instruction 13766#else 13767 mov rFP, r1 @ fp = newFp 13768 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 13769 mov rINST, r9 @ publish new rINST 13770 str r1, [rSELF, #offThread_curFrame] @ self->curFrame = newFp 13771 GOTO_OPCODE(ip) @ jump to next instruction 13772#endif 13773 13774.LinvokeNative: 13775 @ Prep for the native call 13776 @ r0=methodToCall, r1=newFp, r10=newSaveArea 13777 ldr lr, [rSELF, #offThread_pInterpBreak] 13778 ldr r9, [rSELF, #offThread_jniLocal_topCookie]@r9<-thread->localRef->... 13779 str r1, [rSELF, #offThread_curFrame] @ self->curFrame = newFp 13780 str r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top 13781 ldr lr, [lr] @ lr<- active submodes 13782 13783 mov r2, r0 @ r2<- methodToCall 13784 mov r0, r1 @ r0<- newFp (points to args) 13785 add r1, rSELF, #offThread_retval @ r1<- &retval 13786 mov r3, rSELF @ arg3<- self 13787 13788#ifdef ASSIST_DEBUGGER 13789 /* insert fake function header to help gdb find the stack frame */ 13790 b .Lskip 13791 .type dalvik_mterp, %function 13792dalvik_mterp: 13793 .fnstart 13794 MTERP_ENTRY1 13795 MTERP_ENTRY2 13796.Lskip: 13797#endif 13798 13799 ands lr, #kSubModeMethodTrace @ method tracing? 13800 beq 110f @ hop if not 13801 @ r2=JNIMethod, r6=rSELF 13802 stmfd sp!, {r2,r6} 13803 13804 mov lr, pc @ set return addr 13805 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 13806 13807 @ r0=JNIMethod, r1=rSELF 13808 ldmfd sp!, {r0-r1} 13809 bl dvmFastNativeMethodTraceExit 13810 b 220f 13811110: 13812 mov lr, pc @ set return addr 13813 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 13814220: 13815#if defined(WITH_JIT) 13816 ldr r3, [rSELF, #offThread_ppJitProfTable] @ Refresh Jit's on/off status 13817#endif 13818 13819 @ native return; r10=newSaveArea 13820 @ equivalent to dvmPopJniLocals 13821 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top 13822 ldr r1, [rSELF, #offThread_exception] @ check for exception 13823#if defined(WITH_JIT) 13824 ldr r3, [r3] @ r3 <- gDvmJit.pProfTable 13825#endif 13826 str rFP, [rSELF, #offThread_curFrame] @ self->curFrame = fp 13827 cmp r1, #0 @ null? 13828 str r0, [rSELF, #offThread_jniLocal_topCookie] @ new top <- old top 13829#if defined(WITH_JIT) 13830 str r3, [rSELF, #offThread_pJitProfTable] @ refresh cached on/off switch 13831#endif 13832 bne common_exceptionThrown @ no, handle exception 13833 13834 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 13835 GET_INST_OPCODE(ip) @ extract opcode from rINST 13836 GOTO_OPCODE(ip) @ jump to next instruction 13837 13838.LstackOverflow: @ r0=methodToCall 13839 mov r1, r0 @ r1<- methodToCall 13840 mov r0, rSELF @ r0<- self 13841 bl dvmHandleStackOverflow 13842 b common_exceptionThrown 13843#ifdef ASSIST_DEBUGGER 13844 .fnend 13845 .size dalvik_mterp, .-dalvik_mterp 13846#endif 13847 13848 13849 /* 13850 * Common code for method invocation, calling through "glue code". 13851 * 13852 * TODO: now that we have range and non-range invoke handlers, this 13853 * needs to be split into two. Maybe just create entry points 13854 * that set r9 and jump here? 13855 * 13856 * On entry: 13857 * r0 is "Method* methodToCall", the method we're trying to call 13858 * r9 is "bool methodCallRange", indicating if this is a /range variant 13859 */ 13860 .if 0 13861.LinvokeOld: 13862 sub sp, sp, #8 @ space for args + pad 13863 FETCH(ip, 2) @ ip<- FEDC or CCCC 13864 mov r2, r0 @ A2<- methodToCall 13865 mov r0, rSELF @ A0<- self 13866 SAVE_PC_FP_TO_SELF() @ export state to "self" 13867 mov r1, r9 @ A1<- methodCallRange 13868 mov r3, rINST, lsr #8 @ A3<- AA 13869 str ip, [sp, #0] @ A4<- ip 13870 bl dvmMterp_invokeMethod @ call the C invokeMethod 13871 add sp, sp, #8 @ remove arg area 13872 b common_resumeAfterGlueCall @ continue to next instruction 13873 .endif 13874 13875 13876 13877/* 13878 * Common code for handling a return instruction. 13879 * 13880 * This does not return. 13881 */ 13882common_returnFromMethod: 13883.LreturnNew: 13884 mov r0, #kInterpEntryReturn 13885 mov r9, #0 13886 bl common_periodicChecks 13887 13888 ldr lr, [rSELF, #offThread_pInterpBreak] 13889 SAVEAREA_FROM_FP(r0, rFP) 13890 ldr lr, [lr] @ lr<- active submodes 13891 ldr r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc 13892 ands lr, #kSubModeMethodTrace @ method tracing? 13893 beq 333f 13894 stmfd sp!, {r0-r3} @ preserve r0-r3 13895 mov r0, r6 13896 @ r0=rSELF 13897 bl dvmFastJavaMethodTraceExit 13898 ldmfd sp!, {r0-r3} @ restore r0-r3 13899333: 13900 ldr rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame 13901 ldr r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)] 13902 @ r2<- method we're returning to 13903 cmp r2, #0 @ is this a break frame? 13904#if defined(WORKAROUND_CORTEX_A9_745320) 13905 /* Don't use conditional loads if the HW defect exists */ 13906 beq 101f 13907 ldr r10, [r2, #offMethod_clazz] @ r10<- method->clazz 13908101: 13909#else 13910 ldrne r10, [r2, #offMethod_clazz] @ r10<- method->clazz 13911#endif 13912 mov r1, #0 @ "want switch" = false 13913 beq common_gotoBail @ break frame, bail out completely 13914 13915 PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST 13916 str r2, [rSELF, #offThread_method]@ self->method = newSave->method 13917 ldr r1, [r10, #offClassObject_pDvmDex] @ r1<- method->clazz->pDvmDex 13918 str rFP, [rSELF, #offThread_curFrame] @ self->curFrame = fp 13919#if defined(WITH_JIT) 13920 ldr r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr 13921 mov rPC, r9 @ publish new rPC 13922 str r1, [rSELF, #offThread_methodClassDex] 13923 str r10, [rSELF, #offThread_inJitCodeCache] @ may return to JIT'ed land 13924 cmp r10, #0 @ caller is compiled code 13925 blxne r10 13926 GET_INST_OPCODE(ip) @ extract opcode from rINST 13927 GOTO_OPCODE(ip) @ jump to next instruction 13928#else 13929 GET_INST_OPCODE(ip) @ extract opcode from rINST 13930 mov rPC, r9 @ publish new rPC 13931 str r1, [rSELF, #offThread_methodClassDex] 13932 GOTO_OPCODE(ip) @ jump to next instruction 13933#endif 13934 13935 /* 13936 * Return handling, calls through "glue code". 13937 */ 13938 .if 0 13939.LreturnOld: 13940 SAVE_PC_FP_TO_SELF() @ export state 13941 mov r0, rSELF @ arg to function 13942 bl dvmMterp_returnFromMethod 13943 b common_resumeAfterGlueCall 13944 .endif 13945 13946 13947/* 13948 * Somebody has thrown an exception. Handle it. 13949 * 13950 * If the exception processing code returns to us (instead of falling 13951 * out of the interpreter), continue with whatever the next instruction 13952 * now happens to be. 13953 * 13954 * This does not return. 13955 */ 13956 .global dvmMterpCommonExceptionThrown 13957dvmMterpCommonExceptionThrown: 13958common_exceptionThrown: 13959.LexceptionNew: 13960 mov r0, #kInterpEntryThrow 13961 mov r9, #0 13962 bl common_periodicChecks 13963 13964 ldr r9, [rSELF, #offThread_exception] @ r9<- self->exception 13965 mov r1, rSELF @ r1<- self 13966 mov r0, r9 @ r0<- exception 13967 bl dvmAddTrackedAlloc @ don't let the exception be GCed 13968 mov r3, #0 @ r3<- NULL 13969 str r3, [rSELF, #offThread_exception] @ self->exception = NULL 13970 13971 /* set up args and a local for "&fp" */ 13972 /* (str sp, [sp, #-4]! would be perfect here, but is discouraged) */ 13973 str rFP, [sp, #-4]! @ *--sp = fp 13974 mov ip, sp @ ip<- &fp 13975 mov r3, #0 @ r3<- false 13976 str ip, [sp, #-4]! @ *--sp = &fp 13977 ldr r1, [rSELF, #offThread_method] @ r1<- self->method 13978 mov r0, rSELF @ r0<- self 13979 ldr r1, [r1, #offMethod_insns] @ r1<- method->insns 13980 mov r2, r9 @ r2<- exception 13981 sub r1, rPC, r1 @ r1<- pc - method->insns 13982 mov r1, r1, asr #1 @ r1<- offset in code units 13983 13984 /* call, r0 gets catchRelPc (a code-unit offset) */ 13985 bl dvmFindCatchBlock @ call(self, relPc, exc, scan?, &fp) 13986 13987 /* fix earlier stack overflow if necessary; may trash rFP */ 13988 ldrb r1, [rSELF, #offThread_stackOverflowed] 13989 cmp r1, #0 @ did we overflow earlier? 13990 beq 1f @ no, skip ahead 13991 mov rFP, r0 @ save relPc result in rFP 13992 mov r0, rSELF @ r0<- self 13993 mov r1, r9 @ r1<- exception 13994 bl dvmCleanupStackOverflow @ call(self) 13995 mov r0, rFP @ restore result 139961: 13997 13998 /* update frame pointer and check result from dvmFindCatchBlock */ 13999 ldr rFP, [sp, #4] @ retrieve the updated rFP 14000 cmp r0, #0 @ is catchRelPc < 0? 14001 add sp, sp, #8 @ restore stack 14002 bmi .LnotCaughtLocally 14003 14004 /* adjust locals to match self->curFrame and updated PC */ 14005 SAVEAREA_FROM_FP(r1, rFP) @ r1<- new save area 14006 ldr r1, [r1, #offStackSaveArea_method] @ r1<- new method 14007 str r1, [rSELF, #offThread_method] @ self->method = new method 14008 ldr r2, [r1, #offMethod_clazz] @ r2<- method->clazz 14009 ldr r3, [r1, #offMethod_insns] @ r3<- method->insns 14010 ldr r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex 14011 add rPC, r3, r0, asl #1 @ rPC<- method->insns + catchRelPc 14012 str r2, [rSELF, #offThread_methodClassDex] @ self->pDvmDex = meth... 14013 14014 /* release the tracked alloc on the exception */ 14015 mov r0, r9 @ r0<- exception 14016 mov r1, rSELF @ r1<- self 14017 bl dvmReleaseTrackedAlloc @ release the exception 14018 14019 /* restore the exception if the handler wants it */ 14020 FETCH_INST() @ load rINST from rPC 14021 GET_INST_OPCODE(ip) @ extract opcode from rINST 14022 cmp ip, #OP_MOVE_EXCEPTION @ is it "move-exception"? 14023 streq r9, [rSELF, #offThread_exception] @ yes, restore the exception 14024 GOTO_OPCODE(ip) @ jump to next instruction 14025 14026.LnotCaughtLocally: @ r9=exception 14027 /* fix stack overflow if necessary */ 14028 ldrb r1, [rSELF, #offThread_stackOverflowed] 14029 cmp r1, #0 @ did we overflow earlier? 14030 movne r0, rSELF @ if yes: r0<- self 14031 movne r1, r9 @ if yes: r1<- exception 14032 blne dvmCleanupStackOverflow @ if yes: call(self) 14033 14034 @ may want to show "not caught locally" debug messages here 14035#if DVM_SHOW_EXCEPTION >= 2 14036 /* call __android_log_print(prio, tag, format, ...) */ 14037 /* "Exception %s from %s:%d not caught locally" */ 14038 @ dvmLineNumFromPC(method, pc - method->insns) 14039 ldr r0, [rSELF, #offThread_method] 14040 ldr r1, [r0, #offMethod_insns] 14041 sub r1, rPC, r1 14042 asr r1, r1, #1 14043 bl dvmLineNumFromPC 14044 str r0, [sp, #-4]! 14045 @ dvmGetMethodSourceFile(method) 14046 ldr r0, [rSELF, #offThread_method] 14047 bl dvmGetMethodSourceFile 14048 str r0, [sp, #-4]! 14049 @ exception->clazz->descriptor 14050 ldr r3, [r9, #offObject_clazz] 14051 ldr r3, [r3, #offClassObject_descriptor] 14052 @ 14053 ldr r2, strExceptionNotCaughtLocally 14054 ldr r1, strLogTag 14055 mov r0, #3 @ LOG_DEBUG 14056 bl __android_log_print 14057#endif 14058 str r9, [rSELF, #offThread_exception] @ restore exception 14059 mov r0, r9 @ r0<- exception 14060 mov r1, rSELF @ r1<- self 14061 bl dvmReleaseTrackedAlloc @ release the exception 14062 mov r1, #0 @ "want switch" = false 14063 b common_gotoBail @ bail out 14064 14065 14066 /* 14067 * Exception handling, calls through "glue code". 14068 */ 14069 .if 0 14070.LexceptionOld: 14071 SAVE_PC_FP_TO_SELF() @ export state 14072 mov r0, rSELF @ arg to function 14073 bl dvmMterp_exceptionThrown 14074 b common_resumeAfterGlueCall 14075 .endif 14076 14077 14078/* 14079 * After returning from a "glued" function, pull out the updated 14080 * values and start executing at the next instruction. 14081 */ 14082common_resumeAfterGlueCall: 14083 LOAD_PC_FP_FROM_SELF() @ pull rPC and rFP out of thread 14084 FETCH_INST() @ load rINST from rPC 14085 GET_INST_OPCODE(ip) @ extract opcode from rINST 14086 GOTO_OPCODE(ip) @ jump to next instruction 14087 14088/* 14089 * Invalid array index. Note that our calling convention is strange; we use r1 14090 * and r3 because those just happen to be the registers all our callers are 14091 * using. We shuffle them here before calling the C function. 14092 * r1: index 14093 * r3: size 14094 */ 14095common_errArrayIndex: 14096 EXPORT_PC() 14097 mov r0, r1 14098 mov r1, r3 14099 bl dvmThrowArrayIndexOutOfBoundsException 14100 b common_exceptionThrown 14101 14102/* 14103 * Integer divide or mod by zero. 14104 */ 14105common_errDivideByZero: 14106 EXPORT_PC() 14107 ldr r0, strArithmeticException 14108 ldr r1, strDivideByZero 14109 bl dvmThrowException 14110 b common_exceptionThrown 14111 14112/* 14113 * Attempt to allocate an array with a negative size. 14114 * On entry: length in r1 14115 */ 14116common_errNegativeArraySize: 14117 EXPORT_PC() 14118 mov r0, r1 @ arg0 <- len 14119 bl dvmThrowNegativeArraySizeException @ (len) 14120 b common_exceptionThrown 14121 14122/* 14123 * Invocation of a non-existent method. 14124 */ 14125common_errNoSuchMethod: 14126 EXPORT_PC() 14127 ldr r0, strNoSuchMethodError 14128 mov r1, #0 14129 bl dvmThrowException 14130 b common_exceptionThrown 14131 14132/* 14133 * We encountered a null object when we weren't expecting one. We 14134 * export the PC, throw a NullPointerException, and goto the exception 14135 * processing code. 14136 */ 14137common_errNullObject: 14138 EXPORT_PC() 14139 ldr r0, strNullPointerException 14140 mov r1, #0 14141 bl dvmThrowException 14142 b common_exceptionThrown 14143 14144/* 14145 * For debugging, cause an immediate fault. The source address will 14146 * be in lr (use a bl instruction to jump here). 14147 */ 14148common_abort: 14149 ldr pc, .LdeadFood 14150.LdeadFood: 14151 .word 0xdeadf00d 14152 14153/* 14154 * Spit out a "we were here", preserving all registers. (The attempt 14155 * to save ip won't work, but we need to save an even number of 14156 * registers for EABI 64-bit stack alignment.) 14157 */ 14158 .macro SQUEAK num 14159common_squeak\num: 14160 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14161 ldr r0, strSqueak 14162 mov r1, #\num 14163 bl printf 14164 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14165 bx lr 14166 .endm 14167 14168 SQUEAK 0 14169 SQUEAK 1 14170 SQUEAK 2 14171 SQUEAK 3 14172 SQUEAK 4 14173 SQUEAK 5 14174 14175/* 14176 * Spit out the number in r0, preserving registers. 14177 */ 14178common_printNum: 14179 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14180 mov r1, r0 14181 ldr r0, strSqueak 14182 bl printf 14183 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14184 bx lr 14185 14186/* 14187 * Print a newline, preserving registers. 14188 */ 14189common_printNewline: 14190 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14191 ldr r0, strNewline 14192 bl printf 14193 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14194 bx lr 14195 14196 /* 14197 * Print the 32-bit quantity in r0 as a hex value, preserving registers. 14198 */ 14199common_printHex: 14200 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14201 mov r1, r0 14202 ldr r0, strPrintHex 14203 bl printf 14204 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14205 bx lr 14206 14207/* 14208 * Print the 64-bit quantity in r0-r1, preserving registers. 14209 */ 14210common_printLong: 14211 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14212 mov r3, r1 14213 mov r2, r0 14214 ldr r0, strPrintLong 14215 bl printf 14216 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14217 bx lr 14218 14219/* 14220 * Print full method info. Pass the Method* in r0. Preserves regs. 14221 */ 14222common_printMethod: 14223 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14224 bl dvmMterpPrintMethod 14225 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14226 bx lr 14227 14228/* 14229 * Call a C helper function that dumps regs and possibly some 14230 * additional info. Requires the C function to be compiled in. 14231 */ 14232 .if 0 14233common_dumpRegs: 14234 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14235 bl dvmMterpDumpArmRegs 14236 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14237 bx lr 14238 .endif 14239 14240#if 0 14241/* 14242 * Experiment on VFP mode. 14243 * 14244 * uint32_t setFPSCR(uint32_t val, uint32_t mask) 14245 * 14246 * Updates the bits specified by "mask", setting them to the values in "val". 14247 */ 14248setFPSCR: 14249 and r0, r0, r1 @ make sure no stray bits are set 14250 fmrx r2, fpscr @ get VFP reg 14251 mvn r1, r1 @ bit-invert mask 14252 and r2, r2, r1 @ clear masked bits 14253 orr r2, r2, r0 @ set specified bits 14254 fmxr fpscr, r2 @ set VFP reg 14255 mov r0, r2 @ return new value 14256 bx lr 14257 14258 .align 2 14259 .global dvmConfigureFP 14260 .type dvmConfigureFP, %function 14261dvmConfigureFP: 14262 stmfd sp!, {ip, lr} 14263 /* 0x03000000 sets DN/FZ */ 14264 /* 0x00009f00 clears the six exception enable flags */ 14265 bl common_squeak0 14266 mov r0, #0x03000000 @ r0<- 0x03000000 14267 add r1, r0, #0x9f00 @ r1<- 0x03009f00 14268 bl setFPSCR 14269 ldmfd sp!, {ip, pc} 14270#endif 14271 14272 14273/* 14274 * String references, must be close to the code that uses them. 14275 */ 14276 .align 2 14277strArithmeticException: 14278 .word .LstrArithmeticException 14279strDivideByZero: 14280 .word .LstrDivideByZero 14281strNoSuchMethodError: 14282 .word .LstrNoSuchMethodError 14283strNullPointerException: 14284 .word .LstrNullPointerException 14285 14286strLogTag: 14287 .word .LstrLogTag 14288strExceptionNotCaughtLocally: 14289 .word .LstrExceptionNotCaughtLocally 14290 14291strNewline: 14292 .word .LstrNewline 14293strSqueak: 14294 .word .LstrSqueak 14295strPrintHex: 14296 .word .LstrPrintHex 14297strPrintLong: 14298 .word .LstrPrintLong 14299 14300/* 14301 * Zero-terminated ASCII string data. 14302 * 14303 * On ARM we have two choices: do like gcc does, and LDR from a .word 14304 * with the address, or use an ADR pseudo-op to get the address 14305 * directly. ADR saves 4 bytes and an indirection, but it's using a 14306 * PC-relative addressing mode and hence has a limited range, which 14307 * makes it not work well with mergeable string sections. 14308 */ 14309 .section .rodata.str1.4,"aMS",%progbits,1 14310 14311.LstrBadEntryPoint: 14312 .asciz "Bad entry point %d\n" 14313.LstrArithmeticException: 14314 .asciz "Ljava/lang/ArithmeticException;" 14315.LstrDivideByZero: 14316 .asciz "divide by zero" 14317.LstrFilledNewArrayNotImpl: 14318 .asciz "filled-new-array only implemented for objects and 'int'" 14319.LstrInternalError: 14320 .asciz "Ljava/lang/InternalError;" 14321.LstrInstantiationError: 14322 .asciz "Ljava/lang/InstantiationError;" 14323.LstrNoSuchMethodError: 14324 .asciz "Ljava/lang/NoSuchMethodError;" 14325.LstrNullPointerException: 14326 .asciz "Ljava/lang/NullPointerException;" 14327 14328.LstrLogTag: 14329 .asciz "mterp" 14330.LstrExceptionNotCaughtLocally: 14331 .asciz "Exception %s from %s:%d not caught locally\n" 14332 14333.LstrNewline: 14334 .asciz "\n" 14335.LstrSqueak: 14336 .asciz "<%d>" 14337.LstrPrintHex: 14338 .asciz "<0x%x>" 14339.LstrPrintLong: 14340 .asciz "<%lld>" 14341 14342