InterpAsm-armv7-a.S revision 18fba346582c08d81aa96d9508c0e935bad5f36f
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 rGLUE MterpGlue 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 rGLUE r6 79#define rINST r7 80#define rIBASE r8 81 82/* save/restore the PC and/or FP from the glue struct */ 83#define LOAD_PC_FROM_GLUE() ldr rPC, [rGLUE, #offGlue_pc] 84#define SAVE_PC_TO_GLUE() str rPC, [rGLUE, #offGlue_pc] 85#define LOAD_FP_FROM_GLUE() ldr rFP, [rGLUE, #offGlue_fp] 86#define SAVE_FP_TO_GLUE() str rFP, [rGLUE, #offGlue_fp] 87#define LOAD_PC_FP_FROM_GLUE() ldmia rGLUE, {rPC, rFP} 88#define SAVE_PC_FP_TO_GLUE() stmia rGLUE, {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,[rGLUE,#offGlue_pJitProfTable] 190#define GET_JIT_THRESHOLD(_reg) ldr _reg,[rGLUE,#offGlue_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 MterpGlue* glue 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, #offGlue_bailPtr] @ save SP for eventual return 302 303 /* set up "named" registers, figure out entry point */ 304 mov rGLUE, r0 @ set rGLUE 305 ldr r1, [r0, #offGlue_entryPoint] @ enum is 4 bytes in aapcs-EABI 306 LOAD_PC_FP_FROM_GLUE() @ load rPC and rFP from "glue" 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 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 314 /* Entry is always a possible trace start */ 315 GET_JIT_PROF_TABLE(r0) 316 FETCH_INST() 317 mov r1, #0 @ prepare the value for the new state 318 str r1, [r10, #offThread_inJitCodeCache] @ back to the interp land 319 cmp r0,#0 @ is profiling disabled? 320#if !defined(WITH_SELF_VERIFICATION) 321 bne common_updateProfile @ profiling is enabled 322#else 323 ldr r2, [r10, #offThread_shadowSpace] @ to find out the jit exit state 324 beq 1f @ profiling is disabled 325 ldr r3, [r2, #offShadowSpace_jitExitState] @ jit exit state 326 cmp r3, #kSVSTraceSelect @ hot trace following? 327 moveq r2,#kJitTSelectRequestHot @ ask for trace selection 328 beq common_selectTrace @ go build the trace 329 cmp r3, #kSVSNoProfile @ don't profile the next instruction? 330 beq 1f @ intrepret the next instruction 331 b common_updateProfile @ collect profiles 332#endif 3331: 334 GET_INST_OPCODE(ip) 335 GOTO_OPCODE(ip) 336#else 337 /* start executing the instruction at rPC */ 338 FETCH_INST() @ load rINST from rPC 339 GET_INST_OPCODE(ip) @ extract opcode from rINST 340 GOTO_OPCODE(ip) @ jump to next instruction 341#endif 342 343.Lnot_instr: 344 cmp r1, #kInterpEntryReturn @ were we returning from a method? 345 beq common_returnFromMethod 346 347.Lnot_return: 348 cmp r1, #kInterpEntryThrow @ were we throwing an exception? 349 beq common_exceptionThrown 350 351#if defined(WITH_JIT) 352.Lnot_throw: 353 ldr r10,[rGLUE, #offGlue_jitResumeNPC] 354 ldr r2,[rGLUE, #offGlue_jitResumeDPC] 355 cmp r1, #kInterpEntryResume @ resuming after Jit single-step? 356 bne .Lbad_arg 357 cmp rPC,r2 358 bne .LentryInstr @ must have branched, don't resume 359#if defined(WITH_SELF_VERIFICATION) 360 @ glue->entryPoint will be set in dvmSelfVerificationSaveState 361 b jitSVShadowRunStart @ re-enter the translation after the 362 @ single-stepped instruction 363 @noreturn 364#endif 365 mov r1, #kInterpEntryInstr 366 str r1, [rGLUE, #offGlue_entryPoint] 367 bx r10 @ re-enter the translation 368#endif 369 370.Lbad_arg: 371 ldr r0, strBadEntryPoint 372 @ r1 holds value of entryPoint 373 bl printf 374 bl dvmAbort 375 .fnend 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 MterpGlue* glue 392 * r1 bool changeInterp 393 */ 394dvmMterpStdBail: 395 ldr sp, [r0, #offGlue_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, [rGLUE, #offGlue_retval] @ r0<- glue->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, rGLUE, #offGlue_retval @ r3<- &glue->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, [rGLUE, #offGlue_retval] @ r0<- glue->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 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 618 mov r2, rINST, lsr #8 @ r2<- AA 619 ldr r3, [r0, #offThread_exception] @ r3<- dvmGetException bypass 620 mov r1, #0 @ r1<- 0 621 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 622 SET_VREG(r3, r2) @ fp[AA]<- exception obj 623 GET_INST_OPCODE(ip) @ extract opcode from rINST 624 str r1, [r0, #offThread_exception] @ dvmClearException bypass 625 GOTO_OPCODE(ip) @ jump to next instruction 626 627/* ------------------------------ */ 628 .balign 64 629.L_OP_RETURN_VOID: /* 0x0e */ 630/* File: armv5te/OP_RETURN_VOID.S */ 631 b common_returnFromMethod 632 633/* ------------------------------ */ 634 .balign 64 635.L_OP_RETURN: /* 0x0f */ 636/* File: armv5te/OP_RETURN.S */ 637 /* 638 * Return a 32-bit value. Copies the return value into the "glue" 639 * structure, then jumps to the return handler. 640 * 641 * for: return, return-object 642 */ 643 /* op vAA */ 644 mov r2, rINST, lsr #8 @ r2<- AA 645 GET_VREG(r0, r2) @ r0<- vAA 646 str r0, [rGLUE, #offGlue_retval] @ retval.i <- vAA 647 b common_returnFromMethod 648 649/* ------------------------------ */ 650 .balign 64 651.L_OP_RETURN_WIDE: /* 0x10 */ 652/* File: armv5te/OP_RETURN_WIDE.S */ 653 /* 654 * Return a 64-bit value. Copies the return value into the "glue" 655 * structure, then jumps to the return handler. 656 */ 657 /* return-wide vAA */ 658 mov r2, rINST, lsr #8 @ r2<- AA 659 add r2, rFP, r2, lsl #2 @ r2<- &fp[AA] 660 add r3, rGLUE, #offGlue_retval @ r3<- &glue->retval 661 ldmia r2, {r0-r1} @ r0/r1 <- vAA/vAA+1 662 stmia r3, {r0-r1} @ retval<- r0/r1 663 b common_returnFromMethod 664 665/* ------------------------------ */ 666 .balign 64 667.L_OP_RETURN_OBJECT: /* 0x11 */ 668/* File: armv5te/OP_RETURN_OBJECT.S */ 669/* File: armv5te/OP_RETURN.S */ 670 /* 671 * Return a 32-bit value. Copies the return value into the "glue" 672 * structure, then jumps to the return handler. 673 * 674 * for: return, return-object 675 */ 676 /* op vAA */ 677 mov r2, rINST, lsr #8 @ r2<- AA 678 GET_VREG(r0, r2) @ r0<- vAA 679 str r0, [rGLUE, #offGlue_retval] @ retval.i <- vAA 680 b common_returnFromMethod 681 682 683/* ------------------------------ */ 684 .balign 64 685.L_OP_CONST_4: /* 0x12 */ 686/* File: armv6t2/OP_CONST_4.S */ 687 /* const/4 vA, #+B */ 688 mov r1, rINST, lsl #16 @ r1<- Bxxx0000 689 ubfx r0, rINST, #8, #4 @ r0<- A 690 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 691 mov r1, r1, asr #28 @ r1<- sssssssB (sign-extended) 692 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 693 SET_VREG(r1, r0) @ fp[A]<- r1 694 GOTO_OPCODE(ip) @ execute next instruction 695 696/* ------------------------------ */ 697 .balign 64 698.L_OP_CONST_16: /* 0x13 */ 699/* File: armv5te/OP_CONST_16.S */ 700 /* const/16 vAA, #+BBBB */ 701 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 702 mov r3, rINST, lsr #8 @ r3<- AA 703 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 704 SET_VREG(r0, r3) @ vAA<- r0 705 GET_INST_OPCODE(ip) @ extract opcode from rINST 706 GOTO_OPCODE(ip) @ jump to next instruction 707 708/* ------------------------------ */ 709 .balign 64 710.L_OP_CONST: /* 0x14 */ 711/* File: armv5te/OP_CONST.S */ 712 /* const vAA, #+BBBBbbbb */ 713 mov r3, rINST, lsr #8 @ r3<- AA 714 FETCH(r0, 1) @ r0<- bbbb (low) 715 FETCH(r1, 2) @ r1<- BBBB (high) 716 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 717 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 718 GET_INST_OPCODE(ip) @ extract opcode from rINST 719 SET_VREG(r0, r3) @ vAA<- r0 720 GOTO_OPCODE(ip) @ jump to next instruction 721 722/* ------------------------------ */ 723 .balign 64 724.L_OP_CONST_HIGH16: /* 0x15 */ 725/* File: armv5te/OP_CONST_HIGH16.S */ 726 /* const/high16 vAA, #+BBBB0000 */ 727 FETCH(r0, 1) @ r0<- 0000BBBB (zero-extended) 728 mov r3, rINST, lsr #8 @ r3<- AA 729 mov r0, r0, lsl #16 @ r0<- BBBB0000 730 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 731 SET_VREG(r0, r3) @ vAA<- r0 732 GET_INST_OPCODE(ip) @ extract opcode from rINST 733 GOTO_OPCODE(ip) @ jump to next instruction 734 735/* ------------------------------ */ 736 .balign 64 737.L_OP_CONST_WIDE_16: /* 0x16 */ 738/* File: armv5te/OP_CONST_WIDE_16.S */ 739 /* const-wide/16 vAA, #+BBBB */ 740 FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) 741 mov r3, rINST, lsr #8 @ r3<- AA 742 mov r1, r0, asr #31 @ r1<- ssssssss 743 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 744 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 745 GET_INST_OPCODE(ip) @ extract opcode from rINST 746 stmia r3, {r0-r1} @ vAA<- r0/r1 747 GOTO_OPCODE(ip) @ jump to next instruction 748 749/* ------------------------------ */ 750 .balign 64 751.L_OP_CONST_WIDE_32: /* 0x17 */ 752/* File: armv5te/OP_CONST_WIDE_32.S */ 753 /* const-wide/32 vAA, #+BBBBbbbb */ 754 FETCH(r0, 1) @ r0<- 0000bbbb (low) 755 mov r3, rINST, lsr #8 @ r3<- AA 756 FETCH_S(r2, 2) @ r2<- ssssBBBB (high) 757 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 758 orr r0, r0, r2, lsl #16 @ r0<- BBBBbbbb 759 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 760 mov r1, r0, asr #31 @ r1<- ssssssss 761 GET_INST_OPCODE(ip) @ extract opcode from rINST 762 stmia r3, {r0-r1} @ vAA<- r0/r1 763 GOTO_OPCODE(ip) @ jump to next instruction 764 765/* ------------------------------ */ 766 .balign 64 767.L_OP_CONST_WIDE: /* 0x18 */ 768/* File: armv5te/OP_CONST_WIDE.S */ 769 /* const-wide vAA, #+HHHHhhhhBBBBbbbb */ 770 FETCH(r0, 1) @ r0<- bbbb (low) 771 FETCH(r1, 2) @ r1<- BBBB (low middle) 772 FETCH(r2, 3) @ r2<- hhhh (high middle) 773 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb (low word) 774 FETCH(r3, 4) @ r3<- HHHH (high) 775 mov r9, rINST, lsr #8 @ r9<- AA 776 orr r1, r2, r3, lsl #16 @ r1<- HHHHhhhh (high word) 777 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 778 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 779 GET_INST_OPCODE(ip) @ extract opcode from rINST 780 stmia r9, {r0-r1} @ vAA<- r0/r1 781 GOTO_OPCODE(ip) @ jump to next instruction 782 783/* ------------------------------ */ 784 .balign 64 785.L_OP_CONST_WIDE_HIGH16: /* 0x19 */ 786/* File: armv5te/OP_CONST_WIDE_HIGH16.S */ 787 /* const-wide/high16 vAA, #+BBBB000000000000 */ 788 FETCH(r1, 1) @ r1<- 0000BBBB (zero-extended) 789 mov r3, rINST, lsr #8 @ r3<- AA 790 mov r0, #0 @ r0<- 00000000 791 mov r1, r1, lsl #16 @ r1<- BBBB0000 792 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 793 add r3, rFP, r3, lsl #2 @ r3<- &fp[AA] 794 GET_INST_OPCODE(ip) @ extract opcode from rINST 795 stmia r3, {r0-r1} @ vAA<- r0/r1 796 GOTO_OPCODE(ip) @ jump to next instruction 797 798/* ------------------------------ */ 799 .balign 64 800.L_OP_CONST_STRING: /* 0x1a */ 801/* File: armv5te/OP_CONST_STRING.S */ 802 /* const/string vAA, String@BBBB */ 803 FETCH(r1, 1) @ r1<- BBBB 804 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- glue->methodClassDex 805 mov r9, rINST, lsr #8 @ r9<- AA 806 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 807 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 808 cmp r0, #0 @ not yet resolved? 809 beq .LOP_CONST_STRING_resolve 810 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 811 GET_INST_OPCODE(ip) @ extract opcode from rINST 812 SET_VREG(r0, r9) @ vAA<- r0 813 GOTO_OPCODE(ip) @ jump to next instruction 814 815/* ------------------------------ */ 816 .balign 64 817.L_OP_CONST_STRING_JUMBO: /* 0x1b */ 818/* File: armv5te/OP_CONST_STRING_JUMBO.S */ 819 /* const/string vAA, String@BBBBBBBB */ 820 FETCH(r0, 1) @ r0<- bbbb (low) 821 FETCH(r1, 2) @ r1<- BBBB (high) 822 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- glue->methodClassDex 823 mov r9, rINST, lsr #8 @ r9<- AA 824 ldr r2, [r2, #offDvmDex_pResStrings] @ r2<- dvmDex->pResStrings 825 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 826 ldr r0, [r2, r1, lsl #2] @ r0<- pResStrings[BBBB] 827 cmp r0, #0 828 beq .LOP_CONST_STRING_JUMBO_resolve 829 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 830 GET_INST_OPCODE(ip) @ extract opcode from rINST 831 SET_VREG(r0, r9) @ vAA<- r0 832 GOTO_OPCODE(ip) @ jump to next instruction 833 834/* ------------------------------ */ 835 .balign 64 836.L_OP_CONST_CLASS: /* 0x1c */ 837/* File: armv5te/OP_CONST_CLASS.S */ 838 /* const/class vAA, Class@BBBB */ 839 FETCH(r1, 1) @ r1<- BBBB 840 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- glue->methodClassDex 841 mov r9, rINST, lsr #8 @ r9<- AA 842 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- dvmDex->pResClasses 843 ldr r0, [r2, r1, lsl #2] @ r0<- pResClasses[BBBB] 844 cmp r0, #0 @ not yet resolved? 845 beq .LOP_CONST_CLASS_resolve 846 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 847 GET_INST_OPCODE(ip) @ extract opcode from rINST 848 SET_VREG(r0, r9) @ vAA<- r0 849 GOTO_OPCODE(ip) @ jump to next instruction 850 851/* ------------------------------ */ 852 .balign 64 853.L_OP_MONITOR_ENTER: /* 0x1d */ 854/* File: armv5te/OP_MONITOR_ENTER.S */ 855 /* 856 * Synchronize on an object. 857 */ 858 /* monitor-enter vAA */ 859 mov r2, rINST, lsr #8 @ r2<- AA 860 GET_VREG(r1, r2) @ r1<- vAA (object) 861 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 862 cmp r1, #0 @ null object? 863 EXPORT_PC() @ need for precise GC, MONITOR_TRACKING 864 beq common_errNullObject @ null object, throw an exception 865 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 866 bl dvmLockObject @ call(self, obj) 867#ifdef WITH_DEADLOCK_PREDICTION /* implies WITH_MONITOR_TRACKING */ 868 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 869 ldr r1, [r0, #offThread_exception] @ check for exception 870 cmp r1, #0 871 bne common_exceptionThrown @ exception raised, bail out 872#endif 873 GET_INST_OPCODE(ip) @ extract opcode from rINST 874 GOTO_OPCODE(ip) @ jump to next instruction 875 876/* ------------------------------ */ 877 .balign 64 878.L_OP_MONITOR_EXIT: /* 0x1e */ 879/* File: armv5te/OP_MONITOR_EXIT.S */ 880 /* 881 * Unlock an object. 882 * 883 * Exceptions that occur when unlocking a monitor need to appear as 884 * if they happened at the following instruction. See the Dalvik 885 * instruction spec. 886 */ 887 /* monitor-exit vAA */ 888 mov r2, rINST, lsr #8 @ r2<- AA 889 EXPORT_PC() @ before fetch: export the PC 890 GET_VREG(r1, r2) @ r1<- vAA (object) 891 cmp r1, #0 @ null object? 892 beq 1f @ yes 893 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 894 bl dvmUnlockObject @ r0<- success for unlock(self, obj) 895 cmp r0, #0 @ failed? 896 FETCH_ADVANCE_INST(1) @ before throw: advance rPC, load rINST 897 beq common_exceptionThrown @ yes, exception is pending 898 GET_INST_OPCODE(ip) @ extract opcode from rINST 899 GOTO_OPCODE(ip) @ jump to next instruction 9001: 901 FETCH_ADVANCE_INST(1) @ advance before throw 902 b common_errNullObject 903 904/* ------------------------------ */ 905 .balign 64 906.L_OP_CHECK_CAST: /* 0x1f */ 907/* File: armv5te/OP_CHECK_CAST.S */ 908 /* 909 * Check to see if a cast from one class to another is allowed. 910 */ 911 /* check-cast vAA, class@BBBB */ 912 mov r3, rINST, lsr #8 @ r3<- AA 913 FETCH(r2, 1) @ r2<- BBBB 914 GET_VREG(r9, r3) @ r9<- object 915 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- pDvmDex 916 cmp r9, #0 @ is object null? 917 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 918 beq .LOP_CHECK_CAST_okay @ null obj, cast always succeeds 919 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 920 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 921 cmp r1, #0 @ have we resolved this before? 922 beq .LOP_CHECK_CAST_resolve @ not resolved, do it now 923.LOP_CHECK_CAST_resolved: 924 cmp r0, r1 @ same class (trivial success)? 925 bne .LOP_CHECK_CAST_fullcheck @ no, do full check 926.LOP_CHECK_CAST_okay: 927 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 928 GET_INST_OPCODE(ip) @ extract opcode from rINST 929 GOTO_OPCODE(ip) @ jump to next instruction 930 931/* ------------------------------ */ 932 .balign 64 933.L_OP_INSTANCE_OF: /* 0x20 */ 934/* File: armv5te/OP_INSTANCE_OF.S */ 935 /* 936 * Check to see if an object reference is an instance of a class. 937 * 938 * Most common situation is a non-null object, being compared against 939 * an already-resolved class. 940 */ 941 /* instance-of vA, vB, class@CCCC */ 942 mov r3, rINST, lsr #12 @ r3<- B 943 mov r9, rINST, lsr #8 @ r9<- A+ 944 GET_VREG(r0, r3) @ r0<- vB (object) 945 and r9, r9, #15 @ r9<- A 946 cmp r0, #0 @ is object null? 947 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- pDvmDex 948 beq .LOP_INSTANCE_OF_store @ null obj, not an instance, store r0 949 FETCH(r3, 1) @ r3<- CCCC 950 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 951 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 952 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 953 cmp r1, #0 @ have we resolved this before? 954 beq .LOP_INSTANCE_OF_resolve @ not resolved, do it now 955.LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class 956 cmp r0, r1 @ same class (trivial success)? 957 beq .LOP_INSTANCE_OF_trivial @ yes, trivial finish 958 b .LOP_INSTANCE_OF_fullcheck @ no, do full check 959 960/* ------------------------------ */ 961 .balign 64 962.L_OP_ARRAY_LENGTH: /* 0x21 */ 963/* File: armv6t2/OP_ARRAY_LENGTH.S */ 964 /* 965 * Return the length of an array. 966 */ 967 mov r1, rINST, lsr #12 @ r1<- B 968 ubfx r2, rINST, #8, #4 @ r2<- A 969 GET_VREG(r0, r1) @ r0<- vB (object ref) 970 cmp r0, #0 @ is object null? 971 beq common_errNullObject @ yup, fail 972 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 973 ldr r3, [r0, #offArrayObject_length] @ r3<- array length 974 GET_INST_OPCODE(ip) @ extract opcode from rINST 975 SET_VREG(r3, r2) @ vB<- length 976 GOTO_OPCODE(ip) @ jump to next instruction 977 978/* ------------------------------ */ 979 .balign 64 980.L_OP_NEW_INSTANCE: /* 0x22 */ 981/* File: armv5te/OP_NEW_INSTANCE.S */ 982 /* 983 * Create a new instance of a class. 984 */ 985 /* new-instance vAA, class@BBBB */ 986 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 987 FETCH(r1, 1) @ r1<- BBBB 988 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 989 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 990 EXPORT_PC() @ req'd for init, resolve, alloc 991 cmp r0, #0 @ already resolved? 992 beq .LOP_NEW_INSTANCE_resolve @ no, resolve it now 993.LOP_NEW_INSTANCE_resolved: @ r0=class 994 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 995 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 996 bne .LOP_NEW_INSTANCE_needinit @ no, init class now 997.LOP_NEW_INSTANCE_initialized: @ r0=class 998 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 999 bl dvmAllocObject @ r0<- new object 1000 b .LOP_NEW_INSTANCE_finish @ continue 1001 1002/* ------------------------------ */ 1003 .balign 64 1004.L_OP_NEW_ARRAY: /* 0x23 */ 1005/* File: armv5te/OP_NEW_ARRAY.S */ 1006 /* 1007 * Allocate an array of objects, specified with the array class 1008 * and a count. 1009 * 1010 * The verifier guarantees that this is an array class, so we don't 1011 * check for it here. 1012 */ 1013 /* new-array vA, vB, class@CCCC */ 1014 mov r0, rINST, lsr #12 @ r0<- B 1015 FETCH(r2, 1) @ r2<- CCCC 1016 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 1017 GET_VREG(r1, r0) @ r1<- vB (array length) 1018 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1019 cmp r1, #0 @ check length 1020 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 1021 bmi common_errNegativeArraySize @ negative length, bail 1022 cmp r0, #0 @ already resolved? 1023 EXPORT_PC() @ req'd for resolve, alloc 1024 bne .LOP_NEW_ARRAY_finish @ resolved, continue 1025 b .LOP_NEW_ARRAY_resolve @ do resolve now 1026 1027/* ------------------------------ */ 1028 .balign 64 1029.L_OP_FILLED_NEW_ARRAY: /* 0x24 */ 1030/* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1031 /* 1032 * Create a new array with elements filled from registers. 1033 * 1034 * for: filled-new-array, filled-new-array/range 1035 */ 1036 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1037 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1038 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 1039 FETCH(r1, 1) @ r1<- BBBB 1040 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1041 EXPORT_PC() @ need for resolve and alloc 1042 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1043 mov r10, rINST, lsr #8 @ r10<- AA or BA 1044 cmp r0, #0 @ already resolved? 1045 bne .LOP_FILLED_NEW_ARRAY_continue @ yes, continue on 10468: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 1047 mov r2, #0 @ r2<- false 1048 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1049 bl dvmResolveClass @ r0<- call(clazz, ref) 1050 cmp r0, #0 @ got null? 1051 beq common_exceptionThrown @ yes, handle exception 1052 b .LOP_FILLED_NEW_ARRAY_continue 1053 1054/* ------------------------------ */ 1055 .balign 64 1056.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */ 1057/* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */ 1058/* File: armv5te/OP_FILLED_NEW_ARRAY.S */ 1059 /* 1060 * Create a new array with elements filled from registers. 1061 * 1062 * for: filled-new-array, filled-new-array/range 1063 */ 1064 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 1065 /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */ 1066 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 1067 FETCH(r1, 1) @ r1<- BBBB 1068 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 1069 EXPORT_PC() @ need for resolve and alloc 1070 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 1071 mov r10, rINST, lsr #8 @ r10<- AA or BA 1072 cmp r0, #0 @ already resolved? 1073 bne .LOP_FILLED_NEW_ARRAY_RANGE_continue @ yes, continue on 10748: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 1075 mov r2, #0 @ r2<- false 1076 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 1077 bl dvmResolveClass @ r0<- call(clazz, ref) 1078 cmp r0, #0 @ got null? 1079 beq common_exceptionThrown @ yes, handle exception 1080 b .LOP_FILLED_NEW_ARRAY_RANGE_continue 1081 1082 1083/* ------------------------------ */ 1084 .balign 64 1085.L_OP_FILL_ARRAY_DATA: /* 0x26 */ 1086/* File: armv5te/OP_FILL_ARRAY_DATA.S */ 1087 /* fill-array-data vAA, +BBBBBBBB */ 1088 FETCH(r0, 1) @ r0<- bbbb (lo) 1089 FETCH(r1, 2) @ r1<- BBBB (hi) 1090 mov r3, rINST, lsr #8 @ r3<- AA 1091 orr r1, r0, r1, lsl #16 @ r1<- BBBBbbbb 1092 GET_VREG(r0, r3) @ r0<- vAA (array object) 1093 add r1, rPC, r1, lsl #1 @ r1<- PC + BBBBbbbb*2 (array data off.) 1094 EXPORT_PC(); 1095 bl dvmInterpHandleFillArrayData@ fill the array with predefined data 1096 cmp r0, #0 @ 0 means an exception is thrown 1097 beq common_exceptionThrown @ has exception 1098 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 1099 GET_INST_OPCODE(ip) @ extract opcode from rINST 1100 GOTO_OPCODE(ip) @ jump to next instruction 1101 1102/* ------------------------------ */ 1103 .balign 64 1104.L_OP_THROW: /* 0x27 */ 1105/* File: armv5te/OP_THROW.S */ 1106 /* 1107 * Throw an exception object in the current thread. 1108 */ 1109 /* throw vAA */ 1110 mov r2, rINST, lsr #8 @ r2<- AA 1111 GET_VREG(r1, r2) @ r1<- vAA (exception object) 1112 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 1113 EXPORT_PC() @ exception handler can throw 1114 cmp r1, #0 @ null object? 1115 beq common_errNullObject @ yes, throw an NPE instead 1116 @ bypass dvmSetException, just store it 1117 str r1, [r0, #offThread_exception] @ thread->exception<- obj 1118 b common_exceptionThrown 1119 1120/* ------------------------------ */ 1121 .balign 64 1122.L_OP_GOTO: /* 0x28 */ 1123/* File: armv5te/OP_GOTO.S */ 1124 /* 1125 * Unconditional branch, 8-bit offset. 1126 * 1127 * The branch distance is a signed code-unit offset, which we need to 1128 * double to get a byte offset. 1129 */ 1130 /* goto +AA */ 1131 mov r0, rINST, lsl #16 @ r0<- AAxx0000 1132 movs r9, r0, asr #24 @ r9<- ssssssAA (sign-extended) 1133 mov r9, r9, lsl #1 @ r9<- byte offset 1134 bmi common_backwardBranch @ backward branch, do periodic checks 1135#if defined(WITH_JIT) 1136 GET_JIT_PROF_TABLE(r0) 1137 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1138 cmp r0,#0 1139 bne common_updateProfile 1140 GET_INST_OPCODE(ip) @ extract opcode from rINST 1141 GOTO_OPCODE(ip) @ jump to next instruction 1142#else 1143 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1144 GET_INST_OPCODE(ip) @ extract opcode from rINST 1145 GOTO_OPCODE(ip) @ jump to next instruction 1146#endif 1147 1148/* ------------------------------ */ 1149 .balign 64 1150.L_OP_GOTO_16: /* 0x29 */ 1151/* File: armv5te/OP_GOTO_16.S */ 1152 /* 1153 * Unconditional branch, 16-bit offset. 1154 * 1155 * The branch distance is a signed code-unit offset, which we need to 1156 * double to get a byte offset. 1157 */ 1158 /* goto/16 +AAAA */ 1159 FETCH_S(r0, 1) @ r0<- ssssAAAA (sign-extended) 1160 movs r9, r0, asl #1 @ r9<- byte offset, check sign 1161 bmi common_backwardBranch @ backward branch, do periodic checks 1162#if defined(WITH_JIT) 1163 GET_JIT_PROF_TABLE(r0) 1164 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1165 cmp r0,#0 1166 bne common_updateProfile 1167 GET_INST_OPCODE(ip) @ extract opcode from rINST 1168 GOTO_OPCODE(ip) @ jump to next instruction 1169#else 1170 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1171 GET_INST_OPCODE(ip) @ extract opcode from rINST 1172 GOTO_OPCODE(ip) @ jump to next instruction 1173#endif 1174 1175/* ------------------------------ */ 1176 .balign 64 1177.L_OP_GOTO_32: /* 0x2a */ 1178/* File: armv5te/OP_GOTO_32.S */ 1179 /* 1180 * Unconditional branch, 32-bit offset. 1181 * 1182 * The branch distance is a signed code-unit offset, which we need to 1183 * double to get a byte offset. 1184 * 1185 * Unlike most opcodes, this one is allowed to branch to itself, so 1186 * our "backward branch" test must be "<=0" instead of "<0". The ORRS 1187 * instruction doesn't affect the V flag, so we need to clear it 1188 * explicitly. 1189 */ 1190 /* goto/32 +AAAAAAAA */ 1191 FETCH(r0, 1) @ r0<- aaaa (lo) 1192 FETCH(r1, 2) @ r1<- AAAA (hi) 1193 cmp ip, ip @ (clear V flag during stall) 1194 orrs r0, r0, r1, lsl #16 @ r0<- AAAAaaaa, check sign 1195 mov r9, r0, asl #1 @ r9<- byte offset 1196 ble common_backwardBranch @ backward branch, do periodic checks 1197#if defined(WITH_JIT) 1198 GET_JIT_PROF_TABLE(r0) 1199 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1200 cmp r0,#0 1201 bne common_updateProfile 1202 GET_INST_OPCODE(ip) @ extract opcode from rINST 1203 GOTO_OPCODE(ip) @ jump to next instruction 1204#else 1205 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1206 GET_INST_OPCODE(ip) @ extract opcode from rINST 1207 GOTO_OPCODE(ip) @ jump to next instruction 1208#endif 1209 1210/* ------------------------------ */ 1211 .balign 64 1212.L_OP_PACKED_SWITCH: /* 0x2b */ 1213/* File: armv5te/OP_PACKED_SWITCH.S */ 1214 /* 1215 * Handle a packed-switch or sparse-switch instruction. In both cases 1216 * we decode it and hand it off to a helper function. 1217 * 1218 * We don't really expect backward branches in a switch statement, but 1219 * they're perfectly legal, so we check for them here. 1220 * 1221 * for: packed-switch, sparse-switch 1222 */ 1223 /* op vAA, +BBBB */ 1224 FETCH(r0, 1) @ r0<- bbbb (lo) 1225 FETCH(r1, 2) @ r1<- BBBB (hi) 1226 mov r3, rINST, lsr #8 @ r3<- AA 1227 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1228 GET_VREG(r1, r3) @ r1<- vAA 1229 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1230 bl dvmInterpHandlePackedSwitch @ r0<- code-unit branch offset 1231 movs r9, r0, asl #1 @ r9<- branch byte offset, check sign 1232 bmi common_backwardBranch @ backward branch, do periodic checks 1233 beq common_backwardBranch @ (want to use BLE but V is unknown) 1234#if defined(WITH_JIT) 1235 GET_JIT_PROF_TABLE(r0) 1236 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1237 cmp r0,#0 1238 bne common_updateProfile 1239 GET_INST_OPCODE(ip) @ extract opcode from rINST 1240 GOTO_OPCODE(ip) @ jump to next instruction 1241#else 1242 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1243 GET_INST_OPCODE(ip) @ extract opcode from rINST 1244 GOTO_OPCODE(ip) @ jump to next instruction 1245#endif 1246 1247/* ------------------------------ */ 1248 .balign 64 1249.L_OP_SPARSE_SWITCH: /* 0x2c */ 1250/* File: armv5te/OP_SPARSE_SWITCH.S */ 1251/* File: armv5te/OP_PACKED_SWITCH.S */ 1252 /* 1253 * Handle a packed-switch or sparse-switch instruction. In both cases 1254 * we decode it and hand it off to a helper function. 1255 * 1256 * We don't really expect backward branches in a switch statement, but 1257 * they're perfectly legal, so we check for them here. 1258 * 1259 * for: packed-switch, sparse-switch 1260 */ 1261 /* op vAA, +BBBB */ 1262 FETCH(r0, 1) @ r0<- bbbb (lo) 1263 FETCH(r1, 2) @ r1<- BBBB (hi) 1264 mov r3, rINST, lsr #8 @ r3<- AA 1265 orr r0, r0, r1, lsl #16 @ r0<- BBBBbbbb 1266 GET_VREG(r1, r3) @ r1<- vAA 1267 add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 1268 bl dvmInterpHandleSparseSwitch @ r0<- code-unit branch offset 1269 movs r9, r0, asl #1 @ r9<- branch byte offset, check sign 1270 bmi common_backwardBranch @ backward branch, do periodic checks 1271 beq common_backwardBranch @ (want to use BLE but V is unknown) 1272#if defined(WITH_JIT) 1273 GET_JIT_PROF_TABLE(r0) 1274 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1275 cmp r0,#0 1276 bne common_updateProfile 1277 GET_INST_OPCODE(ip) @ extract opcode from rINST 1278 GOTO_OPCODE(ip) @ jump to next instruction 1279#else 1280 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1281 GET_INST_OPCODE(ip) @ extract opcode from rINST 1282 GOTO_OPCODE(ip) @ jump to next instruction 1283#endif 1284 1285 1286/* ------------------------------ */ 1287 .balign 64 1288.L_OP_CMPL_FLOAT: /* 0x2d */ 1289/* File: arm-vfp/OP_CMPL_FLOAT.S */ 1290 /* 1291 * Compare two floating-point values. Puts 0, 1, or -1 into the 1292 * destination register based on the results of the comparison. 1293 * 1294 * int compare(x, y) { 1295 * if (x == y) { 1296 * return 0; 1297 * } else if (x > y) { 1298 * return 1; 1299 * } else if (x < y) { 1300 * return -1; 1301 * } else { 1302 * return -1; 1303 * } 1304 * } 1305 */ 1306 /* op vAA, vBB, vCC */ 1307 FETCH(r0, 1) @ r0<- CCBB 1308 mov r9, rINST, lsr #8 @ r9<- AA 1309 and r2, r0, #255 @ r2<- BB 1310 mov r3, r0, lsr #8 @ r3<- CC 1311 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1312 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1313 flds s0, [r2] @ s0<- vBB 1314 flds s1, [r3] @ s1<- vCC 1315 fcmpes s0, s1 @ compare (vBB, vCC) 1316 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1317 mvn r0, #0 @ r0<- -1 (default) 1318 GET_INST_OPCODE(ip) @ extract opcode from rINST 1319 fmstat @ export status flags 1320 movgt r0, #1 @ (greater than) r1<- 1 1321 moveq r0, #0 @ (equal) r1<- 0 1322 b .LOP_CMPL_FLOAT_finish @ argh 1323 1324 1325/* ------------------------------ */ 1326 .balign 64 1327.L_OP_CMPG_FLOAT: /* 0x2e */ 1328/* File: arm-vfp/OP_CMPG_FLOAT.S */ 1329 /* 1330 * Compare two floating-point values. Puts 0, 1, or -1 into the 1331 * destination register based on the results of the comparison. 1332 * 1333 * int compare(x, y) { 1334 * if (x == y) { 1335 * return 0; 1336 * } else if (x < y) { 1337 * return -1; 1338 * } else if (x > y) { 1339 * return 1; 1340 * } else { 1341 * return 1; 1342 * } 1343 * } 1344 */ 1345 /* op vAA, vBB, vCC */ 1346 FETCH(r0, 1) @ r0<- CCBB 1347 mov r9, rINST, lsr #8 @ r9<- AA 1348 and r2, r0, #255 @ r2<- BB 1349 mov r3, r0, lsr #8 @ r3<- CC 1350 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1351 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1352 flds s0, [r2] @ s0<- vBB 1353 flds s1, [r3] @ s1<- vCC 1354 fcmpes s0, s1 @ compare (vBB, vCC) 1355 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1356 mov r0, #1 @ r0<- 1 (default) 1357 GET_INST_OPCODE(ip) @ extract opcode from rINST 1358 fmstat @ export status flags 1359 mvnmi r0, #0 @ (less than) r1<- -1 1360 moveq r0, #0 @ (equal) r1<- 0 1361 b .LOP_CMPG_FLOAT_finish @ argh 1362 1363 1364/* ------------------------------ */ 1365 .balign 64 1366.L_OP_CMPL_DOUBLE: /* 0x2f */ 1367/* File: arm-vfp/OP_CMPL_DOUBLE.S */ 1368 /* 1369 * Compare two floating-point values. Puts 0, 1, or -1 into the 1370 * destination register based on the results of the comparison. 1371 * 1372 * int compare(x, y) { 1373 * if (x == y) { 1374 * return 0; 1375 * } else if (x > y) { 1376 * return 1; 1377 * } else if (x < y) { 1378 * return -1; 1379 * } else { 1380 * return -1; 1381 * } 1382 * } 1383 */ 1384 /* op vAA, vBB, vCC */ 1385 FETCH(r0, 1) @ r0<- CCBB 1386 mov r9, rINST, lsr #8 @ r9<- AA 1387 and r2, r0, #255 @ r2<- BB 1388 mov r3, r0, lsr #8 @ r3<- CC 1389 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1390 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1391 fldd d0, [r2] @ d0<- vBB 1392 fldd d1, [r3] @ d1<- vCC 1393 fcmped d0, d1 @ compare (vBB, vCC) 1394 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1395 mvn r0, #0 @ r0<- -1 (default) 1396 GET_INST_OPCODE(ip) @ extract opcode from rINST 1397 fmstat @ export status flags 1398 movgt r0, #1 @ (greater than) r1<- 1 1399 moveq r0, #0 @ (equal) r1<- 0 1400 b .LOP_CMPL_DOUBLE_finish @ argh 1401 1402 1403/* ------------------------------ */ 1404 .balign 64 1405.L_OP_CMPG_DOUBLE: /* 0x30 */ 1406/* File: arm-vfp/OP_CMPG_DOUBLE.S */ 1407 /* 1408 * Compare two floating-point values. Puts 0, 1, or -1 into the 1409 * destination register based on the results of the comparison. 1410 * 1411 * int compare(x, y) { 1412 * if (x == y) { 1413 * return 0; 1414 * } else if (x < y) { 1415 * return -1; 1416 * } else if (x > y) { 1417 * return 1; 1418 * } else { 1419 * return 1; 1420 * } 1421 * } 1422 */ 1423 /* op vAA, vBB, vCC */ 1424 FETCH(r0, 1) @ r0<- CCBB 1425 mov r9, rINST, lsr #8 @ r9<- AA 1426 and r2, r0, #255 @ r2<- BB 1427 mov r3, r0, lsr #8 @ r3<- CC 1428 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 1429 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 1430 fldd d0, [r2] @ d0<- vBB 1431 fldd d1, [r3] @ d1<- vCC 1432 fcmped d0, d1 @ compare (vBB, vCC) 1433 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1434 mov r0, #1 @ r0<- 1 (default) 1435 GET_INST_OPCODE(ip) @ extract opcode from rINST 1436 fmstat @ export status flags 1437 mvnmi r0, #0 @ (less than) r1<- -1 1438 moveq r0, #0 @ (equal) r1<- 0 1439 b .LOP_CMPG_DOUBLE_finish @ argh 1440 1441 1442/* ------------------------------ */ 1443 .balign 64 1444.L_OP_CMP_LONG: /* 0x31 */ 1445/* File: armv5te/OP_CMP_LONG.S */ 1446 /* 1447 * Compare two 64-bit values. Puts 0, 1, or -1 into the destination 1448 * register based on the results of the comparison. 1449 * 1450 * We load the full values with LDM, but in practice many values could 1451 * be resolved by only looking at the high word. This could be made 1452 * faster or slower by splitting the LDM into a pair of LDRs. 1453 * 1454 * If we just wanted to set condition flags, we could do this: 1455 * subs ip, r0, r2 1456 * sbcs ip, r1, r3 1457 * subeqs ip, r0, r2 1458 * Leaving { <0, 0, >0 } in ip. However, we have to set it to a specific 1459 * integer value, which we can do with 2 conditional mov/mvn instructions 1460 * (set 1, set -1; if they're equal we already have 0 in ip), giving 1461 * us a constant 5-cycle path plus a branch at the end to the 1462 * instruction epilogue code. The multi-compare approach below needs 1463 * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch 1464 * in the worst case (the 64-bit values are equal). 1465 */ 1466 /* cmp-long vAA, vBB, vCC */ 1467 FETCH(r0, 1) @ r0<- CCBB 1468 mov r9, rINST, lsr #8 @ r9<- AA 1469 and r2, r0, #255 @ r2<- BB 1470 mov r3, r0, lsr #8 @ r3<- CC 1471 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 1472 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 1473 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 1474 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 1475 cmp r1, r3 @ compare (vBB+1, vCC+1) 1476 blt .LOP_CMP_LONG_less @ signed compare on high part 1477 bgt .LOP_CMP_LONG_greater 1478 subs r1, r0, r2 @ r1<- r0 - r2 1479 bhi .LOP_CMP_LONG_greater @ unsigned compare on low part 1480 bne .LOP_CMP_LONG_less 1481 b .LOP_CMP_LONG_finish @ equal; r1 already holds 0 1482 1483/* ------------------------------ */ 1484 .balign 64 1485.L_OP_IF_EQ: /* 0x32 */ 1486/* File: armv6t2/OP_IF_EQ.S */ 1487/* File: armv6t2/bincmp.S */ 1488 /* 1489 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1490 * fragment that specifies the *reverse* comparison to perform, e.g. 1491 * for "if-le" you would use "gt". 1492 * 1493 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1494 */ 1495 /* if-cmp vA, vB, +CCCC */ 1496 mov r1, rINST, lsr #12 @ r1<- B 1497 ubfx r0, rINST, #8, #4 @ r0<- A 1498 GET_VREG(r3, r1) @ r3<- vB 1499 GET_VREG(r2, r0) @ r2<- vA 1500 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1501 cmp r2, r3 @ compare (vA, vB) 1502 bne 1f @ branch to 1 if comparison failed 1503 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1504 movs r9, r9, asl #1 @ convert to bytes, check sign 1505 bmi common_backwardBranch @ yes, do periodic checks 15061: 1507#if defined(WITH_JIT) 1508 GET_JIT_PROF_TABLE(r0) 1509 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1510 b common_testUpdateProfile 1511#else 1512 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1513 GET_INST_OPCODE(ip) @ extract opcode from rINST 1514 GOTO_OPCODE(ip) @ jump to next instruction 1515#endif 1516 1517 1518/* ------------------------------ */ 1519 .balign 64 1520.L_OP_IF_NE: /* 0x33 */ 1521/* File: armv6t2/OP_IF_NE.S */ 1522/* File: armv6t2/bincmp.S */ 1523 /* 1524 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1525 * fragment that specifies the *reverse* comparison to perform, e.g. 1526 * for "if-le" you would use "gt". 1527 * 1528 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1529 */ 1530 /* if-cmp vA, vB, +CCCC */ 1531 mov r1, rINST, lsr #12 @ r1<- B 1532 ubfx r0, rINST, #8, #4 @ r0<- A 1533 GET_VREG(r3, r1) @ r3<- vB 1534 GET_VREG(r2, r0) @ r2<- vA 1535 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1536 cmp r2, r3 @ compare (vA, vB) 1537 beq 1f @ branch to 1 if comparison failed 1538 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1539 movs r9, r9, asl #1 @ convert to bytes, check sign 1540 bmi common_backwardBranch @ yes, do periodic checks 15411: 1542#if defined(WITH_JIT) 1543 GET_JIT_PROF_TABLE(r0) 1544 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1545 b common_testUpdateProfile 1546#else 1547 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1548 GET_INST_OPCODE(ip) @ extract opcode from rINST 1549 GOTO_OPCODE(ip) @ jump to next instruction 1550#endif 1551 1552 1553/* ------------------------------ */ 1554 .balign 64 1555.L_OP_IF_LT: /* 0x34 */ 1556/* File: armv6t2/OP_IF_LT.S */ 1557/* File: armv6t2/bincmp.S */ 1558 /* 1559 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1560 * fragment that specifies the *reverse* comparison to perform, e.g. 1561 * for "if-le" you would use "gt". 1562 * 1563 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1564 */ 1565 /* if-cmp vA, vB, +CCCC */ 1566 mov r1, rINST, lsr #12 @ r1<- B 1567 ubfx r0, rINST, #8, #4 @ r0<- A 1568 GET_VREG(r3, r1) @ r3<- vB 1569 GET_VREG(r2, r0) @ r2<- vA 1570 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1571 cmp r2, r3 @ compare (vA, vB) 1572 bge 1f @ branch to 1 if comparison failed 1573 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1574 movs r9, r9, asl #1 @ convert to bytes, check sign 1575 bmi common_backwardBranch @ yes, do periodic checks 15761: 1577#if defined(WITH_JIT) 1578 GET_JIT_PROF_TABLE(r0) 1579 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1580 b common_testUpdateProfile 1581#else 1582 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1583 GET_INST_OPCODE(ip) @ extract opcode from rINST 1584 GOTO_OPCODE(ip) @ jump to next instruction 1585#endif 1586 1587 1588/* ------------------------------ */ 1589 .balign 64 1590.L_OP_IF_GE: /* 0x35 */ 1591/* File: armv6t2/OP_IF_GE.S */ 1592/* File: armv6t2/bincmp.S */ 1593 /* 1594 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1595 * fragment that specifies the *reverse* comparison to perform, e.g. 1596 * for "if-le" you would use "gt". 1597 * 1598 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1599 */ 1600 /* if-cmp vA, vB, +CCCC */ 1601 mov r1, rINST, lsr #12 @ r1<- B 1602 ubfx r0, rINST, #8, #4 @ r0<- A 1603 GET_VREG(r3, r1) @ r3<- vB 1604 GET_VREG(r2, r0) @ r2<- vA 1605 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1606 cmp r2, r3 @ compare (vA, vB) 1607 blt 1f @ branch to 1 if comparison failed 1608 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1609 movs r9, r9, asl #1 @ convert to bytes, check sign 1610 bmi common_backwardBranch @ yes, do periodic checks 16111: 1612#if defined(WITH_JIT) 1613 GET_JIT_PROF_TABLE(r0) 1614 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1615 b common_testUpdateProfile 1616#else 1617 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1618 GET_INST_OPCODE(ip) @ extract opcode from rINST 1619 GOTO_OPCODE(ip) @ jump to next instruction 1620#endif 1621 1622 1623/* ------------------------------ */ 1624 .balign 64 1625.L_OP_IF_GT: /* 0x36 */ 1626/* File: armv6t2/OP_IF_GT.S */ 1627/* File: armv6t2/bincmp.S */ 1628 /* 1629 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1630 * fragment that specifies the *reverse* comparison to perform, e.g. 1631 * for "if-le" you would use "gt". 1632 * 1633 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1634 */ 1635 /* if-cmp vA, vB, +CCCC */ 1636 mov r1, rINST, lsr #12 @ r1<- B 1637 ubfx r0, rINST, #8, #4 @ r0<- A 1638 GET_VREG(r3, r1) @ r3<- vB 1639 GET_VREG(r2, r0) @ r2<- vA 1640 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1641 cmp r2, r3 @ compare (vA, vB) 1642 ble 1f @ branch to 1 if comparison failed 1643 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1644 movs r9, r9, asl #1 @ convert to bytes, check sign 1645 bmi common_backwardBranch @ yes, do periodic checks 16461: 1647#if defined(WITH_JIT) 1648 GET_JIT_PROF_TABLE(r0) 1649 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1650 b common_testUpdateProfile 1651#else 1652 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1653 GET_INST_OPCODE(ip) @ extract opcode from rINST 1654 GOTO_OPCODE(ip) @ jump to next instruction 1655#endif 1656 1657 1658/* ------------------------------ */ 1659 .balign 64 1660.L_OP_IF_LE: /* 0x37 */ 1661/* File: armv6t2/OP_IF_LE.S */ 1662/* File: armv6t2/bincmp.S */ 1663 /* 1664 * Generic two-operand compare-and-branch operation. Provide a "revcmp" 1665 * fragment that specifies the *reverse* comparison to perform, e.g. 1666 * for "if-le" you would use "gt". 1667 * 1668 * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le 1669 */ 1670 /* if-cmp vA, vB, +CCCC */ 1671 mov r1, rINST, lsr #12 @ r1<- B 1672 ubfx r0, rINST, #8, #4 @ r0<- A 1673 GET_VREG(r3, r1) @ r3<- vB 1674 GET_VREG(r2, r0) @ r2<- vA 1675 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1676 cmp r2, r3 @ compare (vA, vB) 1677 bgt 1f @ branch to 1 if comparison failed 1678 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1679 movs r9, r9, asl #1 @ convert to bytes, check sign 1680 bmi common_backwardBranch @ yes, do periodic checks 16811: 1682#if defined(WITH_JIT) 1683 GET_JIT_PROF_TABLE(r0) 1684 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1685 b common_testUpdateProfile 1686#else 1687 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1688 GET_INST_OPCODE(ip) @ extract opcode from rINST 1689 GOTO_OPCODE(ip) @ jump to next instruction 1690#endif 1691 1692 1693/* ------------------------------ */ 1694 .balign 64 1695.L_OP_IF_EQZ: /* 0x38 */ 1696/* File: armv5te/OP_IF_EQZ.S */ 1697/* File: armv5te/zcmp.S */ 1698 /* 1699 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1700 * fragment that specifies the *reverse* comparison to perform, e.g. 1701 * for "if-le" you would use "gt". 1702 * 1703 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1704 */ 1705 /* if-cmp vAA, +BBBB */ 1706 mov r0, rINST, lsr #8 @ r0<- AA 1707 GET_VREG(r2, r0) @ r2<- vAA 1708 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1709 cmp r2, #0 @ compare (vA, 0) 1710 bne 1f @ branch to 1 if comparison failed 1711 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1712 movs r9, r9, asl #1 @ convert to bytes, check sign 1713 bmi common_backwardBranch @ backward branch, do periodic checks 17141: 1715#if defined(WITH_JIT) 1716 GET_JIT_PROF_TABLE(r0) 1717 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1718 cmp r0,#0 1719 bne common_updateProfile 1720 GET_INST_OPCODE(ip) @ extract opcode from rINST 1721 GOTO_OPCODE(ip) @ jump to next instruction 1722#else 1723 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1724 GET_INST_OPCODE(ip) @ extract opcode from rINST 1725 GOTO_OPCODE(ip) @ jump to next instruction 1726#endif 1727 1728 1729/* ------------------------------ */ 1730 .balign 64 1731.L_OP_IF_NEZ: /* 0x39 */ 1732/* File: armv5te/OP_IF_NEZ.S */ 1733/* File: armv5te/zcmp.S */ 1734 /* 1735 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1736 * fragment that specifies the *reverse* comparison to perform, e.g. 1737 * for "if-le" you would use "gt". 1738 * 1739 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1740 */ 1741 /* if-cmp vAA, +BBBB */ 1742 mov r0, rINST, lsr #8 @ r0<- AA 1743 GET_VREG(r2, r0) @ r2<- vAA 1744 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1745 cmp r2, #0 @ compare (vA, 0) 1746 beq 1f @ branch to 1 if comparison failed 1747 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1748 movs r9, r9, asl #1 @ convert to bytes, check sign 1749 bmi common_backwardBranch @ backward branch, do periodic checks 17501: 1751#if defined(WITH_JIT) 1752 GET_JIT_PROF_TABLE(r0) 1753 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1754 cmp r0,#0 1755 bne common_updateProfile 1756 GET_INST_OPCODE(ip) @ extract opcode from rINST 1757 GOTO_OPCODE(ip) @ jump to next instruction 1758#else 1759 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1760 GET_INST_OPCODE(ip) @ extract opcode from rINST 1761 GOTO_OPCODE(ip) @ jump to next instruction 1762#endif 1763 1764 1765/* ------------------------------ */ 1766 .balign 64 1767.L_OP_IF_LTZ: /* 0x3a */ 1768/* File: armv5te/OP_IF_LTZ.S */ 1769/* File: armv5te/zcmp.S */ 1770 /* 1771 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1772 * fragment that specifies the *reverse* comparison to perform, e.g. 1773 * for "if-le" you would use "gt". 1774 * 1775 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1776 */ 1777 /* if-cmp vAA, +BBBB */ 1778 mov r0, rINST, lsr #8 @ r0<- AA 1779 GET_VREG(r2, r0) @ r2<- vAA 1780 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1781 cmp r2, #0 @ compare (vA, 0) 1782 bge 1f @ branch to 1 if comparison failed 1783 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1784 movs r9, r9, asl #1 @ convert to bytes, check sign 1785 bmi common_backwardBranch @ backward branch, do periodic checks 17861: 1787#if defined(WITH_JIT) 1788 GET_JIT_PROF_TABLE(r0) 1789 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1790 cmp r0,#0 1791 bne common_updateProfile 1792 GET_INST_OPCODE(ip) @ extract opcode from rINST 1793 GOTO_OPCODE(ip) @ jump to next instruction 1794#else 1795 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1796 GET_INST_OPCODE(ip) @ extract opcode from rINST 1797 GOTO_OPCODE(ip) @ jump to next instruction 1798#endif 1799 1800 1801/* ------------------------------ */ 1802 .balign 64 1803.L_OP_IF_GEZ: /* 0x3b */ 1804/* File: armv5te/OP_IF_GEZ.S */ 1805/* File: armv5te/zcmp.S */ 1806 /* 1807 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1808 * fragment that specifies the *reverse* comparison to perform, e.g. 1809 * for "if-le" you would use "gt". 1810 * 1811 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1812 */ 1813 /* if-cmp vAA, +BBBB */ 1814 mov r0, rINST, lsr #8 @ r0<- AA 1815 GET_VREG(r2, r0) @ r2<- vAA 1816 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1817 cmp r2, #0 @ compare (vA, 0) 1818 blt 1f @ branch to 1 if comparison failed 1819 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1820 movs r9, r9, asl #1 @ convert to bytes, check sign 1821 bmi common_backwardBranch @ backward branch, do periodic checks 18221: 1823#if defined(WITH_JIT) 1824 GET_JIT_PROF_TABLE(r0) 1825 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1826 cmp r0,#0 1827 bne common_updateProfile 1828 GET_INST_OPCODE(ip) @ extract opcode from rINST 1829 GOTO_OPCODE(ip) @ jump to next instruction 1830#else 1831 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1832 GET_INST_OPCODE(ip) @ extract opcode from rINST 1833 GOTO_OPCODE(ip) @ jump to next instruction 1834#endif 1835 1836 1837/* ------------------------------ */ 1838 .balign 64 1839.L_OP_IF_GTZ: /* 0x3c */ 1840/* File: armv5te/OP_IF_GTZ.S */ 1841/* File: armv5te/zcmp.S */ 1842 /* 1843 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1844 * fragment that specifies the *reverse* comparison to perform, e.g. 1845 * for "if-le" you would use "gt". 1846 * 1847 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1848 */ 1849 /* if-cmp vAA, +BBBB */ 1850 mov r0, rINST, lsr #8 @ r0<- AA 1851 GET_VREG(r2, r0) @ r2<- vAA 1852 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1853 cmp r2, #0 @ compare (vA, 0) 1854 ble 1f @ branch to 1 if comparison failed 1855 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1856 movs r9, r9, asl #1 @ convert to bytes, check sign 1857 bmi common_backwardBranch @ backward branch, do periodic checks 18581: 1859#if defined(WITH_JIT) 1860 GET_JIT_PROF_TABLE(r0) 1861 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1862 cmp r0,#0 1863 bne common_updateProfile 1864 GET_INST_OPCODE(ip) @ extract opcode from rINST 1865 GOTO_OPCODE(ip) @ jump to next instruction 1866#else 1867 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1868 GET_INST_OPCODE(ip) @ extract opcode from rINST 1869 GOTO_OPCODE(ip) @ jump to next instruction 1870#endif 1871 1872 1873/* ------------------------------ */ 1874 .balign 64 1875.L_OP_IF_LEZ: /* 0x3d */ 1876/* File: armv5te/OP_IF_LEZ.S */ 1877/* File: armv5te/zcmp.S */ 1878 /* 1879 * Generic one-operand compare-and-branch operation. Provide a "revcmp" 1880 * fragment that specifies the *reverse* comparison to perform, e.g. 1881 * for "if-le" you would use "gt". 1882 * 1883 * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez 1884 */ 1885 /* if-cmp vAA, +BBBB */ 1886 mov r0, rINST, lsr #8 @ r0<- AA 1887 GET_VREG(r2, r0) @ r2<- vAA 1888 mov r9, #4 @ r0<- BYTE branch dist for not-taken 1889 cmp r2, #0 @ compare (vA, 0) 1890 bgt 1f @ branch to 1 if comparison failed 1891 FETCH_S(r9, 1) @ r9<- branch offset, in code units 1892 movs r9, r9, asl #1 @ convert to bytes, check sign 1893 bmi common_backwardBranch @ backward branch, do periodic checks 18941: 1895#if defined(WITH_JIT) 1896 GET_JIT_PROF_TABLE(r0) 1897 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1898 cmp r0,#0 1899 bne common_updateProfile 1900 GET_INST_OPCODE(ip) @ extract opcode from rINST 1901 GOTO_OPCODE(ip) @ jump to next instruction 1902#else 1903 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 1904 GET_INST_OPCODE(ip) @ extract opcode from rINST 1905 GOTO_OPCODE(ip) @ jump to next instruction 1906#endif 1907 1908 1909/* ------------------------------ */ 1910 .balign 64 1911.L_OP_UNUSED_3E: /* 0x3e */ 1912/* File: armv5te/OP_UNUSED_3E.S */ 1913/* File: armv5te/unused.S */ 1914 bl common_abort 1915 1916 1917/* ------------------------------ */ 1918 .balign 64 1919.L_OP_UNUSED_3F: /* 0x3f */ 1920/* File: armv5te/OP_UNUSED_3F.S */ 1921/* File: armv5te/unused.S */ 1922 bl common_abort 1923 1924 1925/* ------------------------------ */ 1926 .balign 64 1927.L_OP_UNUSED_40: /* 0x40 */ 1928/* File: armv5te/OP_UNUSED_40.S */ 1929/* File: armv5te/unused.S */ 1930 bl common_abort 1931 1932 1933/* ------------------------------ */ 1934 .balign 64 1935.L_OP_UNUSED_41: /* 0x41 */ 1936/* File: armv5te/OP_UNUSED_41.S */ 1937/* File: armv5te/unused.S */ 1938 bl common_abort 1939 1940 1941/* ------------------------------ */ 1942 .balign 64 1943.L_OP_UNUSED_42: /* 0x42 */ 1944/* File: armv5te/OP_UNUSED_42.S */ 1945/* File: armv5te/unused.S */ 1946 bl common_abort 1947 1948 1949/* ------------------------------ */ 1950 .balign 64 1951.L_OP_UNUSED_43: /* 0x43 */ 1952/* File: armv5te/OP_UNUSED_43.S */ 1953/* File: armv5te/unused.S */ 1954 bl common_abort 1955 1956 1957/* ------------------------------ */ 1958 .balign 64 1959.L_OP_AGET: /* 0x44 */ 1960/* File: armv5te/OP_AGET.S */ 1961 /* 1962 * Array get, 32 bits or less. vAA <- vBB[vCC]. 1963 * 1964 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 1965 * instructions. We use a pair of FETCH_Bs instead. 1966 * 1967 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 1968 */ 1969 /* op vAA, vBB, vCC */ 1970 FETCH_B(r2, 1, 0) @ r2<- BB 1971 mov r9, rINST, lsr #8 @ r9<- AA 1972 FETCH_B(r3, 1, 1) @ r3<- CC 1973 GET_VREG(r0, r2) @ r0<- vBB (array object) 1974 GET_VREG(r1, r3) @ r1<- vCC (requested index) 1975 cmp r0, #0 @ null array object? 1976 beq common_errNullObject @ yes, bail 1977 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 1978 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 1979 cmp r1, r3 @ compare unsigned index, length 1980 bcs common_errArrayIndex @ index >= length, bail 1981 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 1982 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 1983 GET_INST_OPCODE(ip) @ extract opcode from rINST 1984 SET_VREG(r2, r9) @ vAA<- r2 1985 GOTO_OPCODE(ip) @ jump to next instruction 1986 1987/* ------------------------------ */ 1988 .balign 64 1989.L_OP_AGET_WIDE: /* 0x45 */ 1990/* File: armv5te/OP_AGET_WIDE.S */ 1991 /* 1992 * Array get, 64 bits. vAA <- vBB[vCC]. 1993 * 1994 * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD. 1995 */ 1996 /* aget-wide vAA, vBB, vCC */ 1997 FETCH(r0, 1) @ r0<- CCBB 1998 mov r9, rINST, lsr #8 @ r9<- AA 1999 and r2, r0, #255 @ r2<- BB 2000 mov r3, r0, lsr #8 @ r3<- CC 2001 GET_VREG(r0, r2) @ r0<- vBB (array object) 2002 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2003 cmp r0, #0 @ null array object? 2004 beq common_errNullObject @ yes, bail 2005 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2006 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2007 cmp r1, r3 @ compare unsigned index, length 2008 bcc .LOP_AGET_WIDE_finish @ okay, continue below 2009 b common_errArrayIndex @ index >= length, bail 2010 @ May want to swap the order of these two branches depending on how the 2011 @ branch prediction (if any) handles conditional forward branches vs. 2012 @ unconditional forward branches. 2013 2014/* ------------------------------ */ 2015 .balign 64 2016.L_OP_AGET_OBJECT: /* 0x46 */ 2017/* File: armv5te/OP_AGET_OBJECT.S */ 2018/* File: armv5te/OP_AGET.S */ 2019 /* 2020 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2021 * 2022 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2023 * instructions. We use a pair of FETCH_Bs instead. 2024 * 2025 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2026 */ 2027 /* op vAA, vBB, vCC */ 2028 FETCH_B(r2, 1, 0) @ r2<- BB 2029 mov r9, rINST, lsr #8 @ r9<- AA 2030 FETCH_B(r3, 1, 1) @ r3<- CC 2031 GET_VREG(r0, r2) @ r0<- vBB (array object) 2032 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2033 cmp r0, #0 @ null array object? 2034 beq common_errNullObject @ yes, bail 2035 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2036 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2037 cmp r1, r3 @ compare unsigned index, length 2038 bcs common_errArrayIndex @ index >= length, bail 2039 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2040 ldr r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2041 GET_INST_OPCODE(ip) @ extract opcode from rINST 2042 SET_VREG(r2, r9) @ vAA<- r2 2043 GOTO_OPCODE(ip) @ jump to next instruction 2044 2045 2046/* ------------------------------ */ 2047 .balign 64 2048.L_OP_AGET_BOOLEAN: /* 0x47 */ 2049/* File: armv5te/OP_AGET_BOOLEAN.S */ 2050/* File: armv5te/OP_AGET.S */ 2051 /* 2052 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2053 * 2054 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2055 * instructions. We use a pair of FETCH_Bs instead. 2056 * 2057 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2058 */ 2059 /* op vAA, vBB, vCC */ 2060 FETCH_B(r2, 1, 0) @ r2<- BB 2061 mov r9, rINST, lsr #8 @ r9<- AA 2062 FETCH_B(r3, 1, 1) @ r3<- CC 2063 GET_VREG(r0, r2) @ r0<- vBB (array object) 2064 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2065 cmp r0, #0 @ null array object? 2066 beq common_errNullObject @ yes, bail 2067 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2068 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2069 cmp r1, r3 @ compare unsigned index, length 2070 bcs common_errArrayIndex @ index >= length, bail 2071 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2072 ldrb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2073 GET_INST_OPCODE(ip) @ extract opcode from rINST 2074 SET_VREG(r2, r9) @ vAA<- r2 2075 GOTO_OPCODE(ip) @ jump to next instruction 2076 2077 2078/* ------------------------------ */ 2079 .balign 64 2080.L_OP_AGET_BYTE: /* 0x48 */ 2081/* File: armv5te/OP_AGET_BYTE.S */ 2082/* File: armv5te/OP_AGET.S */ 2083 /* 2084 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2085 * 2086 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2087 * instructions. We use a pair of FETCH_Bs instead. 2088 * 2089 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2090 */ 2091 /* op vAA, vBB, vCC */ 2092 FETCH_B(r2, 1, 0) @ r2<- BB 2093 mov r9, rINST, lsr #8 @ r9<- AA 2094 FETCH_B(r3, 1, 1) @ r3<- CC 2095 GET_VREG(r0, r2) @ r0<- vBB (array object) 2096 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2097 cmp r0, #0 @ null array object? 2098 beq common_errNullObject @ yes, bail 2099 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2100 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2101 cmp r1, r3 @ compare unsigned index, length 2102 bcs common_errArrayIndex @ index >= length, bail 2103 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2104 ldrsb r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2105 GET_INST_OPCODE(ip) @ extract opcode from rINST 2106 SET_VREG(r2, r9) @ vAA<- r2 2107 GOTO_OPCODE(ip) @ jump to next instruction 2108 2109 2110/* ------------------------------ */ 2111 .balign 64 2112.L_OP_AGET_CHAR: /* 0x49 */ 2113/* File: armv5te/OP_AGET_CHAR.S */ 2114/* File: armv5te/OP_AGET.S */ 2115 /* 2116 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2117 * 2118 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2119 * instructions. We use a pair of FETCH_Bs instead. 2120 * 2121 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2122 */ 2123 /* op vAA, vBB, vCC */ 2124 FETCH_B(r2, 1, 0) @ r2<- BB 2125 mov r9, rINST, lsr #8 @ r9<- AA 2126 FETCH_B(r3, 1, 1) @ r3<- CC 2127 GET_VREG(r0, r2) @ r0<- vBB (array object) 2128 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2129 cmp r0, #0 @ null array object? 2130 beq common_errNullObject @ yes, bail 2131 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2132 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2133 cmp r1, r3 @ compare unsigned index, length 2134 bcs common_errArrayIndex @ index >= length, bail 2135 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2136 ldrh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2137 GET_INST_OPCODE(ip) @ extract opcode from rINST 2138 SET_VREG(r2, r9) @ vAA<- r2 2139 GOTO_OPCODE(ip) @ jump to next instruction 2140 2141 2142/* ------------------------------ */ 2143 .balign 64 2144.L_OP_AGET_SHORT: /* 0x4a */ 2145/* File: armv5te/OP_AGET_SHORT.S */ 2146/* File: armv5te/OP_AGET.S */ 2147 /* 2148 * Array get, 32 bits or less. vAA <- vBB[vCC]. 2149 * 2150 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2151 * instructions. We use a pair of FETCH_Bs instead. 2152 * 2153 * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short 2154 */ 2155 /* op vAA, vBB, vCC */ 2156 FETCH_B(r2, 1, 0) @ r2<- BB 2157 mov r9, rINST, lsr #8 @ r9<- AA 2158 FETCH_B(r3, 1, 1) @ r3<- CC 2159 GET_VREG(r0, r2) @ r0<- vBB (array object) 2160 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2161 cmp r0, #0 @ null array object? 2162 beq common_errNullObject @ yes, bail 2163 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2164 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2165 cmp r1, r3 @ compare unsigned index, length 2166 bcs common_errArrayIndex @ index >= length, bail 2167 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2168 ldrsh r2, [r0, #offArrayObject_contents] @ r2<- vBB[vCC] 2169 GET_INST_OPCODE(ip) @ extract opcode from rINST 2170 SET_VREG(r2, r9) @ vAA<- r2 2171 GOTO_OPCODE(ip) @ jump to next instruction 2172 2173 2174/* ------------------------------ */ 2175 .balign 64 2176.L_OP_APUT: /* 0x4b */ 2177/* File: armv5te/OP_APUT.S */ 2178 /* 2179 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2180 * 2181 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2182 * instructions. We use a pair of FETCH_Bs instead. 2183 * 2184 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2185 */ 2186 /* op vAA, vBB, vCC */ 2187 FETCH_B(r2, 1, 0) @ r2<- BB 2188 mov r9, rINST, lsr #8 @ r9<- AA 2189 FETCH_B(r3, 1, 1) @ r3<- CC 2190 GET_VREG(r0, r2) @ r0<- vBB (array object) 2191 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2192 cmp r0, #0 @ null array object? 2193 beq common_errNullObject @ yes, bail 2194 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2195 add r0, r0, r1, lsl #2 @ r0<- arrayObj + index*width 2196 cmp r1, r3 @ compare unsigned index, length 2197 bcs common_errArrayIndex @ index >= length, bail 2198 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2199 GET_VREG(r2, r9) @ r2<- vAA 2200 GET_INST_OPCODE(ip) @ extract opcode from rINST 2201 str r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2202 GOTO_OPCODE(ip) @ jump to next instruction 2203 2204/* ------------------------------ */ 2205 .balign 64 2206.L_OP_APUT_WIDE: /* 0x4c */ 2207/* File: armv5te/OP_APUT_WIDE.S */ 2208 /* 2209 * Array put, 64 bits. vBB[vCC] <- vAA. 2210 * 2211 * Arrays of long/double are 64-bit aligned, so it's okay to use STRD. 2212 */ 2213 /* aput-wide vAA, vBB, vCC */ 2214 FETCH(r0, 1) @ r0<- CCBB 2215 mov r9, rINST, lsr #8 @ r9<- AA 2216 and r2, r0, #255 @ r2<- BB 2217 mov r3, r0, lsr #8 @ r3<- CC 2218 GET_VREG(r0, r2) @ r0<- vBB (array object) 2219 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2220 cmp r0, #0 @ null array object? 2221 beq common_errNullObject @ yes, bail 2222 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2223 add r0, r0, r1, lsl #3 @ r0<- arrayObj + index*width 2224 cmp r1, r3 @ compare unsigned index, length 2225 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2226 bcc .LOP_APUT_WIDE_finish @ okay, continue below 2227 b common_errArrayIndex @ index >= length, bail 2228 @ May want to swap the order of these two branches depending on how the 2229 @ branch prediction (if any) handles conditional forward branches vs. 2230 @ unconditional forward branches. 2231 2232/* ------------------------------ */ 2233 .balign 64 2234.L_OP_APUT_OBJECT: /* 0x4d */ 2235/* File: armv5te/OP_APUT_OBJECT.S */ 2236 /* 2237 * Store an object into an array. vBB[vCC] <- vAA. 2238 */ 2239 /* op vAA, vBB, vCC */ 2240 FETCH(r0, 1) @ r0<- CCBB 2241 mov r9, rINST, lsr #8 @ r9<- AA 2242 and r2, r0, #255 @ r2<- BB 2243 mov r3, r0, lsr #8 @ r3<- CC 2244 GET_VREG(rINST, r2) @ rINST<- vBB (array object) 2245 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2246 cmp rINST, #0 @ null array object? 2247 GET_VREG(r9, r9) @ r9<- vAA 2248 beq common_errNullObject @ yes, bail 2249 ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length 2250 add r10, rINST, r1, lsl #2 @ r10<- arrayObj + index*width 2251 cmp r1, r3 @ compare unsigned index, length 2252 bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on 2253 b common_errArrayIndex @ index >= length, bail 2254 2255 2256/* ------------------------------ */ 2257 .balign 64 2258.L_OP_APUT_BOOLEAN: /* 0x4e */ 2259/* File: armv5te/OP_APUT_BOOLEAN.S */ 2260/* File: armv5te/OP_APUT.S */ 2261 /* 2262 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2263 * 2264 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2265 * instructions. We use a pair of FETCH_Bs instead. 2266 * 2267 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2268 */ 2269 /* op vAA, vBB, vCC */ 2270 FETCH_B(r2, 1, 0) @ r2<- BB 2271 mov r9, rINST, lsr #8 @ r9<- AA 2272 FETCH_B(r3, 1, 1) @ r3<- CC 2273 GET_VREG(r0, r2) @ r0<- vBB (array object) 2274 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2275 cmp r0, #0 @ null array object? 2276 beq common_errNullObject @ yes, bail 2277 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2278 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2279 cmp r1, r3 @ compare unsigned index, length 2280 bcs common_errArrayIndex @ index >= length, bail 2281 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2282 GET_VREG(r2, r9) @ r2<- vAA 2283 GET_INST_OPCODE(ip) @ extract opcode from rINST 2284 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2285 GOTO_OPCODE(ip) @ jump to next instruction 2286 2287 2288/* ------------------------------ */ 2289 .balign 64 2290.L_OP_APUT_BYTE: /* 0x4f */ 2291/* File: armv5te/OP_APUT_BYTE.S */ 2292/* File: armv5te/OP_APUT.S */ 2293 /* 2294 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2295 * 2296 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2297 * instructions. We use a pair of FETCH_Bs instead. 2298 * 2299 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2300 */ 2301 /* op vAA, vBB, vCC */ 2302 FETCH_B(r2, 1, 0) @ r2<- BB 2303 mov r9, rINST, lsr #8 @ r9<- AA 2304 FETCH_B(r3, 1, 1) @ r3<- CC 2305 GET_VREG(r0, r2) @ r0<- vBB (array object) 2306 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2307 cmp r0, #0 @ null array object? 2308 beq common_errNullObject @ yes, bail 2309 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2310 add r0, r0, r1, lsl #0 @ r0<- arrayObj + index*width 2311 cmp r1, r3 @ compare unsigned index, length 2312 bcs common_errArrayIndex @ index >= length, bail 2313 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2314 GET_VREG(r2, r9) @ r2<- vAA 2315 GET_INST_OPCODE(ip) @ extract opcode from rINST 2316 strb r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2317 GOTO_OPCODE(ip) @ jump to next instruction 2318 2319 2320/* ------------------------------ */ 2321 .balign 64 2322.L_OP_APUT_CHAR: /* 0x50 */ 2323/* File: armv5te/OP_APUT_CHAR.S */ 2324/* File: armv5te/OP_APUT.S */ 2325 /* 2326 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2327 * 2328 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2329 * instructions. We use a pair of FETCH_Bs instead. 2330 * 2331 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2332 */ 2333 /* op vAA, vBB, vCC */ 2334 FETCH_B(r2, 1, 0) @ r2<- BB 2335 mov r9, rINST, lsr #8 @ r9<- AA 2336 FETCH_B(r3, 1, 1) @ r3<- CC 2337 GET_VREG(r0, r2) @ r0<- vBB (array object) 2338 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2339 cmp r0, #0 @ null array object? 2340 beq common_errNullObject @ yes, bail 2341 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2342 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2343 cmp r1, r3 @ compare unsigned index, length 2344 bcs common_errArrayIndex @ index >= length, bail 2345 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2346 GET_VREG(r2, r9) @ r2<- vAA 2347 GET_INST_OPCODE(ip) @ extract opcode from rINST 2348 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2349 GOTO_OPCODE(ip) @ jump to next instruction 2350 2351 2352/* ------------------------------ */ 2353 .balign 64 2354.L_OP_APUT_SHORT: /* 0x51 */ 2355/* File: armv5te/OP_APUT_SHORT.S */ 2356/* File: armv5te/OP_APUT.S */ 2357 /* 2358 * Array put, 32 bits or less. vBB[vCC] <- vAA. 2359 * 2360 * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17 2361 * instructions. We use a pair of FETCH_Bs instead. 2362 * 2363 * for: aput, aput-boolean, aput-byte, aput-char, aput-short 2364 */ 2365 /* op vAA, vBB, vCC */ 2366 FETCH_B(r2, 1, 0) @ r2<- BB 2367 mov r9, rINST, lsr #8 @ r9<- AA 2368 FETCH_B(r3, 1, 1) @ r3<- CC 2369 GET_VREG(r0, r2) @ r0<- vBB (array object) 2370 GET_VREG(r1, r3) @ r1<- vCC (requested index) 2371 cmp r0, #0 @ null array object? 2372 beq common_errNullObject @ yes, bail 2373 ldr r3, [r0, #offArrayObject_length] @ r3<- arrayObj->length 2374 add r0, r0, r1, lsl #1 @ r0<- arrayObj + index*width 2375 cmp r1, r3 @ compare unsigned index, length 2376 bcs common_errArrayIndex @ index >= length, bail 2377 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2378 GET_VREG(r2, r9) @ r2<- vAA 2379 GET_INST_OPCODE(ip) @ extract opcode from rINST 2380 strh r2, [r0, #offArrayObject_contents] @ vBB[vCC]<- r2 2381 GOTO_OPCODE(ip) @ jump to next instruction 2382 2383 2384/* ------------------------------ */ 2385 .balign 64 2386.L_OP_IGET: /* 0x52 */ 2387/* File: armv6t2/OP_IGET.S */ 2388 /* 2389 * General 32-bit instance field get. 2390 * 2391 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2392 */ 2393 /* op vA, vB, field@CCCC */ 2394 mov r0, rINST, lsr #12 @ r0<- B 2395 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2396 FETCH(r1, 1) @ r1<- field ref CCCC 2397 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2398 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2399 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2400 cmp r0, #0 @ is resolved entry null? 2401 bne .LOP_IGET_finish @ no, already resolved 24028: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2403 EXPORT_PC() @ resolve() could throw 2404 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2405 bl dvmResolveInstField @ r0<- resolved InstField ptr 2406 cmp r0, #0 2407 bne .LOP_IGET_finish 2408 b common_exceptionThrown 2409 2410/* ------------------------------ */ 2411 .balign 64 2412.L_OP_IGET_WIDE: /* 0x53 */ 2413/* File: armv6t2/OP_IGET_WIDE.S */ 2414 /* 2415 * Wide 32-bit instance field get. 2416 */ 2417 /* iget-wide vA, vB, field@CCCC */ 2418 mov r0, rINST, lsr #12 @ r0<- B 2419 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2420 FETCH(r1, 1) @ r1<- field ref CCCC 2421 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2422 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2423 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2424 cmp r0, #0 @ is resolved entry null? 2425 bne .LOP_IGET_WIDE_finish @ no, already resolved 24268: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2427 EXPORT_PC() @ resolve() could throw 2428 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2429 bl dvmResolveInstField @ r0<- resolved InstField ptr 2430 cmp r0, #0 2431 bne .LOP_IGET_WIDE_finish 2432 b common_exceptionThrown 2433 2434/* ------------------------------ */ 2435 .balign 64 2436.L_OP_IGET_OBJECT: /* 0x54 */ 2437/* File: armv5te/OP_IGET_OBJECT.S */ 2438/* File: armv5te/OP_IGET.S */ 2439 /* 2440 * General 32-bit instance field get. 2441 * 2442 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2443 */ 2444 /* op vA, vB, field@CCCC */ 2445 mov r0, rINST, lsr #12 @ r0<- B 2446 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2447 FETCH(r1, 1) @ r1<- field ref CCCC 2448 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2449 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2450 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2451 cmp r0, #0 @ is resolved entry null? 2452 bne .LOP_IGET_OBJECT_finish @ no, already resolved 24538: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2454 EXPORT_PC() @ resolve() could throw 2455 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2456 bl dvmResolveInstField @ r0<- resolved InstField ptr 2457 cmp r0, #0 2458 bne .LOP_IGET_OBJECT_finish 2459 b common_exceptionThrown 2460 2461 2462/* ------------------------------ */ 2463 .balign 64 2464.L_OP_IGET_BOOLEAN: /* 0x55 */ 2465/* File: armv5te/OP_IGET_BOOLEAN.S */ 2466@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" } 2467/* File: armv5te/OP_IGET.S */ 2468 /* 2469 * General 32-bit instance field get. 2470 * 2471 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2472 */ 2473 /* op vA, vB, field@CCCC */ 2474 mov r0, rINST, lsr #12 @ r0<- B 2475 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2476 FETCH(r1, 1) @ r1<- field ref CCCC 2477 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2478 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2479 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2480 cmp r0, #0 @ is resolved entry null? 2481 bne .LOP_IGET_BOOLEAN_finish @ no, already resolved 24828: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2483 EXPORT_PC() @ resolve() could throw 2484 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2485 bl dvmResolveInstField @ r0<- resolved InstField ptr 2486 cmp r0, #0 2487 bne .LOP_IGET_BOOLEAN_finish 2488 b common_exceptionThrown 2489 2490 2491/* ------------------------------ */ 2492 .balign 64 2493.L_OP_IGET_BYTE: /* 0x56 */ 2494/* File: armv5te/OP_IGET_BYTE.S */ 2495@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" } 2496/* File: armv5te/OP_IGET.S */ 2497 /* 2498 * General 32-bit instance field get. 2499 * 2500 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2501 */ 2502 /* op vA, vB, field@CCCC */ 2503 mov r0, rINST, lsr #12 @ r0<- B 2504 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2505 FETCH(r1, 1) @ r1<- field ref CCCC 2506 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2507 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2508 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2509 cmp r0, #0 @ is resolved entry null? 2510 bne .LOP_IGET_BYTE_finish @ no, already resolved 25118: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2512 EXPORT_PC() @ resolve() could throw 2513 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2514 bl dvmResolveInstField @ r0<- resolved InstField ptr 2515 cmp r0, #0 2516 bne .LOP_IGET_BYTE_finish 2517 b common_exceptionThrown 2518 2519 2520/* ------------------------------ */ 2521 .balign 64 2522.L_OP_IGET_CHAR: /* 0x57 */ 2523/* File: armv5te/OP_IGET_CHAR.S */ 2524@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" } 2525/* File: armv5te/OP_IGET.S */ 2526 /* 2527 * General 32-bit instance field get. 2528 * 2529 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2530 */ 2531 /* op vA, vB, field@CCCC */ 2532 mov r0, rINST, lsr #12 @ r0<- B 2533 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2534 FETCH(r1, 1) @ r1<- field ref CCCC 2535 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2536 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2537 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2538 cmp r0, #0 @ is resolved entry null? 2539 bne .LOP_IGET_CHAR_finish @ no, already resolved 25408: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2541 EXPORT_PC() @ resolve() could throw 2542 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2543 bl dvmResolveInstField @ r0<- resolved InstField ptr 2544 cmp r0, #0 2545 bne .LOP_IGET_CHAR_finish 2546 b common_exceptionThrown 2547 2548 2549/* ------------------------------ */ 2550 .balign 64 2551.L_OP_IGET_SHORT: /* 0x58 */ 2552/* File: armv5te/OP_IGET_SHORT.S */ 2553@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" } 2554/* File: armv5te/OP_IGET.S */ 2555 /* 2556 * General 32-bit instance field get. 2557 * 2558 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 2559 */ 2560 /* op vA, vB, field@CCCC */ 2561 mov r0, rINST, lsr #12 @ r0<- B 2562 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2563 FETCH(r1, 1) @ r1<- field ref CCCC 2564 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2565 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2566 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2567 cmp r0, #0 @ is resolved entry null? 2568 bne .LOP_IGET_SHORT_finish @ no, already resolved 25698: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2570 EXPORT_PC() @ resolve() could throw 2571 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2572 bl dvmResolveInstField @ r0<- resolved InstField ptr 2573 cmp r0, #0 2574 bne .LOP_IGET_SHORT_finish 2575 b common_exceptionThrown 2576 2577 2578/* ------------------------------ */ 2579 .balign 64 2580.L_OP_IPUT: /* 0x59 */ 2581/* File: armv6t2/OP_IPUT.S */ 2582 /* 2583 * General 32-bit instance field put. 2584 * 2585 * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short 2586 */ 2587 /* op vA, vB, field@CCCC */ 2588 mov r0, rINST, lsr #12 @ r0<- B 2589 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2590 FETCH(r1, 1) @ r1<- field ref CCCC 2591 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2592 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2593 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2594 cmp r0, #0 @ is resolved entry null? 2595 bne .LOP_IPUT_finish @ no, already resolved 25968: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2597 EXPORT_PC() @ resolve() could throw 2598 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2599 bl dvmResolveInstField @ r0<- resolved InstField ptr 2600 cmp r0, #0 @ success? 2601 bne .LOP_IPUT_finish @ yes, finish up 2602 b common_exceptionThrown 2603 2604/* ------------------------------ */ 2605 .balign 64 2606.L_OP_IPUT_WIDE: /* 0x5a */ 2607/* File: armv6t2/OP_IPUT_WIDE.S */ 2608 /* iput-wide vA, vB, field@CCCC */ 2609 mov r0, rINST, lsr #12 @ r0<- B 2610 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2611 FETCH(r1, 1) @ r1<- field ref CCCC 2612 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 2613 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2614 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2615 cmp r0, #0 @ is resolved entry null? 2616 bne .LOP_IPUT_WIDE_finish @ no, already resolved 26178: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2618 EXPORT_PC() @ resolve() could throw 2619 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2620 bl dvmResolveInstField @ r0<- resolved InstField ptr 2621 cmp r0, #0 @ success? 2622 bne .LOP_IPUT_WIDE_finish @ yes, finish up 2623 b common_exceptionThrown 2624 2625/* ------------------------------ */ 2626 .balign 64 2627.L_OP_IPUT_OBJECT: /* 0x5b */ 2628/* File: armv5te/OP_IPUT_OBJECT.S */ 2629 /* 2630 * 32-bit instance field put. 2631 * 2632 * for: iput-object, iput-object-volatile 2633 */ 2634 /* op vA, vB, field@CCCC */ 2635 mov r0, rINST, lsr #12 @ r0<- B 2636 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2637 FETCH(r1, 1) @ r1<- field ref CCCC 2638 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2639 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2640 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2641 cmp r0, #0 @ is resolved entry null? 2642 bne .LOP_IPUT_OBJECT_finish @ no, already resolved 26438: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2644 EXPORT_PC() @ resolve() could throw 2645 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2646 bl dvmResolveInstField @ r0<- resolved InstField ptr 2647 cmp r0, #0 @ success? 2648 bne .LOP_IPUT_OBJECT_finish @ yes, finish up 2649 b common_exceptionThrown 2650 2651/* ------------------------------ */ 2652 .balign 64 2653.L_OP_IPUT_BOOLEAN: /* 0x5c */ 2654/* File: armv5te/OP_IPUT_BOOLEAN.S */ 2655@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" } 2656/* File: armv5te/OP_IPUT.S */ 2657 /* 2658 * General 32-bit instance field put. 2659 * 2660 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2661 */ 2662 /* op vA, vB, field@CCCC */ 2663 mov r0, rINST, lsr #12 @ r0<- B 2664 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2665 FETCH(r1, 1) @ r1<- field ref CCCC 2666 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2667 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2668 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2669 cmp r0, #0 @ is resolved entry null? 2670 bne .LOP_IPUT_BOOLEAN_finish @ no, already resolved 26718: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2672 EXPORT_PC() @ resolve() could throw 2673 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2674 bl dvmResolveInstField @ r0<- resolved InstField ptr 2675 cmp r0, #0 @ success? 2676 bne .LOP_IPUT_BOOLEAN_finish @ yes, finish up 2677 b common_exceptionThrown 2678 2679 2680/* ------------------------------ */ 2681 .balign 64 2682.L_OP_IPUT_BYTE: /* 0x5d */ 2683/* File: armv5te/OP_IPUT_BYTE.S */ 2684@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" } 2685/* File: armv5te/OP_IPUT.S */ 2686 /* 2687 * General 32-bit instance field put. 2688 * 2689 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2690 */ 2691 /* op vA, vB, field@CCCC */ 2692 mov r0, rINST, lsr #12 @ r0<- B 2693 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2694 FETCH(r1, 1) @ r1<- field ref CCCC 2695 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2696 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2697 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2698 cmp r0, #0 @ is resolved entry null? 2699 bne .LOP_IPUT_BYTE_finish @ no, already resolved 27008: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2701 EXPORT_PC() @ resolve() could throw 2702 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2703 bl dvmResolveInstField @ r0<- resolved InstField ptr 2704 cmp r0, #0 @ success? 2705 bne .LOP_IPUT_BYTE_finish @ yes, finish up 2706 b common_exceptionThrown 2707 2708 2709/* ------------------------------ */ 2710 .balign 64 2711.L_OP_IPUT_CHAR: /* 0x5e */ 2712/* File: armv5te/OP_IPUT_CHAR.S */ 2713@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" } 2714/* File: armv5te/OP_IPUT.S */ 2715 /* 2716 * General 32-bit instance field put. 2717 * 2718 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2719 */ 2720 /* op vA, vB, field@CCCC */ 2721 mov r0, rINST, lsr #12 @ r0<- B 2722 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2723 FETCH(r1, 1) @ r1<- field ref CCCC 2724 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2725 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2726 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2727 cmp r0, #0 @ is resolved entry null? 2728 bne .LOP_IPUT_CHAR_finish @ no, already resolved 27298: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2730 EXPORT_PC() @ resolve() could throw 2731 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2732 bl dvmResolveInstField @ r0<- resolved InstField ptr 2733 cmp r0, #0 @ success? 2734 bne .LOP_IPUT_CHAR_finish @ yes, finish up 2735 b common_exceptionThrown 2736 2737 2738/* ------------------------------ */ 2739 .balign 64 2740.L_OP_IPUT_SHORT: /* 0x5f */ 2741/* File: armv5te/OP_IPUT_SHORT.S */ 2742@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" } 2743/* File: armv5te/OP_IPUT.S */ 2744 /* 2745 * General 32-bit instance field put. 2746 * 2747 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 2748 */ 2749 /* op vA, vB, field@CCCC */ 2750 mov r0, rINST, lsr #12 @ r0<- B 2751 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 2752 FETCH(r1, 1) @ r1<- field ref CCCC 2753 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 2754 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 2755 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 2756 cmp r0, #0 @ is resolved entry null? 2757 bne .LOP_IPUT_SHORT_finish @ no, already resolved 27588: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 2759 EXPORT_PC() @ resolve() could throw 2760 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 2761 bl dvmResolveInstField @ r0<- resolved InstField ptr 2762 cmp r0, #0 @ success? 2763 bne .LOP_IPUT_SHORT_finish @ yes, finish up 2764 b common_exceptionThrown 2765 2766 2767/* ------------------------------ */ 2768 .balign 64 2769.L_OP_SGET: /* 0x60 */ 2770/* File: armv5te/OP_SGET.S */ 2771 /* 2772 * General 32-bit SGET handler. 2773 * 2774 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2775 */ 2776 /* op vAA, field@BBBB */ 2777 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2778 FETCH(r1, 1) @ r1<- field ref BBBB 2779 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2780 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2781 cmp r0, #0 @ is resolved entry null? 2782 beq .LOP_SGET_resolve @ yes, do resolve 2783.LOP_SGET_finish: @ field ptr in r0 2784 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2785 @ no-op @ acquiring load 2786 mov r2, rINST, lsr #8 @ r2<- AA 2787 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2788 SET_VREG(r1, r2) @ fp[AA]<- r1 2789 GET_INST_OPCODE(ip) @ extract opcode from rINST 2790 GOTO_OPCODE(ip) @ jump to next instruction 2791 2792/* ------------------------------ */ 2793 .balign 64 2794.L_OP_SGET_WIDE: /* 0x61 */ 2795/* File: armv5te/OP_SGET_WIDE.S */ 2796 /* 2797 * 64-bit SGET handler. 2798 */ 2799 /* sget-wide vAA, field@BBBB */ 2800 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2801 FETCH(r1, 1) @ r1<- field ref BBBB 2802 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2803 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2804 cmp r0, #0 @ is resolved entry null? 2805 beq .LOP_SGET_WIDE_resolve @ yes, do resolve 2806.LOP_SGET_WIDE_finish: 2807 mov r9, rINST, lsr #8 @ r9<- AA 2808 .if 0 2809 add r0, r0, #offStaticField_value @ r0<- pointer to data 2810 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 2811 .else 2812 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 2813 .endif 2814 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2815 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2816 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 2817 GET_INST_OPCODE(ip) @ extract opcode from rINST 2818 GOTO_OPCODE(ip) @ jump to next instruction 2819 2820/* ------------------------------ */ 2821 .balign 64 2822.L_OP_SGET_OBJECT: /* 0x62 */ 2823/* File: armv5te/OP_SGET_OBJECT.S */ 2824/* File: armv5te/OP_SGET.S */ 2825 /* 2826 * General 32-bit SGET handler. 2827 * 2828 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2829 */ 2830 /* op vAA, field@BBBB */ 2831 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2832 FETCH(r1, 1) @ r1<- field ref BBBB 2833 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2834 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2835 cmp r0, #0 @ is resolved entry null? 2836 beq .LOP_SGET_OBJECT_resolve @ yes, do resolve 2837.LOP_SGET_OBJECT_finish: @ field ptr in r0 2838 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2839 @ no-op @ acquiring load 2840 mov r2, rINST, lsr #8 @ r2<- AA 2841 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2842 SET_VREG(r1, r2) @ fp[AA]<- r1 2843 GET_INST_OPCODE(ip) @ extract opcode from rINST 2844 GOTO_OPCODE(ip) @ jump to next instruction 2845 2846 2847/* ------------------------------ */ 2848 .balign 64 2849.L_OP_SGET_BOOLEAN: /* 0x63 */ 2850/* File: armv5te/OP_SGET_BOOLEAN.S */ 2851/* File: armv5te/OP_SGET.S */ 2852 /* 2853 * General 32-bit SGET handler. 2854 * 2855 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2856 */ 2857 /* op vAA, field@BBBB */ 2858 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2859 FETCH(r1, 1) @ r1<- field ref BBBB 2860 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2861 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2862 cmp r0, #0 @ is resolved entry null? 2863 beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve 2864.LOP_SGET_BOOLEAN_finish: @ field ptr in r0 2865 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2866 @ no-op @ acquiring load 2867 mov r2, rINST, lsr #8 @ r2<- AA 2868 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2869 SET_VREG(r1, r2) @ fp[AA]<- r1 2870 GET_INST_OPCODE(ip) @ extract opcode from rINST 2871 GOTO_OPCODE(ip) @ jump to next instruction 2872 2873 2874/* ------------------------------ */ 2875 .balign 64 2876.L_OP_SGET_BYTE: /* 0x64 */ 2877/* File: armv5te/OP_SGET_BYTE.S */ 2878/* File: armv5te/OP_SGET.S */ 2879 /* 2880 * General 32-bit SGET handler. 2881 * 2882 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2883 */ 2884 /* op vAA, field@BBBB */ 2885 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2886 FETCH(r1, 1) @ r1<- field ref BBBB 2887 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2888 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2889 cmp r0, #0 @ is resolved entry null? 2890 beq .LOP_SGET_BYTE_resolve @ yes, do resolve 2891.LOP_SGET_BYTE_finish: @ field ptr in r0 2892 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2893 @ no-op @ acquiring load 2894 mov r2, rINST, lsr #8 @ r2<- AA 2895 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2896 SET_VREG(r1, r2) @ fp[AA]<- r1 2897 GET_INST_OPCODE(ip) @ extract opcode from rINST 2898 GOTO_OPCODE(ip) @ jump to next instruction 2899 2900 2901/* ------------------------------ */ 2902 .balign 64 2903.L_OP_SGET_CHAR: /* 0x65 */ 2904/* File: armv5te/OP_SGET_CHAR.S */ 2905/* File: armv5te/OP_SGET.S */ 2906 /* 2907 * General 32-bit SGET handler. 2908 * 2909 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2910 */ 2911 /* op vAA, field@BBBB */ 2912 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2913 FETCH(r1, 1) @ r1<- field ref BBBB 2914 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2915 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2916 cmp r0, #0 @ is resolved entry null? 2917 beq .LOP_SGET_CHAR_resolve @ yes, do resolve 2918.LOP_SGET_CHAR_finish: @ field ptr in r0 2919 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2920 @ no-op @ acquiring load 2921 mov r2, rINST, lsr #8 @ r2<- AA 2922 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2923 SET_VREG(r1, r2) @ fp[AA]<- r1 2924 GET_INST_OPCODE(ip) @ extract opcode from rINST 2925 GOTO_OPCODE(ip) @ jump to next instruction 2926 2927 2928/* ------------------------------ */ 2929 .balign 64 2930.L_OP_SGET_SHORT: /* 0x66 */ 2931/* File: armv5te/OP_SGET_SHORT.S */ 2932/* File: armv5te/OP_SGET.S */ 2933 /* 2934 * General 32-bit SGET handler. 2935 * 2936 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 2937 */ 2938 /* op vAA, field@BBBB */ 2939 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2940 FETCH(r1, 1) @ r1<- field ref BBBB 2941 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2942 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2943 cmp r0, #0 @ is resolved entry null? 2944 beq .LOP_SGET_SHORT_resolve @ yes, do resolve 2945.LOP_SGET_SHORT_finish: @ field ptr in r0 2946 ldr r1, [r0, #offStaticField_value] @ r1<- field value 2947 @ no-op @ acquiring load 2948 mov r2, rINST, lsr #8 @ r2<- AA 2949 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2950 SET_VREG(r1, r2) @ fp[AA]<- r1 2951 GET_INST_OPCODE(ip) @ extract opcode from rINST 2952 GOTO_OPCODE(ip) @ jump to next instruction 2953 2954 2955/* ------------------------------ */ 2956 .balign 64 2957.L_OP_SPUT: /* 0x67 */ 2958/* File: armv5te/OP_SPUT.S */ 2959 /* 2960 * General 32-bit SPUT handler. 2961 * 2962 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 2963 */ 2964 /* op vAA, field@BBBB */ 2965 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 2966 FETCH(r1, 1) @ r1<- field ref BBBB 2967 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 2968 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 2969 cmp r0, #0 @ is resolved entry null? 2970 beq .LOP_SPUT_resolve @ yes, do resolve 2971.LOP_SPUT_finish: @ field ptr in r0 2972 mov r2, rINST, lsr #8 @ r2<- AA 2973 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2974 GET_VREG(r1, r2) @ r1<- fp[AA] 2975 GET_INST_OPCODE(ip) @ extract opcode from rINST 2976 @ no-op @ releasing store 2977 str r1, [r0, #offStaticField_value] @ field<- vAA 2978 GOTO_OPCODE(ip) @ jump to next instruction 2979 2980/* ------------------------------ */ 2981 .balign 64 2982.L_OP_SPUT_WIDE: /* 0x68 */ 2983/* File: armv5te/OP_SPUT_WIDE.S */ 2984 /* 2985 * 64-bit SPUT handler. 2986 */ 2987 /* sput-wide vAA, field@BBBB */ 2988 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- DvmDex 2989 FETCH(r1, 1) @ r1<- field ref BBBB 2990 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 2991 mov r9, rINST, lsr #8 @ r9<- AA 2992 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 2993 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 2994 cmp r2, #0 @ is resolved entry null? 2995 beq .LOP_SPUT_WIDE_resolve @ yes, do resolve 2996.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9 2997 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 2998 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 2999 GET_INST_OPCODE(r10) @ extract opcode from rINST 3000 .if 0 3001 add r2, r2, #offStaticField_value @ r2<- pointer to data 3002 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 3003 .else 3004 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 3005 .endif 3006 GOTO_OPCODE(r10) @ jump to next instruction 3007 3008/* ------------------------------ */ 3009 .balign 64 3010.L_OP_SPUT_OBJECT: /* 0x69 */ 3011/* File: armv5te/OP_SPUT_OBJECT.S */ 3012 /* 3013 * 32-bit SPUT handler for objects 3014 * 3015 * for: sput-object, sput-object-volatile 3016 */ 3017 /* op vAA, field@BBBB */ 3018 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3019 FETCH(r1, 1) @ r1<- field ref BBBB 3020 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3021 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3022 cmp r0, #0 @ is resolved entry null? 3023 bne .LOP_SPUT_OBJECT_finish @ no, continue 3024 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 3025 EXPORT_PC() @ resolve() could throw, so export now 3026 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 3027 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 3028 cmp r0, #0 @ success? 3029 bne .LOP_SPUT_OBJECT_finish @ yes, finish 3030 b common_exceptionThrown @ no, handle exception 3031 3032 3033/* ------------------------------ */ 3034 .balign 64 3035.L_OP_SPUT_BOOLEAN: /* 0x6a */ 3036/* File: armv5te/OP_SPUT_BOOLEAN.S */ 3037/* File: armv5te/OP_SPUT.S */ 3038 /* 3039 * General 32-bit SPUT handler. 3040 * 3041 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3042 */ 3043 /* op vAA, field@BBBB */ 3044 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3045 FETCH(r1, 1) @ r1<- field ref BBBB 3046 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3047 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3048 cmp r0, #0 @ is resolved entry null? 3049 beq .LOP_SPUT_BOOLEAN_resolve @ yes, do resolve 3050.LOP_SPUT_BOOLEAN_finish: @ field ptr in r0 3051 mov r2, rINST, lsr #8 @ r2<- AA 3052 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3053 GET_VREG(r1, r2) @ r1<- fp[AA] 3054 GET_INST_OPCODE(ip) @ extract opcode from rINST 3055 @ no-op @ releasing store 3056 str r1, [r0, #offStaticField_value] @ field<- vAA 3057 GOTO_OPCODE(ip) @ jump to next instruction 3058 3059 3060/* ------------------------------ */ 3061 .balign 64 3062.L_OP_SPUT_BYTE: /* 0x6b */ 3063/* File: armv5te/OP_SPUT_BYTE.S */ 3064/* File: armv5te/OP_SPUT.S */ 3065 /* 3066 * General 32-bit SPUT handler. 3067 * 3068 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3069 */ 3070 /* op vAA, field@BBBB */ 3071 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3072 FETCH(r1, 1) @ r1<- field ref BBBB 3073 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3074 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3075 cmp r0, #0 @ is resolved entry null? 3076 beq .LOP_SPUT_BYTE_resolve @ yes, do resolve 3077.LOP_SPUT_BYTE_finish: @ field ptr in r0 3078 mov r2, rINST, lsr #8 @ r2<- AA 3079 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3080 GET_VREG(r1, r2) @ r1<- fp[AA] 3081 GET_INST_OPCODE(ip) @ extract opcode from rINST 3082 @ no-op @ releasing store 3083 str r1, [r0, #offStaticField_value] @ field<- vAA 3084 GOTO_OPCODE(ip) @ jump to next instruction 3085 3086 3087/* ------------------------------ */ 3088 .balign 64 3089.L_OP_SPUT_CHAR: /* 0x6c */ 3090/* File: armv5te/OP_SPUT_CHAR.S */ 3091/* File: armv5te/OP_SPUT.S */ 3092 /* 3093 * General 32-bit SPUT handler. 3094 * 3095 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3096 */ 3097 /* op vAA, field@BBBB */ 3098 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3099 FETCH(r1, 1) @ r1<- field ref BBBB 3100 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3101 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3102 cmp r0, #0 @ is resolved entry null? 3103 beq .LOP_SPUT_CHAR_resolve @ yes, do resolve 3104.LOP_SPUT_CHAR_finish: @ field ptr in r0 3105 mov r2, rINST, lsr #8 @ r2<- AA 3106 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3107 GET_VREG(r1, r2) @ r1<- fp[AA] 3108 GET_INST_OPCODE(ip) @ extract opcode from rINST 3109 @ no-op @ releasing store 3110 str r1, [r0, #offStaticField_value] @ field<- vAA 3111 GOTO_OPCODE(ip) @ jump to next instruction 3112 3113 3114/* ------------------------------ */ 3115 .balign 64 3116.L_OP_SPUT_SHORT: /* 0x6d */ 3117/* File: armv5te/OP_SPUT_SHORT.S */ 3118/* File: armv5te/OP_SPUT.S */ 3119 /* 3120 * General 32-bit SPUT handler. 3121 * 3122 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 3123 */ 3124 /* op vAA, field@BBBB */ 3125 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 3126 FETCH(r1, 1) @ r1<- field ref BBBB 3127 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 3128 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 3129 cmp r0, #0 @ is resolved entry null? 3130 beq .LOP_SPUT_SHORT_resolve @ yes, do resolve 3131.LOP_SPUT_SHORT_finish: @ field ptr in r0 3132 mov r2, rINST, lsr #8 @ r2<- AA 3133 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 3134 GET_VREG(r1, r2) @ r1<- fp[AA] 3135 GET_INST_OPCODE(ip) @ extract opcode from rINST 3136 @ no-op @ releasing store 3137 str r1, [r0, #offStaticField_value] @ field<- vAA 3138 GOTO_OPCODE(ip) @ jump to next instruction 3139 3140 3141/* ------------------------------ */ 3142 .balign 64 3143.L_OP_INVOKE_VIRTUAL: /* 0x6e */ 3144/* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3145 /* 3146 * Handle a virtual method call. 3147 * 3148 * for: invoke-virtual, invoke-virtual/range 3149 */ 3150 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3151 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3152 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3153 FETCH(r1, 1) @ r1<- BBBB 3154 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3155 FETCH(r10, 2) @ r10<- GFED or CCCC 3156 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3157 .if (!0) 3158 and r10, r10, #15 @ r10<- D (or stays CCCC) 3159 .endif 3160 cmp r0, #0 @ already resolved? 3161 EXPORT_PC() @ must export for invoke 3162 bne .LOP_INVOKE_VIRTUAL_continue @ yes, continue on 3163 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3164 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3165 mov r2, #METHOD_VIRTUAL @ resolver method type 3166 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3167 cmp r0, #0 @ got null? 3168 bne .LOP_INVOKE_VIRTUAL_continue @ no, continue 3169 b common_exceptionThrown @ yes, handle exception 3170 3171/* ------------------------------ */ 3172 .balign 64 3173.L_OP_INVOKE_SUPER: /* 0x6f */ 3174/* File: armv5te/OP_INVOKE_SUPER.S */ 3175 /* 3176 * Handle a "super" method call. 3177 * 3178 * for: invoke-super, invoke-super/range 3179 */ 3180 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3181 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3182 FETCH(r10, 2) @ r10<- GFED or CCCC 3183 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3184 .if (!0) 3185 and r10, r10, #15 @ r10<- D (or stays CCCC) 3186 .endif 3187 FETCH(r1, 1) @ r1<- BBBB 3188 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3189 GET_VREG(r2, r10) @ r2<- "this" ptr 3190 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3191 cmp r2, #0 @ null "this"? 3192 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 3193 beq common_errNullObject @ null "this", throw exception 3194 cmp r0, #0 @ already resolved? 3195 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 3196 EXPORT_PC() @ must export for invoke 3197 bne .LOP_INVOKE_SUPER_continue @ resolved, continue on 3198 b .LOP_INVOKE_SUPER_resolve @ do resolve now 3199 3200/* ------------------------------ */ 3201 .balign 64 3202.L_OP_INVOKE_DIRECT: /* 0x70 */ 3203/* File: armv5te/OP_INVOKE_DIRECT.S */ 3204 /* 3205 * Handle a direct method call. 3206 * 3207 * (We could defer the "is 'this' pointer null" test to the common 3208 * method invocation code, and use a flag to indicate that static 3209 * calls don't count. If we do this as part of copying the arguments 3210 * out we could avoiding loading the first arg twice.) 3211 * 3212 * for: invoke-direct, invoke-direct/range 3213 */ 3214 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3215 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3216 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3217 FETCH(r1, 1) @ r1<- BBBB 3218 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3219 FETCH(r10, 2) @ r10<- GFED or CCCC 3220 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3221 .if (!0) 3222 and r10, r10, #15 @ r10<- D (or stays CCCC) 3223 .endif 3224 cmp r0, #0 @ already resolved? 3225 EXPORT_PC() @ must export for invoke 3226 GET_VREG(r2, r10) @ r2<- "this" ptr 3227 beq .LOP_INVOKE_DIRECT_resolve @ not resolved, do it now 3228.LOP_INVOKE_DIRECT_finish: 3229 cmp r2, #0 @ null "this" ref? 3230 bne common_invokeMethodNoRange @ no, continue on 3231 b common_errNullObject @ yes, throw exception 3232 3233/* ------------------------------ */ 3234 .balign 64 3235.L_OP_INVOKE_STATIC: /* 0x71 */ 3236/* File: armv5te/OP_INVOKE_STATIC.S */ 3237 /* 3238 * Handle a static method call. 3239 * 3240 * for: invoke-static, invoke-static/range 3241 */ 3242 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3243 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3244 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3245 FETCH(r1, 1) @ r1<- BBBB 3246 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3247 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3248 cmp r0, #0 @ already resolved? 3249 EXPORT_PC() @ must export for invoke 3250 bne common_invokeMethodNoRange @ yes, continue on 32510: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3252 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3253 mov r2, #METHOD_STATIC @ resolver method type 3254 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3255 cmp r0, #0 @ got null? 3256 bne common_invokeMethodNoRange @ no, continue 3257 b common_exceptionThrown @ yes, handle exception 3258 3259/* ------------------------------ */ 3260 .balign 64 3261.L_OP_INVOKE_INTERFACE: /* 0x72 */ 3262/* File: armv5te/OP_INVOKE_INTERFACE.S */ 3263 /* 3264 * Handle an interface method call. 3265 * 3266 * for: invoke-interface, invoke-interface/range 3267 */ 3268 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3269 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3270 FETCH(r2, 2) @ r2<- FEDC or CCCC 3271 FETCH(r1, 1) @ r1<- BBBB 3272 .if (!0) 3273 and r2, r2, #15 @ r2<- C (or stays CCCC) 3274 .endif 3275 EXPORT_PC() @ must export for invoke 3276 GET_VREG(r0, r2) @ r0<- first arg ("this") 3277 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- methodClassDex 3278 cmp r0, #0 @ null obj? 3279 ldr r2, [rGLUE, #offGlue_method] @ r2<- method 3280 beq common_errNullObject @ yes, fail 3281 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 3282 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3283 cmp r0, #0 @ failed? 3284 beq common_exceptionThrown @ yes, handle exception 3285 b common_invokeMethodNoRange @ jump to common handler 3286 3287/* ------------------------------ */ 3288 .balign 64 3289.L_OP_UNUSED_73: /* 0x73 */ 3290/* File: armv5te/OP_UNUSED_73.S */ 3291/* File: armv5te/unused.S */ 3292 bl common_abort 3293 3294 3295/* ------------------------------ */ 3296 .balign 64 3297.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */ 3298/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */ 3299/* File: armv5te/OP_INVOKE_VIRTUAL.S */ 3300 /* 3301 * Handle a virtual method call. 3302 * 3303 * for: invoke-virtual, invoke-virtual/range 3304 */ 3305 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3306 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3307 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3308 FETCH(r1, 1) @ r1<- BBBB 3309 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3310 FETCH(r10, 2) @ r10<- GFED or CCCC 3311 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3312 .if (!1) 3313 and r10, r10, #15 @ r10<- D (or stays CCCC) 3314 .endif 3315 cmp r0, #0 @ already resolved? 3316 EXPORT_PC() @ must export for invoke 3317 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ yes, continue on 3318 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3319 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3320 mov r2, #METHOD_VIRTUAL @ resolver method type 3321 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3322 cmp r0, #0 @ got null? 3323 bne .LOP_INVOKE_VIRTUAL_RANGE_continue @ no, continue 3324 b common_exceptionThrown @ yes, handle exception 3325 3326 3327/* ------------------------------ */ 3328 .balign 64 3329.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */ 3330/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */ 3331/* File: armv5te/OP_INVOKE_SUPER.S */ 3332 /* 3333 * Handle a "super" method call. 3334 * 3335 * for: invoke-super, invoke-super/range 3336 */ 3337 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3338 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3339 FETCH(r10, 2) @ r10<- GFED or CCCC 3340 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3341 .if (!1) 3342 and r10, r10, #15 @ r10<- D (or stays CCCC) 3343 .endif 3344 FETCH(r1, 1) @ r1<- BBBB 3345 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3346 GET_VREG(r2, r10) @ r2<- "this" ptr 3347 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 3348 cmp r2, #0 @ null "this"? 3349 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 3350 beq common_errNullObject @ null "this", throw exception 3351 cmp r0, #0 @ already resolved? 3352 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 3353 EXPORT_PC() @ must export for invoke 3354 bne .LOP_INVOKE_SUPER_RANGE_continue @ resolved, continue on 3355 b .LOP_INVOKE_SUPER_RANGE_resolve @ do resolve now 3356 3357 3358/* ------------------------------ */ 3359 .balign 64 3360.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */ 3361/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */ 3362/* File: armv5te/OP_INVOKE_DIRECT.S */ 3363 /* 3364 * Handle a direct method call. 3365 * 3366 * (We could defer the "is 'this' pointer null" test to the common 3367 * method invocation code, and use a flag to indicate that static 3368 * calls don't count. If we do this as part of copying the arguments 3369 * out we could avoiding loading the first arg twice.) 3370 * 3371 * for: invoke-direct, invoke-direct/range 3372 */ 3373 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3374 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3375 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3376 FETCH(r1, 1) @ r1<- BBBB 3377 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3378 FETCH(r10, 2) @ r10<- GFED or CCCC 3379 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3380 .if (!1) 3381 and r10, r10, #15 @ r10<- D (or stays CCCC) 3382 .endif 3383 cmp r0, #0 @ already resolved? 3384 EXPORT_PC() @ must export for invoke 3385 GET_VREG(r2, r10) @ r2<- "this" ptr 3386 beq .LOP_INVOKE_DIRECT_RANGE_resolve @ not resolved, do it now 3387.LOP_INVOKE_DIRECT_RANGE_finish: 3388 cmp r2, #0 @ null "this" ref? 3389 bne common_invokeMethodRange @ no, continue on 3390 b common_errNullObject @ yes, throw exception 3391 3392 3393/* ------------------------------ */ 3394 .balign 64 3395.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */ 3396/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */ 3397/* File: armv5te/OP_INVOKE_STATIC.S */ 3398 /* 3399 * Handle a static method call. 3400 * 3401 * for: invoke-static, invoke-static/range 3402 */ 3403 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3404 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3405 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 3406 FETCH(r1, 1) @ r1<- BBBB 3407 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 3408 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 3409 cmp r0, #0 @ already resolved? 3410 EXPORT_PC() @ must export for invoke 3411 bne common_invokeMethodRange @ yes, continue on 34120: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 3413 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 3414 mov r2, #METHOD_STATIC @ resolver method type 3415 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 3416 cmp r0, #0 @ got null? 3417 bne common_invokeMethodRange @ no, continue 3418 b common_exceptionThrown @ yes, handle exception 3419 3420 3421/* ------------------------------ */ 3422 .balign 64 3423.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */ 3424/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */ 3425/* File: armv5te/OP_INVOKE_INTERFACE.S */ 3426 /* 3427 * Handle an interface method call. 3428 * 3429 * for: invoke-interface, invoke-interface/range 3430 */ 3431 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 3432 /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 3433 FETCH(r2, 2) @ r2<- FEDC or CCCC 3434 FETCH(r1, 1) @ r1<- BBBB 3435 .if (!1) 3436 and r2, r2, #15 @ r2<- C (or stays CCCC) 3437 .endif 3438 EXPORT_PC() @ must export for invoke 3439 GET_VREG(r0, r2) @ r0<- first arg ("this") 3440 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- methodClassDex 3441 cmp r0, #0 @ null obj? 3442 ldr r2, [rGLUE, #offGlue_method] @ r2<- method 3443 beq common_errNullObject @ yes, fail 3444 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 3445 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 3446 cmp r0, #0 @ failed? 3447 beq common_exceptionThrown @ yes, handle exception 3448 b common_invokeMethodRange @ jump to common handler 3449 3450 3451/* ------------------------------ */ 3452 .balign 64 3453.L_OP_UNUSED_79: /* 0x79 */ 3454/* File: armv5te/OP_UNUSED_79.S */ 3455/* File: armv5te/unused.S */ 3456 bl common_abort 3457 3458 3459/* ------------------------------ */ 3460 .balign 64 3461.L_OP_UNUSED_7A: /* 0x7a */ 3462/* File: armv5te/OP_UNUSED_7A.S */ 3463/* File: armv5te/unused.S */ 3464 bl common_abort 3465 3466 3467/* ------------------------------ */ 3468 .balign 64 3469.L_OP_NEG_INT: /* 0x7b */ 3470/* File: armv6t2/OP_NEG_INT.S */ 3471/* File: armv6t2/unop.S */ 3472 /* 3473 * Generic 32-bit unary operation. Provide an "instr" line that 3474 * specifies an instruction that performs "result = op r0". 3475 * This could be an ARM instruction or a function call. 3476 * 3477 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3478 * int-to-byte, int-to-char, int-to-short 3479 */ 3480 /* unop vA, vB */ 3481 mov r3, rINST, lsr #12 @ r3<- B 3482 ubfx r9, rINST, #8, #4 @ r9<- A 3483 GET_VREG(r0, r3) @ r0<- vB 3484 @ optional op; may set condition codes 3485 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3486 rsb r0, r0, #0 @ r0<- op, r0-r3 changed 3487 GET_INST_OPCODE(ip) @ extract opcode from rINST 3488 SET_VREG(r0, r9) @ vAA<- r0 3489 GOTO_OPCODE(ip) @ jump to next instruction 3490 /* 8-9 instructions */ 3491 3492 3493/* ------------------------------ */ 3494 .balign 64 3495.L_OP_NOT_INT: /* 0x7c */ 3496/* File: armv6t2/OP_NOT_INT.S */ 3497/* File: armv6t2/unop.S */ 3498 /* 3499 * Generic 32-bit unary operation. Provide an "instr" line that 3500 * specifies an instruction that performs "result = op r0". 3501 * This could be an ARM instruction or a function call. 3502 * 3503 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3504 * int-to-byte, int-to-char, int-to-short 3505 */ 3506 /* unop vA, vB */ 3507 mov r3, rINST, lsr #12 @ r3<- B 3508 ubfx r9, rINST, #8, #4 @ r9<- A 3509 GET_VREG(r0, r3) @ r0<- vB 3510 @ optional op; may set condition codes 3511 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3512 mvn r0, r0 @ r0<- op, r0-r3 changed 3513 GET_INST_OPCODE(ip) @ extract opcode from rINST 3514 SET_VREG(r0, r9) @ vAA<- r0 3515 GOTO_OPCODE(ip) @ jump to next instruction 3516 /* 8-9 instructions */ 3517 3518 3519/* ------------------------------ */ 3520 .balign 64 3521.L_OP_NEG_LONG: /* 0x7d */ 3522/* File: armv6t2/OP_NEG_LONG.S */ 3523/* File: armv6t2/unopWide.S */ 3524 /* 3525 * Generic 64-bit unary operation. Provide an "instr" line that 3526 * specifies an instruction that performs "result = op r0/r1". 3527 * This could be an ARM instruction or a function call. 3528 * 3529 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3530 */ 3531 /* unop vA, vB */ 3532 mov r3, rINST, lsr #12 @ r3<- B 3533 ubfx r9, rINST, #8, #4 @ r9<- A 3534 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3535 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3536 ldmia r3, {r0-r1} @ r0/r1<- vAA 3537 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3538 rsbs r0, r0, #0 @ optional op; may set condition codes 3539 rsc r1, r1, #0 @ r0/r1<- op, r2-r3 changed 3540 GET_INST_OPCODE(ip) @ extract opcode from rINST 3541 stmia r9, {r0-r1} @ vAA<- r0/r1 3542 GOTO_OPCODE(ip) @ jump to next instruction 3543 /* 10-11 instructions */ 3544 3545 3546/* ------------------------------ */ 3547 .balign 64 3548.L_OP_NOT_LONG: /* 0x7e */ 3549/* File: armv6t2/OP_NOT_LONG.S */ 3550/* File: armv6t2/unopWide.S */ 3551 /* 3552 * Generic 64-bit unary operation. Provide an "instr" line that 3553 * specifies an instruction that performs "result = op r0/r1". 3554 * This could be an ARM instruction or a function call. 3555 * 3556 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3557 */ 3558 /* unop vA, vB */ 3559 mov r3, rINST, lsr #12 @ r3<- B 3560 ubfx r9, rINST, #8, #4 @ r9<- A 3561 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3562 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3563 ldmia r3, {r0-r1} @ r0/r1<- vAA 3564 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3565 mvn r0, r0 @ optional op; may set condition codes 3566 mvn r1, r1 @ r0/r1<- op, r2-r3 changed 3567 GET_INST_OPCODE(ip) @ extract opcode from rINST 3568 stmia r9, {r0-r1} @ vAA<- r0/r1 3569 GOTO_OPCODE(ip) @ jump to next instruction 3570 /* 10-11 instructions */ 3571 3572 3573/* ------------------------------ */ 3574 .balign 64 3575.L_OP_NEG_FLOAT: /* 0x7f */ 3576/* File: armv6t2/OP_NEG_FLOAT.S */ 3577/* File: armv6t2/unop.S */ 3578 /* 3579 * Generic 32-bit unary operation. Provide an "instr" line that 3580 * specifies an instruction that performs "result = op r0". 3581 * This could be an ARM instruction or a function call. 3582 * 3583 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3584 * int-to-byte, int-to-char, int-to-short 3585 */ 3586 /* unop vA, vB */ 3587 mov r3, rINST, lsr #12 @ r3<- B 3588 ubfx r9, rINST, #8, #4 @ r9<- A 3589 GET_VREG(r0, r3) @ r0<- vB 3590 @ optional op; may set condition codes 3591 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3592 add r0, r0, #0x80000000 @ r0<- op, r0-r3 changed 3593 GET_INST_OPCODE(ip) @ extract opcode from rINST 3594 SET_VREG(r0, r9) @ vAA<- r0 3595 GOTO_OPCODE(ip) @ jump to next instruction 3596 /* 8-9 instructions */ 3597 3598 3599/* ------------------------------ */ 3600 .balign 64 3601.L_OP_NEG_DOUBLE: /* 0x80 */ 3602/* File: armv6t2/OP_NEG_DOUBLE.S */ 3603/* File: armv6t2/unopWide.S */ 3604 /* 3605 * Generic 64-bit unary operation. Provide an "instr" line that 3606 * specifies an instruction that performs "result = op r0/r1". 3607 * This could be an ARM instruction or a function call. 3608 * 3609 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3610 */ 3611 /* unop vA, vB */ 3612 mov r3, rINST, lsr #12 @ r3<- B 3613 ubfx r9, rINST, #8, #4 @ r9<- A 3614 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3615 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3616 ldmia r3, {r0-r1} @ r0/r1<- vAA 3617 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3618 @ optional op; may set condition codes 3619 add r1, r1, #0x80000000 @ r0/r1<- op, r2-r3 changed 3620 GET_INST_OPCODE(ip) @ extract opcode from rINST 3621 stmia r9, {r0-r1} @ vAA<- r0/r1 3622 GOTO_OPCODE(ip) @ jump to next instruction 3623 /* 10-11 instructions */ 3624 3625 3626/* ------------------------------ */ 3627 .balign 64 3628.L_OP_INT_TO_LONG: /* 0x81 */ 3629/* File: armv6t2/OP_INT_TO_LONG.S */ 3630/* File: armv6t2/unopWider.S */ 3631 /* 3632 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3633 * that specifies an instruction that performs "result = op r0", where 3634 * "result" is a 64-bit quantity in r0/r1. 3635 * 3636 * For: int-to-long, int-to-double, float-to-long, float-to-double 3637 */ 3638 /* unop vA, vB */ 3639 mov r3, rINST, lsr #12 @ r3<- B 3640 ubfx r9, rINST, #8, #4 @ r9<- A 3641 GET_VREG(r0, r3) @ r0<- vB 3642 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3643 @ optional op; may set condition codes 3644 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3645 mov r1, r0, asr #31 @ r0<- op, r0-r3 changed 3646 GET_INST_OPCODE(ip) @ extract opcode from rINST 3647 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3648 GOTO_OPCODE(ip) @ jump to next instruction 3649 /* 9-10 instructions */ 3650 3651 3652/* ------------------------------ */ 3653 .balign 64 3654.L_OP_INT_TO_FLOAT: /* 0x82 */ 3655/* File: arm-vfp/OP_INT_TO_FLOAT.S */ 3656/* File: arm-vfp/funop.S */ 3657 /* 3658 * Generic 32-bit unary floating-point operation. Provide an "instr" 3659 * line that specifies an instruction that performs "s1 = op s0". 3660 * 3661 * for: int-to-float, float-to-int 3662 */ 3663 /* unop vA, vB */ 3664 mov r3, rINST, lsr #12 @ r3<- B 3665 mov r9, rINST, lsr #8 @ r9<- A+ 3666 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3667 flds s0, [r3] @ s0<- vB 3668 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3669 and r9, r9, #15 @ r9<- A 3670 fsitos s1, s0 @ s1<- op 3671 GET_INST_OPCODE(ip) @ extract opcode from rINST 3672 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3673 fsts s1, [r9] @ vA<- s1 3674 GOTO_OPCODE(ip) @ jump to next instruction 3675 3676 3677/* ------------------------------ */ 3678 .balign 64 3679.L_OP_INT_TO_DOUBLE: /* 0x83 */ 3680/* File: arm-vfp/OP_INT_TO_DOUBLE.S */ 3681/* File: arm-vfp/funopWider.S */ 3682 /* 3683 * Generic 32bit-to-64bit floating point unary operation. Provide an 3684 * "instr" line that specifies an instruction that performs "d0 = op s0". 3685 * 3686 * For: int-to-double, float-to-double 3687 */ 3688 /* unop vA, vB */ 3689 mov r3, rINST, lsr #12 @ r3<- B 3690 mov r9, rINST, lsr #8 @ r9<- A+ 3691 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3692 flds s0, [r3] @ s0<- vB 3693 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3694 and r9, r9, #15 @ r9<- A 3695 fsitod d0, s0 @ d0<- op 3696 GET_INST_OPCODE(ip) @ extract opcode from rINST 3697 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3698 fstd d0, [r9] @ vA<- d0 3699 GOTO_OPCODE(ip) @ jump to next instruction 3700 3701 3702/* ------------------------------ */ 3703 .balign 64 3704.L_OP_LONG_TO_INT: /* 0x84 */ 3705/* File: armv5te/OP_LONG_TO_INT.S */ 3706/* we ignore the high word, making this equivalent to a 32-bit reg move */ 3707/* File: armv5te/OP_MOVE.S */ 3708 /* for move, move-object, long-to-int */ 3709 /* op vA, vB */ 3710 mov r1, rINST, lsr #12 @ r1<- B from 15:12 3711 mov r0, rINST, lsr #8 @ r0<- A from 11:8 3712 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3713 GET_VREG(r2, r1) @ r2<- fp[B] 3714 and r0, r0, #15 3715 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 3716 SET_VREG(r2, r0) @ fp[A]<- r2 3717 GOTO_OPCODE(ip) @ execute next instruction 3718 3719 3720/* ------------------------------ */ 3721 .balign 64 3722.L_OP_LONG_TO_FLOAT: /* 0x85 */ 3723/* File: armv6t2/OP_LONG_TO_FLOAT.S */ 3724/* File: armv6t2/unopNarrower.S */ 3725 /* 3726 * Generic 64bit-to-32bit unary operation. Provide an "instr" line 3727 * that specifies an instruction that performs "result = op r0/r1", where 3728 * "result" is a 32-bit quantity in r0. 3729 * 3730 * For: long-to-float, double-to-int, double-to-float 3731 * 3732 * (This would work for long-to-int, but that instruction is actually 3733 * an exact match for OP_MOVE.) 3734 */ 3735 /* unop vA, vB */ 3736 mov r3, rINST, lsr #12 @ r3<- B 3737 ubfx r9, rINST, #8, #4 @ r9<- A 3738 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3739 ldmia r3, {r0-r1} @ r0/r1<- vB/vB+1 3740 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3741 @ optional op; may set condition codes 3742 bl __aeabi_l2f @ r0<- op, r0-r3 changed 3743 GET_INST_OPCODE(ip) @ extract opcode from rINST 3744 SET_VREG(r0, r9) @ vA<- r0 3745 GOTO_OPCODE(ip) @ jump to next instruction 3746 /* 9-10 instructions */ 3747 3748 3749/* ------------------------------ */ 3750 .balign 64 3751.L_OP_LONG_TO_DOUBLE: /* 0x86 */ 3752/* File: armv6t2/OP_LONG_TO_DOUBLE.S */ 3753/* File: armv6t2/unopWide.S */ 3754 /* 3755 * Generic 64-bit unary operation. Provide an "instr" line that 3756 * specifies an instruction that performs "result = op r0/r1". 3757 * This could be an ARM instruction or a function call. 3758 * 3759 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3760 */ 3761 /* unop vA, vB */ 3762 mov r3, rINST, lsr #12 @ r3<- B 3763 ubfx r9, rINST, #8, #4 @ r9<- A 3764 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3765 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3766 ldmia r3, {r0-r1} @ r0/r1<- vAA 3767 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3768 @ optional op; may set condition codes 3769 bl __aeabi_l2d @ r0/r1<- op, r2-r3 changed 3770 GET_INST_OPCODE(ip) @ extract opcode from rINST 3771 stmia r9, {r0-r1} @ vAA<- r0/r1 3772 GOTO_OPCODE(ip) @ jump to next instruction 3773 /* 10-11 instructions */ 3774 3775 3776/* ------------------------------ */ 3777 .balign 64 3778.L_OP_FLOAT_TO_INT: /* 0x87 */ 3779/* File: arm-vfp/OP_FLOAT_TO_INT.S */ 3780/* File: arm-vfp/funop.S */ 3781 /* 3782 * Generic 32-bit unary floating-point operation. Provide an "instr" 3783 * line that specifies an instruction that performs "s1 = op s0". 3784 * 3785 * for: int-to-float, float-to-int 3786 */ 3787 /* unop vA, vB */ 3788 mov r3, rINST, lsr #12 @ r3<- B 3789 mov r9, rINST, lsr #8 @ r9<- A+ 3790 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3791 flds s0, [r3] @ s0<- vB 3792 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3793 and r9, r9, #15 @ r9<- A 3794 ftosizs s1, s0 @ s1<- op 3795 GET_INST_OPCODE(ip) @ extract opcode from rINST 3796 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3797 fsts s1, [r9] @ vA<- s1 3798 GOTO_OPCODE(ip) @ jump to next instruction 3799 3800 3801/* ------------------------------ */ 3802 .balign 64 3803.L_OP_FLOAT_TO_LONG: /* 0x88 */ 3804/* File: armv6t2/OP_FLOAT_TO_LONG.S */ 3805@include "armv6t2/unopWider.S" {"instr":"bl __aeabi_f2lz"} 3806/* File: armv6t2/unopWider.S */ 3807 /* 3808 * Generic 32bit-to-64bit unary operation. Provide an "instr" line 3809 * that specifies an instruction that performs "result = op r0", where 3810 * "result" is a 64-bit quantity in r0/r1. 3811 * 3812 * For: int-to-long, int-to-double, float-to-long, float-to-double 3813 */ 3814 /* unop vA, vB */ 3815 mov r3, rINST, lsr #12 @ r3<- B 3816 ubfx r9, rINST, #8, #4 @ r9<- A 3817 GET_VREG(r0, r3) @ r0<- vB 3818 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3819 @ optional op; may set condition codes 3820 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3821 bl f2l_doconv @ r0<- op, r0-r3 changed 3822 GET_INST_OPCODE(ip) @ extract opcode from rINST 3823 stmia r9, {r0-r1} @ vA/vA+1<- r0/r1 3824 GOTO_OPCODE(ip) @ jump to next instruction 3825 /* 9-10 instructions */ 3826 3827 3828 3829/* ------------------------------ */ 3830 .balign 64 3831.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */ 3832/* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */ 3833/* File: arm-vfp/funopWider.S */ 3834 /* 3835 * Generic 32bit-to-64bit floating point unary operation. Provide an 3836 * "instr" line that specifies an instruction that performs "d0 = op s0". 3837 * 3838 * For: int-to-double, float-to-double 3839 */ 3840 /* unop vA, vB */ 3841 mov r3, rINST, lsr #12 @ r3<- B 3842 mov r9, rINST, lsr #8 @ r9<- A+ 3843 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3844 flds s0, [r3] @ s0<- vB 3845 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3846 and r9, r9, #15 @ r9<- A 3847 fcvtds d0, s0 @ d0<- op 3848 GET_INST_OPCODE(ip) @ extract opcode from rINST 3849 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3850 fstd d0, [r9] @ vA<- d0 3851 GOTO_OPCODE(ip) @ jump to next instruction 3852 3853 3854/* ------------------------------ */ 3855 .balign 64 3856.L_OP_DOUBLE_TO_INT: /* 0x8a */ 3857/* File: arm-vfp/OP_DOUBLE_TO_INT.S */ 3858/* File: arm-vfp/funopNarrower.S */ 3859 /* 3860 * Generic 64bit-to-32bit unary floating point operation. Provide an 3861 * "instr" line that specifies an instruction that performs "s0 = op d0". 3862 * 3863 * For: double-to-int, double-to-float 3864 */ 3865 /* unop vA, vB */ 3866 mov r3, rINST, lsr #12 @ r3<- B 3867 mov r9, rINST, lsr #8 @ r9<- A+ 3868 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3869 fldd d0, [r3] @ d0<- vB 3870 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3871 and r9, r9, #15 @ r9<- A 3872 ftosizd s0, d0 @ s0<- op 3873 GET_INST_OPCODE(ip) @ extract opcode from rINST 3874 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3875 fsts s0, [r9] @ vA<- s0 3876 GOTO_OPCODE(ip) @ jump to next instruction 3877 3878 3879/* ------------------------------ */ 3880 .balign 64 3881.L_OP_DOUBLE_TO_LONG: /* 0x8b */ 3882/* File: armv6t2/OP_DOUBLE_TO_LONG.S */ 3883@include "armv6t2/unopWide.S" {"instr":"bl __aeabi_d2lz"} 3884/* File: armv6t2/unopWide.S */ 3885 /* 3886 * Generic 64-bit unary operation. Provide an "instr" line that 3887 * specifies an instruction that performs "result = op r0/r1". 3888 * This could be an ARM instruction or a function call. 3889 * 3890 * For: neg-long, not-long, neg-double, long-to-double, double-to-long 3891 */ 3892 /* unop vA, vB */ 3893 mov r3, rINST, lsr #12 @ r3<- B 3894 ubfx r9, rINST, #8, #4 @ r9<- A 3895 add r3, rFP, r3, lsl #2 @ r3<- &fp[B] 3896 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 3897 ldmia r3, {r0-r1} @ r0/r1<- vAA 3898 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3899 @ optional op; may set condition codes 3900 bl d2l_doconv @ r0/r1<- op, r2-r3 changed 3901 GET_INST_OPCODE(ip) @ extract opcode from rINST 3902 stmia r9, {r0-r1} @ vAA<- r0/r1 3903 GOTO_OPCODE(ip) @ jump to next instruction 3904 /* 10-11 instructions */ 3905 3906 3907 3908/* ------------------------------ */ 3909 .balign 64 3910.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */ 3911/* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */ 3912/* File: arm-vfp/funopNarrower.S */ 3913 /* 3914 * Generic 64bit-to-32bit unary floating point operation. Provide an 3915 * "instr" line that specifies an instruction that performs "s0 = op d0". 3916 * 3917 * For: double-to-int, double-to-float 3918 */ 3919 /* unop vA, vB */ 3920 mov r3, rINST, lsr #12 @ r3<- B 3921 mov r9, rINST, lsr #8 @ r9<- A+ 3922 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 3923 fldd d0, [r3] @ d0<- vB 3924 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3925 and r9, r9, #15 @ r9<- A 3926 fcvtsd s0, d0 @ s0<- op 3927 GET_INST_OPCODE(ip) @ extract opcode from rINST 3928 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 3929 fsts s0, [r9] @ vA<- s0 3930 GOTO_OPCODE(ip) @ jump to next instruction 3931 3932 3933/* ------------------------------ */ 3934 .balign 64 3935.L_OP_INT_TO_BYTE: /* 0x8d */ 3936/* File: armv6t2/OP_INT_TO_BYTE.S */ 3937/* File: armv6t2/unop.S */ 3938 /* 3939 * Generic 32-bit unary operation. Provide an "instr" line that 3940 * specifies an instruction that performs "result = op r0". 3941 * This could be an ARM instruction or a function call. 3942 * 3943 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3944 * int-to-byte, int-to-char, int-to-short 3945 */ 3946 /* unop vA, vB */ 3947 mov r3, rINST, lsr #12 @ r3<- B 3948 ubfx r9, rINST, #8, #4 @ r9<- A 3949 GET_VREG(r0, r3) @ r0<- vB 3950 @ optional op; may set condition codes 3951 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3952 sxtb r0, r0 @ r0<- op, r0-r3 changed 3953 GET_INST_OPCODE(ip) @ extract opcode from rINST 3954 SET_VREG(r0, r9) @ vAA<- r0 3955 GOTO_OPCODE(ip) @ jump to next instruction 3956 /* 8-9 instructions */ 3957 3958 3959/* ------------------------------ */ 3960 .balign 64 3961.L_OP_INT_TO_CHAR: /* 0x8e */ 3962/* File: armv6t2/OP_INT_TO_CHAR.S */ 3963/* File: armv6t2/unop.S */ 3964 /* 3965 * Generic 32-bit unary operation. Provide an "instr" line that 3966 * specifies an instruction that performs "result = op r0". 3967 * This could be an ARM instruction or a function call. 3968 * 3969 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3970 * int-to-byte, int-to-char, int-to-short 3971 */ 3972 /* unop vA, vB */ 3973 mov r3, rINST, lsr #12 @ r3<- B 3974 ubfx r9, rINST, #8, #4 @ r9<- A 3975 GET_VREG(r0, r3) @ r0<- vB 3976 @ optional op; may set condition codes 3977 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 3978 uxth r0, r0 @ r0<- op, r0-r3 changed 3979 GET_INST_OPCODE(ip) @ extract opcode from rINST 3980 SET_VREG(r0, r9) @ vAA<- r0 3981 GOTO_OPCODE(ip) @ jump to next instruction 3982 /* 8-9 instructions */ 3983 3984 3985/* ------------------------------ */ 3986 .balign 64 3987.L_OP_INT_TO_SHORT: /* 0x8f */ 3988/* File: armv6t2/OP_INT_TO_SHORT.S */ 3989/* File: armv6t2/unop.S */ 3990 /* 3991 * Generic 32-bit unary operation. Provide an "instr" line that 3992 * specifies an instruction that performs "result = op r0". 3993 * This could be an ARM instruction or a function call. 3994 * 3995 * for: neg-int, not-int, neg-float, int-to-float, float-to-int, 3996 * int-to-byte, int-to-char, int-to-short 3997 */ 3998 /* unop vA, vB */ 3999 mov r3, rINST, lsr #12 @ r3<- B 4000 ubfx r9, rINST, #8, #4 @ r9<- A 4001 GET_VREG(r0, r3) @ r0<- vB 4002 @ optional op; may set condition codes 4003 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 4004 sxth r0, r0 @ r0<- op, r0-r3 changed 4005 GET_INST_OPCODE(ip) @ extract opcode from rINST 4006 SET_VREG(r0, r9) @ vAA<- r0 4007 GOTO_OPCODE(ip) @ jump to next instruction 4008 /* 8-9 instructions */ 4009 4010 4011/* ------------------------------ */ 4012 .balign 64 4013.L_OP_ADD_INT: /* 0x90 */ 4014/* File: armv5te/OP_ADD_INT.S */ 4015/* File: armv5te/binop.S */ 4016 /* 4017 * Generic 32-bit binary operation. Provide an "instr" line that 4018 * specifies an instruction that performs "result = r0 op r1". 4019 * This could be an ARM instruction or a function call. (If the result 4020 * comes back in a register other than r0, you can override "result".) 4021 * 4022 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4023 * vCC (r1). Useful for integer division and modulus. Note that we 4024 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4025 * handles it correctly. 4026 * 4027 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4028 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4029 * mul-float, div-float, rem-float 4030 */ 4031 /* binop vAA, vBB, vCC */ 4032 FETCH(r0, 1) @ r0<- CCBB 4033 mov r9, rINST, lsr #8 @ r9<- AA 4034 mov r3, r0, lsr #8 @ r3<- CC 4035 and r2, r0, #255 @ r2<- BB 4036 GET_VREG(r1, r3) @ r1<- vCC 4037 GET_VREG(r0, r2) @ r0<- vBB 4038 .if 0 4039 cmp r1, #0 @ is second operand zero? 4040 beq common_errDivideByZero 4041 .endif 4042 4043 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4044 @ optional op; may set condition codes 4045 add r0, r0, r1 @ r0<- op, r0-r3 changed 4046 GET_INST_OPCODE(ip) @ extract opcode from rINST 4047 SET_VREG(r0, r9) @ vAA<- r0 4048 GOTO_OPCODE(ip) @ jump to next instruction 4049 /* 11-14 instructions */ 4050 4051 4052/* ------------------------------ */ 4053 .balign 64 4054.L_OP_SUB_INT: /* 0x91 */ 4055/* File: armv5te/OP_SUB_INT.S */ 4056/* File: armv5te/binop.S */ 4057 /* 4058 * Generic 32-bit binary operation. Provide an "instr" line that 4059 * specifies an instruction that performs "result = r0 op r1". 4060 * This could be an ARM instruction or a function call. (If the result 4061 * comes back in a register other than r0, you can override "result".) 4062 * 4063 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4064 * vCC (r1). Useful for integer division and modulus. Note that we 4065 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4066 * handles it correctly. 4067 * 4068 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4069 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4070 * mul-float, div-float, rem-float 4071 */ 4072 /* binop vAA, vBB, vCC */ 4073 FETCH(r0, 1) @ r0<- CCBB 4074 mov r9, rINST, lsr #8 @ r9<- AA 4075 mov r3, r0, lsr #8 @ r3<- CC 4076 and r2, r0, #255 @ r2<- BB 4077 GET_VREG(r1, r3) @ r1<- vCC 4078 GET_VREG(r0, r2) @ r0<- vBB 4079 .if 0 4080 cmp r1, #0 @ is second operand zero? 4081 beq common_errDivideByZero 4082 .endif 4083 4084 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4085 @ optional op; may set condition codes 4086 sub r0, r0, r1 @ r0<- op, r0-r3 changed 4087 GET_INST_OPCODE(ip) @ extract opcode from rINST 4088 SET_VREG(r0, r9) @ vAA<- r0 4089 GOTO_OPCODE(ip) @ jump to next instruction 4090 /* 11-14 instructions */ 4091 4092 4093/* ------------------------------ */ 4094 .balign 64 4095.L_OP_MUL_INT: /* 0x92 */ 4096/* File: armv5te/OP_MUL_INT.S */ 4097/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 4098/* File: armv5te/binop.S */ 4099 /* 4100 * Generic 32-bit binary operation. Provide an "instr" line that 4101 * specifies an instruction that performs "result = r0 op r1". 4102 * This could be an ARM instruction or a function call. (If the result 4103 * comes back in a register other than r0, you can override "result".) 4104 * 4105 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4106 * vCC (r1). Useful for integer division and modulus. Note that we 4107 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4108 * handles it correctly. 4109 * 4110 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4111 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4112 * mul-float, div-float, rem-float 4113 */ 4114 /* binop vAA, vBB, vCC */ 4115 FETCH(r0, 1) @ r0<- CCBB 4116 mov r9, rINST, lsr #8 @ r9<- AA 4117 mov r3, r0, lsr #8 @ r3<- CC 4118 and r2, r0, #255 @ r2<- BB 4119 GET_VREG(r1, r3) @ r1<- vCC 4120 GET_VREG(r0, r2) @ r0<- vBB 4121 .if 0 4122 cmp r1, #0 @ is second operand zero? 4123 beq common_errDivideByZero 4124 .endif 4125 4126 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4127 @ optional op; may set condition codes 4128 mul r0, r1, r0 @ r0<- op, r0-r3 changed 4129 GET_INST_OPCODE(ip) @ extract opcode from rINST 4130 SET_VREG(r0, r9) @ vAA<- r0 4131 GOTO_OPCODE(ip) @ jump to next instruction 4132 /* 11-14 instructions */ 4133 4134 4135/* ------------------------------ */ 4136 .balign 64 4137.L_OP_DIV_INT: /* 0x93 */ 4138/* File: armv5te/OP_DIV_INT.S */ 4139/* File: armv5te/binop.S */ 4140 /* 4141 * Generic 32-bit binary operation. Provide an "instr" line that 4142 * specifies an instruction that performs "result = r0 op r1". 4143 * This could be an ARM instruction or a function call. (If the result 4144 * comes back in a register other than r0, you can override "result".) 4145 * 4146 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4147 * vCC (r1). Useful for integer division and modulus. Note that we 4148 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4149 * handles it correctly. 4150 * 4151 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4152 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4153 * mul-float, div-float, rem-float 4154 */ 4155 /* binop vAA, vBB, vCC */ 4156 FETCH(r0, 1) @ r0<- CCBB 4157 mov r9, rINST, lsr #8 @ r9<- AA 4158 mov r3, r0, lsr #8 @ r3<- CC 4159 and r2, r0, #255 @ r2<- BB 4160 GET_VREG(r1, r3) @ r1<- vCC 4161 GET_VREG(r0, r2) @ r0<- vBB 4162 .if 1 4163 cmp r1, #0 @ is second operand zero? 4164 beq common_errDivideByZero 4165 .endif 4166 4167 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4168 @ optional op; may set condition codes 4169 bl __aeabi_idiv @ r0<- op, r0-r3 changed 4170 GET_INST_OPCODE(ip) @ extract opcode from rINST 4171 SET_VREG(r0, r9) @ vAA<- r0 4172 GOTO_OPCODE(ip) @ jump to next instruction 4173 /* 11-14 instructions */ 4174 4175 4176/* ------------------------------ */ 4177 .balign 64 4178.L_OP_REM_INT: /* 0x94 */ 4179/* File: armv5te/OP_REM_INT.S */ 4180/* idivmod returns quotient in r0 and remainder in r1 */ 4181/* File: armv5te/binop.S */ 4182 /* 4183 * Generic 32-bit binary operation. Provide an "instr" line that 4184 * specifies an instruction that performs "result = r0 op r1". 4185 * This could be an ARM instruction or a function call. (If the result 4186 * comes back in a register other than r0, you can override "result".) 4187 * 4188 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4189 * vCC (r1). Useful for integer division and modulus. Note that we 4190 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4191 * handles it correctly. 4192 * 4193 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4194 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4195 * mul-float, div-float, rem-float 4196 */ 4197 /* binop vAA, vBB, vCC */ 4198 FETCH(r0, 1) @ r0<- CCBB 4199 mov r9, rINST, lsr #8 @ r9<- AA 4200 mov r3, r0, lsr #8 @ r3<- CC 4201 and r2, r0, #255 @ r2<- BB 4202 GET_VREG(r1, r3) @ r1<- vCC 4203 GET_VREG(r0, r2) @ r0<- vBB 4204 .if 1 4205 cmp r1, #0 @ is second operand zero? 4206 beq common_errDivideByZero 4207 .endif 4208 4209 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4210 @ optional op; may set condition codes 4211 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 4212 GET_INST_OPCODE(ip) @ extract opcode from rINST 4213 SET_VREG(r1, r9) @ vAA<- r1 4214 GOTO_OPCODE(ip) @ jump to next instruction 4215 /* 11-14 instructions */ 4216 4217 4218/* ------------------------------ */ 4219 .balign 64 4220.L_OP_AND_INT: /* 0x95 */ 4221/* File: armv5te/OP_AND_INT.S */ 4222/* File: armv5te/binop.S */ 4223 /* 4224 * Generic 32-bit binary operation. Provide an "instr" line that 4225 * specifies an instruction that performs "result = r0 op r1". 4226 * This could be an ARM instruction or a function call. (If the result 4227 * comes back in a register other than r0, you can override "result".) 4228 * 4229 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4230 * vCC (r1). Useful for integer division and modulus. Note that we 4231 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4232 * handles it correctly. 4233 * 4234 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4235 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4236 * mul-float, div-float, rem-float 4237 */ 4238 /* binop vAA, vBB, vCC */ 4239 FETCH(r0, 1) @ r0<- CCBB 4240 mov r9, rINST, lsr #8 @ r9<- AA 4241 mov r3, r0, lsr #8 @ r3<- CC 4242 and r2, r0, #255 @ r2<- BB 4243 GET_VREG(r1, r3) @ r1<- vCC 4244 GET_VREG(r0, r2) @ r0<- vBB 4245 .if 0 4246 cmp r1, #0 @ is second operand zero? 4247 beq common_errDivideByZero 4248 .endif 4249 4250 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4251 @ optional op; may set condition codes 4252 and r0, r0, r1 @ r0<- op, r0-r3 changed 4253 GET_INST_OPCODE(ip) @ extract opcode from rINST 4254 SET_VREG(r0, r9) @ vAA<- r0 4255 GOTO_OPCODE(ip) @ jump to next instruction 4256 /* 11-14 instructions */ 4257 4258 4259/* ------------------------------ */ 4260 .balign 64 4261.L_OP_OR_INT: /* 0x96 */ 4262/* File: armv5te/OP_OR_INT.S */ 4263/* File: armv5te/binop.S */ 4264 /* 4265 * Generic 32-bit binary operation. Provide an "instr" line that 4266 * specifies an instruction that performs "result = r0 op r1". 4267 * This could be an ARM instruction or a function call. (If the result 4268 * comes back in a register other than r0, you can override "result".) 4269 * 4270 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4271 * vCC (r1). Useful for integer division and modulus. Note that we 4272 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4273 * handles it correctly. 4274 * 4275 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4276 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4277 * mul-float, div-float, rem-float 4278 */ 4279 /* binop vAA, vBB, vCC */ 4280 FETCH(r0, 1) @ r0<- CCBB 4281 mov r9, rINST, lsr #8 @ r9<- AA 4282 mov r3, r0, lsr #8 @ r3<- CC 4283 and r2, r0, #255 @ r2<- BB 4284 GET_VREG(r1, r3) @ r1<- vCC 4285 GET_VREG(r0, r2) @ r0<- vBB 4286 .if 0 4287 cmp r1, #0 @ is second operand zero? 4288 beq common_errDivideByZero 4289 .endif 4290 4291 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4292 @ optional op; may set condition codes 4293 orr r0, r0, r1 @ r0<- op, r0-r3 changed 4294 GET_INST_OPCODE(ip) @ extract opcode from rINST 4295 SET_VREG(r0, r9) @ vAA<- r0 4296 GOTO_OPCODE(ip) @ jump to next instruction 4297 /* 11-14 instructions */ 4298 4299 4300/* ------------------------------ */ 4301 .balign 64 4302.L_OP_XOR_INT: /* 0x97 */ 4303/* File: armv5te/OP_XOR_INT.S */ 4304/* File: armv5te/binop.S */ 4305 /* 4306 * Generic 32-bit binary operation. Provide an "instr" line that 4307 * specifies an instruction that performs "result = r0 op r1". 4308 * This could be an ARM instruction or a function call. (If the result 4309 * comes back in a register other than r0, you can override "result".) 4310 * 4311 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4312 * vCC (r1). Useful for integer division and modulus. Note that we 4313 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4314 * handles it correctly. 4315 * 4316 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4317 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4318 * mul-float, div-float, rem-float 4319 */ 4320 /* binop vAA, vBB, vCC */ 4321 FETCH(r0, 1) @ r0<- CCBB 4322 mov r9, rINST, lsr #8 @ r9<- AA 4323 mov r3, r0, lsr #8 @ r3<- CC 4324 and r2, r0, #255 @ r2<- BB 4325 GET_VREG(r1, r3) @ r1<- vCC 4326 GET_VREG(r0, r2) @ r0<- vBB 4327 .if 0 4328 cmp r1, #0 @ is second operand zero? 4329 beq common_errDivideByZero 4330 .endif 4331 4332 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4333 @ optional op; may set condition codes 4334 eor r0, r0, r1 @ r0<- op, r0-r3 changed 4335 GET_INST_OPCODE(ip) @ extract opcode from rINST 4336 SET_VREG(r0, r9) @ vAA<- r0 4337 GOTO_OPCODE(ip) @ jump to next instruction 4338 /* 11-14 instructions */ 4339 4340 4341/* ------------------------------ */ 4342 .balign 64 4343.L_OP_SHL_INT: /* 0x98 */ 4344/* File: armv5te/OP_SHL_INT.S */ 4345/* File: armv5te/binop.S */ 4346 /* 4347 * Generic 32-bit binary operation. Provide an "instr" line that 4348 * specifies an instruction that performs "result = r0 op r1". 4349 * This could be an ARM instruction or a function call. (If the result 4350 * comes back in a register other than r0, you can override "result".) 4351 * 4352 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4353 * vCC (r1). Useful for integer division and modulus. Note that we 4354 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4355 * handles it correctly. 4356 * 4357 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4358 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4359 * mul-float, div-float, rem-float 4360 */ 4361 /* binop vAA, vBB, vCC */ 4362 FETCH(r0, 1) @ r0<- CCBB 4363 mov r9, rINST, lsr #8 @ r9<- AA 4364 mov r3, r0, lsr #8 @ r3<- CC 4365 and r2, r0, #255 @ r2<- BB 4366 GET_VREG(r1, r3) @ r1<- vCC 4367 GET_VREG(r0, r2) @ r0<- vBB 4368 .if 0 4369 cmp r1, #0 @ is second operand zero? 4370 beq common_errDivideByZero 4371 .endif 4372 4373 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4374 and r1, r1, #31 @ optional op; may set condition codes 4375 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 4376 GET_INST_OPCODE(ip) @ extract opcode from rINST 4377 SET_VREG(r0, r9) @ vAA<- r0 4378 GOTO_OPCODE(ip) @ jump to next instruction 4379 /* 11-14 instructions */ 4380 4381 4382/* ------------------------------ */ 4383 .balign 64 4384.L_OP_SHR_INT: /* 0x99 */ 4385/* File: armv5te/OP_SHR_INT.S */ 4386/* File: armv5te/binop.S */ 4387 /* 4388 * Generic 32-bit binary operation. Provide an "instr" line that 4389 * specifies an instruction that performs "result = r0 op r1". 4390 * This could be an ARM instruction or a function call. (If the result 4391 * comes back in a register other than r0, you can override "result".) 4392 * 4393 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4394 * vCC (r1). Useful for integer division and modulus. Note that we 4395 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4396 * handles it correctly. 4397 * 4398 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4399 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4400 * mul-float, div-float, rem-float 4401 */ 4402 /* binop vAA, vBB, vCC */ 4403 FETCH(r0, 1) @ r0<- CCBB 4404 mov r9, rINST, lsr #8 @ r9<- AA 4405 mov r3, r0, lsr #8 @ r3<- CC 4406 and r2, r0, #255 @ r2<- BB 4407 GET_VREG(r1, r3) @ r1<- vCC 4408 GET_VREG(r0, r2) @ r0<- vBB 4409 .if 0 4410 cmp r1, #0 @ is second operand zero? 4411 beq common_errDivideByZero 4412 .endif 4413 4414 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4415 and r1, r1, #31 @ optional op; may set condition codes 4416 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 4417 GET_INST_OPCODE(ip) @ extract opcode from rINST 4418 SET_VREG(r0, r9) @ vAA<- r0 4419 GOTO_OPCODE(ip) @ jump to next instruction 4420 /* 11-14 instructions */ 4421 4422 4423/* ------------------------------ */ 4424 .balign 64 4425.L_OP_USHR_INT: /* 0x9a */ 4426/* File: armv5te/OP_USHR_INT.S */ 4427/* File: armv5te/binop.S */ 4428 /* 4429 * Generic 32-bit binary operation. Provide an "instr" line that 4430 * specifies an instruction that performs "result = r0 op r1". 4431 * This could be an ARM instruction or a function call. (If the result 4432 * comes back in a register other than r0, you can override "result".) 4433 * 4434 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4435 * vCC (r1). Useful for integer division and modulus. Note that we 4436 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 4437 * handles it correctly. 4438 * 4439 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 4440 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 4441 * mul-float, div-float, rem-float 4442 */ 4443 /* binop vAA, vBB, vCC */ 4444 FETCH(r0, 1) @ r0<- CCBB 4445 mov r9, rINST, lsr #8 @ r9<- AA 4446 mov r3, r0, lsr #8 @ r3<- CC 4447 and r2, r0, #255 @ r2<- BB 4448 GET_VREG(r1, r3) @ r1<- vCC 4449 GET_VREG(r0, r2) @ r0<- vBB 4450 .if 0 4451 cmp r1, #0 @ is second operand zero? 4452 beq common_errDivideByZero 4453 .endif 4454 4455 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4456 and r1, r1, #31 @ optional op; may set condition codes 4457 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 4458 GET_INST_OPCODE(ip) @ extract opcode from rINST 4459 SET_VREG(r0, r9) @ vAA<- r0 4460 GOTO_OPCODE(ip) @ jump to next instruction 4461 /* 11-14 instructions */ 4462 4463 4464/* ------------------------------ */ 4465 .balign 64 4466.L_OP_ADD_LONG: /* 0x9b */ 4467/* File: armv5te/OP_ADD_LONG.S */ 4468/* File: armv5te/binopWide.S */ 4469 /* 4470 * Generic 64-bit binary operation. Provide an "instr" line that 4471 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4472 * This could be an ARM instruction or a function call. (If the result 4473 * comes back in a register other than r0, you can override "result".) 4474 * 4475 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4476 * vCC (r1). Useful for integer division and modulus. 4477 * 4478 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4479 * xor-long, add-double, sub-double, mul-double, div-double, 4480 * rem-double 4481 * 4482 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4483 */ 4484 /* binop vAA, vBB, vCC */ 4485 FETCH(r0, 1) @ r0<- CCBB 4486 mov r9, rINST, lsr #8 @ r9<- AA 4487 and r2, r0, #255 @ r2<- BB 4488 mov r3, r0, lsr #8 @ r3<- CC 4489 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4490 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4491 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4492 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4493 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4494 .if 0 4495 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4496 beq common_errDivideByZero 4497 .endif 4498 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4499 4500 adds r0, r0, r2 @ optional op; may set condition codes 4501 adc r1, r1, r3 @ result<- op, r0-r3 changed 4502 GET_INST_OPCODE(ip) @ extract opcode from rINST 4503 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4504 GOTO_OPCODE(ip) @ jump to next instruction 4505 /* 14-17 instructions */ 4506 4507 4508/* ------------------------------ */ 4509 .balign 64 4510.L_OP_SUB_LONG: /* 0x9c */ 4511/* File: armv5te/OP_SUB_LONG.S */ 4512/* File: armv5te/binopWide.S */ 4513 /* 4514 * Generic 64-bit binary operation. Provide an "instr" line that 4515 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4516 * This could be an ARM instruction or a function call. (If the result 4517 * comes back in a register other than r0, you can override "result".) 4518 * 4519 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4520 * vCC (r1). Useful for integer division and modulus. 4521 * 4522 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4523 * xor-long, add-double, sub-double, mul-double, div-double, 4524 * rem-double 4525 * 4526 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4527 */ 4528 /* binop vAA, vBB, vCC */ 4529 FETCH(r0, 1) @ r0<- CCBB 4530 mov r9, rINST, lsr #8 @ r9<- AA 4531 and r2, r0, #255 @ r2<- BB 4532 mov r3, r0, lsr #8 @ r3<- CC 4533 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4534 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4535 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4536 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4537 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4538 .if 0 4539 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4540 beq common_errDivideByZero 4541 .endif 4542 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4543 4544 subs r0, r0, r2 @ optional op; may set condition codes 4545 sbc r1, r1, r3 @ result<- op, r0-r3 changed 4546 GET_INST_OPCODE(ip) @ extract opcode from rINST 4547 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4548 GOTO_OPCODE(ip) @ jump to next instruction 4549 /* 14-17 instructions */ 4550 4551 4552/* ------------------------------ */ 4553 .balign 64 4554.L_OP_MUL_LONG: /* 0x9d */ 4555/* File: armv5te/OP_MUL_LONG.S */ 4556 /* 4557 * Signed 64-bit integer multiply. 4558 * 4559 * Consider WXxYZ (r1r0 x r3r2) with a long multiply: 4560 * WX 4561 * x YZ 4562 * -------- 4563 * ZW ZX 4564 * YW YX 4565 * 4566 * The low word of the result holds ZX, the high word holds 4567 * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because 4568 * it doesn't fit in the low 64 bits. 4569 * 4570 * Unlike most ARM math operations, multiply instructions have 4571 * restrictions on using the same register more than once (Rd and Rm 4572 * cannot be the same). 4573 */ 4574 /* mul-long vAA, vBB, vCC */ 4575 FETCH(r0, 1) @ r0<- CCBB 4576 and r2, r0, #255 @ r2<- BB 4577 mov r3, r0, lsr #8 @ r3<- CC 4578 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4579 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4580 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4581 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4582 mul ip, r2, r1 @ ip<- ZxW 4583 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 4584 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 4585 mov r0, rINST, lsr #8 @ r0<- AA 4586 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 4587 add r0, rFP, r0, lsl #2 @ r0<- &fp[AA] 4588 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4589 b .LOP_MUL_LONG_finish 4590 4591/* ------------------------------ */ 4592 .balign 64 4593.L_OP_DIV_LONG: /* 0x9e */ 4594/* File: armv5te/OP_DIV_LONG.S */ 4595/* File: armv5te/binopWide.S */ 4596 /* 4597 * Generic 64-bit binary operation. Provide an "instr" line that 4598 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4599 * This could be an ARM instruction or a function call. (If the result 4600 * comes back in a register other than r0, you can override "result".) 4601 * 4602 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4603 * vCC (r1). Useful for integer division and modulus. 4604 * 4605 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4606 * xor-long, add-double, sub-double, mul-double, div-double, 4607 * rem-double 4608 * 4609 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4610 */ 4611 /* binop vAA, vBB, vCC */ 4612 FETCH(r0, 1) @ r0<- CCBB 4613 mov r9, rINST, lsr #8 @ r9<- AA 4614 and r2, r0, #255 @ r2<- BB 4615 mov r3, r0, lsr #8 @ r3<- CC 4616 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4617 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4618 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4619 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4620 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4621 .if 1 4622 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4623 beq common_errDivideByZero 4624 .endif 4625 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4626 4627 @ optional op; may set condition codes 4628 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4629 GET_INST_OPCODE(ip) @ extract opcode from rINST 4630 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4631 GOTO_OPCODE(ip) @ jump to next instruction 4632 /* 14-17 instructions */ 4633 4634 4635/* ------------------------------ */ 4636 .balign 64 4637.L_OP_REM_LONG: /* 0x9f */ 4638/* File: armv5te/OP_REM_LONG.S */ 4639/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 4640/* File: armv5te/binopWide.S */ 4641 /* 4642 * Generic 64-bit binary operation. Provide an "instr" line that 4643 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4644 * This could be an ARM instruction or a function call. (If the result 4645 * comes back in a register other than r0, you can override "result".) 4646 * 4647 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4648 * vCC (r1). Useful for integer division and modulus. 4649 * 4650 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4651 * xor-long, add-double, sub-double, mul-double, div-double, 4652 * rem-double 4653 * 4654 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4655 */ 4656 /* binop vAA, vBB, vCC */ 4657 FETCH(r0, 1) @ r0<- CCBB 4658 mov r9, rINST, lsr #8 @ r9<- AA 4659 and r2, r0, #255 @ r2<- BB 4660 mov r3, r0, lsr #8 @ r3<- CC 4661 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4662 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4663 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4664 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4665 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4666 .if 1 4667 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4668 beq common_errDivideByZero 4669 .endif 4670 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4671 4672 @ optional op; may set condition codes 4673 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 4674 GET_INST_OPCODE(ip) @ extract opcode from rINST 4675 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 4676 GOTO_OPCODE(ip) @ jump to next instruction 4677 /* 14-17 instructions */ 4678 4679 4680/* ------------------------------ */ 4681 .balign 64 4682.L_OP_AND_LONG: /* 0xa0 */ 4683/* File: armv5te/OP_AND_LONG.S */ 4684/* File: armv5te/binopWide.S */ 4685 /* 4686 * Generic 64-bit binary operation. Provide an "instr" line that 4687 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4688 * This could be an ARM instruction or a function call. (If the result 4689 * comes back in a register other than r0, you can override "result".) 4690 * 4691 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4692 * vCC (r1). Useful for integer division and modulus. 4693 * 4694 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4695 * xor-long, add-double, sub-double, mul-double, div-double, 4696 * rem-double 4697 * 4698 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4699 */ 4700 /* binop vAA, vBB, vCC */ 4701 FETCH(r0, 1) @ r0<- CCBB 4702 mov r9, rINST, lsr #8 @ r9<- AA 4703 and r2, r0, #255 @ r2<- BB 4704 mov r3, r0, lsr #8 @ r3<- CC 4705 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4706 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4707 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4708 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4709 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4710 .if 0 4711 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4712 beq common_errDivideByZero 4713 .endif 4714 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4715 4716 and r0, r0, r2 @ optional op; may set condition codes 4717 and r1, r1, r3 @ result<- op, r0-r3 changed 4718 GET_INST_OPCODE(ip) @ extract opcode from rINST 4719 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4720 GOTO_OPCODE(ip) @ jump to next instruction 4721 /* 14-17 instructions */ 4722 4723 4724/* ------------------------------ */ 4725 .balign 64 4726.L_OP_OR_LONG: /* 0xa1 */ 4727/* File: armv5te/OP_OR_LONG.S */ 4728/* File: armv5te/binopWide.S */ 4729 /* 4730 * Generic 64-bit binary operation. Provide an "instr" line that 4731 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4732 * This could be an ARM instruction or a function call. (If the result 4733 * comes back in a register other than r0, you can override "result".) 4734 * 4735 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4736 * vCC (r1). Useful for integer division and modulus. 4737 * 4738 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4739 * xor-long, add-double, sub-double, mul-double, div-double, 4740 * rem-double 4741 * 4742 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4743 */ 4744 /* binop vAA, vBB, vCC */ 4745 FETCH(r0, 1) @ r0<- CCBB 4746 mov r9, rINST, lsr #8 @ r9<- AA 4747 and r2, r0, #255 @ r2<- BB 4748 mov r3, r0, lsr #8 @ r3<- CC 4749 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4750 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4751 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4752 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4753 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4754 .if 0 4755 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4756 beq common_errDivideByZero 4757 .endif 4758 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4759 4760 orr r0, r0, r2 @ optional op; may set condition codes 4761 orr r1, r1, r3 @ result<- op, r0-r3 changed 4762 GET_INST_OPCODE(ip) @ extract opcode from rINST 4763 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4764 GOTO_OPCODE(ip) @ jump to next instruction 4765 /* 14-17 instructions */ 4766 4767 4768/* ------------------------------ */ 4769 .balign 64 4770.L_OP_XOR_LONG: /* 0xa2 */ 4771/* File: armv5te/OP_XOR_LONG.S */ 4772/* File: armv5te/binopWide.S */ 4773 /* 4774 * Generic 64-bit binary operation. Provide an "instr" line that 4775 * specifies an instruction that performs "result = r0-r1 op r2-r3". 4776 * This could be an ARM instruction or a function call. (If the result 4777 * comes back in a register other than r0, you can override "result".) 4778 * 4779 * If "chkzero" is set to 1, we perform a divide-by-zero check on 4780 * vCC (r1). Useful for integer division and modulus. 4781 * 4782 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 4783 * xor-long, add-double, sub-double, mul-double, div-double, 4784 * rem-double 4785 * 4786 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 4787 */ 4788 /* binop vAA, vBB, vCC */ 4789 FETCH(r0, 1) @ r0<- CCBB 4790 mov r9, rINST, lsr #8 @ r9<- AA 4791 and r2, r0, #255 @ r2<- BB 4792 mov r3, r0, lsr #8 @ r3<- CC 4793 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4794 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 4795 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 4796 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 4797 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 4798 .if 0 4799 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 4800 beq common_errDivideByZero 4801 .endif 4802 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4803 4804 eor r0, r0, r2 @ optional op; may set condition codes 4805 eor r1, r1, r3 @ result<- op, r0-r3 changed 4806 GET_INST_OPCODE(ip) @ extract opcode from rINST 4807 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 4808 GOTO_OPCODE(ip) @ jump to next instruction 4809 /* 14-17 instructions */ 4810 4811 4812/* ------------------------------ */ 4813 .balign 64 4814.L_OP_SHL_LONG: /* 0xa3 */ 4815/* File: armv5te/OP_SHL_LONG.S */ 4816 /* 4817 * Long integer shift. This is different from the generic 32/64-bit 4818 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4819 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4820 * 6 bits of the shift distance. 4821 */ 4822 /* shl-long vAA, vBB, vCC */ 4823 FETCH(r0, 1) @ r0<- CCBB 4824 mov r9, rINST, lsr #8 @ r9<- AA 4825 and r3, r0, #255 @ r3<- BB 4826 mov r0, r0, lsr #8 @ r0<- CC 4827 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4828 GET_VREG(r2, r0) @ r2<- vCC 4829 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4830 and r2, r2, #63 @ r2<- r2 & 0x3f 4831 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4832 4833 mov r1, r1, asl r2 @ r1<- r1 << r2 4834 rsb r3, r2, #32 @ r3<- 32 - r2 4835 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 4836 subs ip, r2, #32 @ ip<- r2 - 32 4837 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 4838 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4839 b .LOP_SHL_LONG_finish 4840 4841/* ------------------------------ */ 4842 .balign 64 4843.L_OP_SHR_LONG: /* 0xa4 */ 4844/* File: armv5te/OP_SHR_LONG.S */ 4845 /* 4846 * Long integer shift. This is different from the generic 32/64-bit 4847 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4848 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4849 * 6 bits of the shift distance. 4850 */ 4851 /* shr-long vAA, vBB, vCC */ 4852 FETCH(r0, 1) @ r0<- CCBB 4853 mov r9, rINST, lsr #8 @ r9<- AA 4854 and r3, r0, #255 @ r3<- BB 4855 mov r0, r0, lsr #8 @ r0<- CC 4856 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4857 GET_VREG(r2, r0) @ r2<- vCC 4858 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4859 and r2, r2, #63 @ r0<- r0 & 0x3f 4860 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4861 4862 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4863 rsb r3, r2, #32 @ r3<- 32 - r2 4864 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4865 subs ip, r2, #32 @ ip<- r2 - 32 4866 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 4867 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4868 b .LOP_SHR_LONG_finish 4869 4870/* ------------------------------ */ 4871 .balign 64 4872.L_OP_USHR_LONG: /* 0xa5 */ 4873/* File: armv5te/OP_USHR_LONG.S */ 4874 /* 4875 * Long integer shift. This is different from the generic 32/64-bit 4876 * binary operations because vAA/vBB are 64-bit but vCC (the shift 4877 * distance) is 32-bit. Also, Dalvik requires us to mask off the low 4878 * 6 bits of the shift distance. 4879 */ 4880 /* ushr-long vAA, vBB, vCC */ 4881 FETCH(r0, 1) @ r0<- CCBB 4882 mov r9, rINST, lsr #8 @ r9<- AA 4883 and r3, r0, #255 @ r3<- BB 4884 mov r0, r0, lsr #8 @ r0<- CC 4885 add r3, rFP, r3, lsl #2 @ r3<- &fp[BB] 4886 GET_VREG(r2, r0) @ r2<- vCC 4887 ldmia r3, {r0-r1} @ r0/r1<- vBB/vBB+1 4888 and r2, r2, #63 @ r0<- r0 & 0x3f 4889 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 4890 4891 mov r0, r0, lsr r2 @ r0<- r2 >> r2 4892 rsb r3, r2, #32 @ r3<- 32 - r2 4893 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 4894 subs ip, r2, #32 @ ip<- r2 - 32 4895 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 4896 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4897 b .LOP_USHR_LONG_finish 4898 4899/* ------------------------------ */ 4900 .balign 64 4901.L_OP_ADD_FLOAT: /* 0xa6 */ 4902/* File: arm-vfp/OP_ADD_FLOAT.S */ 4903/* File: arm-vfp/fbinop.S */ 4904 /* 4905 * Generic 32-bit floating-point operation. Provide an "instr" line that 4906 * specifies an instruction that performs "s2 = s0 op s1". Because we 4907 * use the "softfp" ABI, this must be an instruction, not a function call. 4908 * 4909 * For: add-float, sub-float, mul-float, div-float 4910 */ 4911 /* floatop vAA, vBB, vCC */ 4912 FETCH(r0, 1) @ r0<- CCBB 4913 mov r9, rINST, lsr #8 @ r9<- AA 4914 mov r3, r0, lsr #8 @ r3<- CC 4915 and r2, r0, #255 @ r2<- BB 4916 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4917 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4918 flds s1, [r3] @ s1<- vCC 4919 flds s0, [r2] @ s0<- vBB 4920 4921 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4922 fadds s2, s0, s1 @ s2<- op 4923 GET_INST_OPCODE(ip) @ extract opcode from rINST 4924 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4925 fsts s2, [r9] @ vAA<- s2 4926 GOTO_OPCODE(ip) @ jump to next instruction 4927 4928 4929/* ------------------------------ */ 4930 .balign 64 4931.L_OP_SUB_FLOAT: /* 0xa7 */ 4932/* File: arm-vfp/OP_SUB_FLOAT.S */ 4933/* File: arm-vfp/fbinop.S */ 4934 /* 4935 * Generic 32-bit floating-point operation. Provide an "instr" line that 4936 * specifies an instruction that performs "s2 = s0 op s1". Because we 4937 * use the "softfp" ABI, this must be an instruction, not a function call. 4938 * 4939 * For: add-float, sub-float, mul-float, div-float 4940 */ 4941 /* floatop vAA, vBB, vCC */ 4942 FETCH(r0, 1) @ r0<- CCBB 4943 mov r9, rINST, lsr #8 @ r9<- AA 4944 mov r3, r0, lsr #8 @ r3<- CC 4945 and r2, r0, #255 @ r2<- BB 4946 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4947 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4948 flds s1, [r3] @ s1<- vCC 4949 flds s0, [r2] @ s0<- vBB 4950 4951 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4952 fsubs s2, s0, s1 @ s2<- op 4953 GET_INST_OPCODE(ip) @ extract opcode from rINST 4954 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4955 fsts s2, [r9] @ vAA<- s2 4956 GOTO_OPCODE(ip) @ jump to next instruction 4957 4958 4959/* ------------------------------ */ 4960 .balign 64 4961.L_OP_MUL_FLOAT: /* 0xa8 */ 4962/* File: arm-vfp/OP_MUL_FLOAT.S */ 4963/* File: arm-vfp/fbinop.S */ 4964 /* 4965 * Generic 32-bit floating-point operation. Provide an "instr" line that 4966 * specifies an instruction that performs "s2 = s0 op s1". Because we 4967 * use the "softfp" ABI, this must be an instruction, not a function call. 4968 * 4969 * For: add-float, sub-float, mul-float, div-float 4970 */ 4971 /* floatop vAA, vBB, vCC */ 4972 FETCH(r0, 1) @ r0<- CCBB 4973 mov r9, rINST, lsr #8 @ r9<- AA 4974 mov r3, r0, lsr #8 @ r3<- CC 4975 and r2, r0, #255 @ r2<- BB 4976 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 4977 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 4978 flds s1, [r3] @ s1<- vCC 4979 flds s0, [r2] @ s0<- vBB 4980 4981 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 4982 fmuls s2, s0, s1 @ s2<- op 4983 GET_INST_OPCODE(ip) @ extract opcode from rINST 4984 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 4985 fsts s2, [r9] @ vAA<- s2 4986 GOTO_OPCODE(ip) @ jump to next instruction 4987 4988 4989/* ------------------------------ */ 4990 .balign 64 4991.L_OP_DIV_FLOAT: /* 0xa9 */ 4992/* File: arm-vfp/OP_DIV_FLOAT.S */ 4993/* File: arm-vfp/fbinop.S */ 4994 /* 4995 * Generic 32-bit floating-point operation. Provide an "instr" line that 4996 * specifies an instruction that performs "s2 = s0 op s1". Because we 4997 * use the "softfp" ABI, this must be an instruction, not a function call. 4998 * 4999 * For: add-float, sub-float, mul-float, div-float 5000 */ 5001 /* floatop vAA, vBB, vCC */ 5002 FETCH(r0, 1) @ r0<- CCBB 5003 mov r9, rINST, lsr #8 @ r9<- AA 5004 mov r3, r0, lsr #8 @ r3<- CC 5005 and r2, r0, #255 @ r2<- BB 5006 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5007 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5008 flds s1, [r3] @ s1<- vCC 5009 flds s0, [r2] @ s0<- vBB 5010 5011 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5012 fdivs s2, s0, s1 @ s2<- op 5013 GET_INST_OPCODE(ip) @ extract opcode from rINST 5014 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5015 fsts s2, [r9] @ vAA<- s2 5016 GOTO_OPCODE(ip) @ jump to next instruction 5017 5018 5019/* ------------------------------ */ 5020 .balign 64 5021.L_OP_REM_FLOAT: /* 0xaa */ 5022/* File: armv5te/OP_REM_FLOAT.S */ 5023/* EABI doesn't define a float remainder function, but libm does */ 5024/* File: armv5te/binop.S */ 5025 /* 5026 * Generic 32-bit binary operation. Provide an "instr" line that 5027 * specifies an instruction that performs "result = r0 op r1". 5028 * This could be an ARM instruction or a function call. (If the result 5029 * comes back in a register other than r0, you can override "result".) 5030 * 5031 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5032 * vCC (r1). Useful for integer division and modulus. Note that we 5033 * *don't* check for (INT_MIN / -1) here, because the ARM math lib 5034 * handles it correctly. 5035 * 5036 * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, 5037 * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, 5038 * mul-float, div-float, rem-float 5039 */ 5040 /* binop vAA, vBB, vCC */ 5041 FETCH(r0, 1) @ r0<- CCBB 5042 mov r9, rINST, lsr #8 @ r9<- AA 5043 mov r3, r0, lsr #8 @ r3<- CC 5044 and r2, r0, #255 @ r2<- BB 5045 GET_VREG(r1, r3) @ r1<- vCC 5046 GET_VREG(r0, r2) @ r0<- vBB 5047 .if 0 5048 cmp r1, #0 @ is second operand zero? 5049 beq common_errDivideByZero 5050 .endif 5051 5052 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5053 @ optional op; may set condition codes 5054 bl fmodf @ r0<- op, r0-r3 changed 5055 GET_INST_OPCODE(ip) @ extract opcode from rINST 5056 SET_VREG(r0, r9) @ vAA<- r0 5057 GOTO_OPCODE(ip) @ jump to next instruction 5058 /* 11-14 instructions */ 5059 5060 5061/* ------------------------------ */ 5062 .balign 64 5063.L_OP_ADD_DOUBLE: /* 0xab */ 5064/* File: arm-vfp/OP_ADD_DOUBLE.S */ 5065/* File: arm-vfp/fbinopWide.S */ 5066 /* 5067 * Generic 64-bit double-precision floating point binary operation. 5068 * Provide an "instr" line that specifies an instruction that performs 5069 * "d2 = d0 op d1". 5070 * 5071 * for: add-double, sub-double, mul-double, div-double 5072 */ 5073 /* doubleop vAA, vBB, vCC */ 5074 FETCH(r0, 1) @ r0<- CCBB 5075 mov r9, rINST, lsr #8 @ r9<- AA 5076 mov r3, r0, lsr #8 @ r3<- CC 5077 and r2, r0, #255 @ r2<- BB 5078 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5079 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5080 fldd d1, [r3] @ d1<- vCC 5081 fldd d0, [r2] @ d0<- vBB 5082 5083 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5084 faddd d2, d0, d1 @ s2<- op 5085 GET_INST_OPCODE(ip) @ extract opcode from rINST 5086 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5087 fstd d2, [r9] @ vAA<- d2 5088 GOTO_OPCODE(ip) @ jump to next instruction 5089 5090 5091/* ------------------------------ */ 5092 .balign 64 5093.L_OP_SUB_DOUBLE: /* 0xac */ 5094/* File: arm-vfp/OP_SUB_DOUBLE.S */ 5095/* File: arm-vfp/fbinopWide.S */ 5096 /* 5097 * Generic 64-bit double-precision floating point binary operation. 5098 * Provide an "instr" line that specifies an instruction that performs 5099 * "d2 = d0 op d1". 5100 * 5101 * for: add-double, sub-double, mul-double, div-double 5102 */ 5103 /* doubleop vAA, vBB, vCC */ 5104 FETCH(r0, 1) @ r0<- CCBB 5105 mov r9, rINST, lsr #8 @ r9<- AA 5106 mov r3, r0, lsr #8 @ r3<- CC 5107 and r2, r0, #255 @ r2<- BB 5108 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5109 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5110 fldd d1, [r3] @ d1<- vCC 5111 fldd d0, [r2] @ d0<- vBB 5112 5113 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5114 fsubd d2, d0, d1 @ s2<- op 5115 GET_INST_OPCODE(ip) @ extract opcode from rINST 5116 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5117 fstd d2, [r9] @ vAA<- d2 5118 GOTO_OPCODE(ip) @ jump to next instruction 5119 5120 5121/* ------------------------------ */ 5122 .balign 64 5123.L_OP_MUL_DOUBLE: /* 0xad */ 5124/* File: arm-vfp/OP_MUL_DOUBLE.S */ 5125/* File: arm-vfp/fbinopWide.S */ 5126 /* 5127 * Generic 64-bit double-precision floating point binary operation. 5128 * Provide an "instr" line that specifies an instruction that performs 5129 * "d2 = d0 op d1". 5130 * 5131 * for: add-double, sub-double, mul-double, div-double 5132 */ 5133 /* doubleop vAA, vBB, vCC */ 5134 FETCH(r0, 1) @ r0<- CCBB 5135 mov r9, rINST, lsr #8 @ r9<- AA 5136 mov r3, r0, lsr #8 @ r3<- CC 5137 and r2, r0, #255 @ r2<- BB 5138 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5139 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5140 fldd d1, [r3] @ d1<- vCC 5141 fldd d0, [r2] @ d0<- vBB 5142 5143 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5144 fmuld d2, d0, d1 @ s2<- op 5145 GET_INST_OPCODE(ip) @ extract opcode from rINST 5146 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5147 fstd d2, [r9] @ vAA<- d2 5148 GOTO_OPCODE(ip) @ jump to next instruction 5149 5150 5151/* ------------------------------ */ 5152 .balign 64 5153.L_OP_DIV_DOUBLE: /* 0xae */ 5154/* File: arm-vfp/OP_DIV_DOUBLE.S */ 5155/* File: arm-vfp/fbinopWide.S */ 5156 /* 5157 * Generic 64-bit double-precision floating point binary operation. 5158 * Provide an "instr" line that specifies an instruction that performs 5159 * "d2 = d0 op d1". 5160 * 5161 * for: add-double, sub-double, mul-double, div-double 5162 */ 5163 /* doubleop vAA, vBB, vCC */ 5164 FETCH(r0, 1) @ r0<- CCBB 5165 mov r9, rINST, lsr #8 @ r9<- AA 5166 mov r3, r0, lsr #8 @ r3<- CC 5167 and r2, r0, #255 @ r2<- BB 5168 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vCC 5169 VREG_INDEX_TO_ADDR(r2, r2) @ r2<- &vBB 5170 fldd d1, [r3] @ d1<- vCC 5171 fldd d0, [r2] @ d0<- vBB 5172 5173 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5174 fdivd d2, d0, d1 @ s2<- op 5175 GET_INST_OPCODE(ip) @ extract opcode from rINST 5176 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vAA 5177 fstd d2, [r9] @ vAA<- d2 5178 GOTO_OPCODE(ip) @ jump to next instruction 5179 5180 5181/* ------------------------------ */ 5182 .balign 64 5183.L_OP_REM_DOUBLE: /* 0xaf */ 5184/* File: armv5te/OP_REM_DOUBLE.S */ 5185/* EABI doesn't define a double remainder function, but libm does */ 5186/* File: armv5te/binopWide.S */ 5187 /* 5188 * Generic 64-bit binary operation. Provide an "instr" line that 5189 * specifies an instruction that performs "result = r0-r1 op r2-r3". 5190 * This could be an ARM instruction or a function call. (If the result 5191 * comes back in a register other than r0, you can override "result".) 5192 * 5193 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5194 * vCC (r1). Useful for integer division and modulus. 5195 * 5196 * for: add-long, sub-long, div-long, rem-long, and-long, or-long, 5197 * xor-long, add-double, sub-double, mul-double, div-double, 5198 * rem-double 5199 * 5200 * IMPORTANT: you may specify "chkzero" or "preinstr" but not both. 5201 */ 5202 /* binop vAA, vBB, vCC */ 5203 FETCH(r0, 1) @ r0<- CCBB 5204 mov r9, rINST, lsr #8 @ r9<- AA 5205 and r2, r0, #255 @ r2<- BB 5206 mov r3, r0, lsr #8 @ r3<- CC 5207 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 5208 add r2, rFP, r2, lsl #2 @ r2<- &fp[BB] 5209 add r3, rFP, r3, lsl #2 @ r3<- &fp[CC] 5210 ldmia r2, {r0-r1} @ r0/r1<- vBB/vBB+1 5211 ldmia r3, {r2-r3} @ r2/r3<- vCC/vCC+1 5212 .if 0 5213 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5214 beq common_errDivideByZero 5215 .endif 5216 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 5217 5218 @ optional op; may set condition codes 5219 bl fmod @ result<- op, r0-r3 changed 5220 GET_INST_OPCODE(ip) @ extract opcode from rINST 5221 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5222 GOTO_OPCODE(ip) @ jump to next instruction 5223 /* 14-17 instructions */ 5224 5225 5226/* ------------------------------ */ 5227 .balign 64 5228.L_OP_ADD_INT_2ADDR: /* 0xb0 */ 5229/* File: armv6t2/OP_ADD_INT_2ADDR.S */ 5230/* File: armv6t2/binop2addr.S */ 5231 /* 5232 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5233 * that specifies an instruction that performs "result = r0 op r1". 5234 * This could be an ARM instruction or a function call. (If the result 5235 * comes back in a register other than r0, you can override "result".) 5236 * 5237 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5238 * vCC (r1). Useful for integer division and modulus. 5239 * 5240 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5241 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5242 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5243 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5244 */ 5245 /* binop/2addr vA, vB */ 5246 mov r3, rINST, lsr #12 @ r3<- B 5247 ubfx r9, rINST, #8, #4 @ r9<- A 5248 GET_VREG(r1, r3) @ r1<- vB 5249 GET_VREG(r0, r9) @ r0<- vA 5250 .if 0 5251 cmp r1, #0 @ is second operand zero? 5252 beq common_errDivideByZero 5253 .endif 5254 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5255 5256 @ optional op; may set condition codes 5257 add r0, r0, r1 @ r0<- op, r0-r3 changed 5258 GET_INST_OPCODE(ip) @ extract opcode from rINST 5259 SET_VREG(r0, r9) @ vAA<- r0 5260 GOTO_OPCODE(ip) @ jump to next instruction 5261 /* 10-13 instructions */ 5262 5263 5264/* ------------------------------ */ 5265 .balign 64 5266.L_OP_SUB_INT_2ADDR: /* 0xb1 */ 5267/* File: armv6t2/OP_SUB_INT_2ADDR.S */ 5268/* File: armv6t2/binop2addr.S */ 5269 /* 5270 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5271 * that specifies an instruction that performs "result = r0 op r1". 5272 * This could be an ARM instruction or a function call. (If the result 5273 * comes back in a register other than r0, you can override "result".) 5274 * 5275 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5276 * vCC (r1). Useful for integer division and modulus. 5277 * 5278 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5279 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5280 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5281 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5282 */ 5283 /* binop/2addr vA, vB */ 5284 mov r3, rINST, lsr #12 @ r3<- B 5285 ubfx r9, rINST, #8, #4 @ r9<- A 5286 GET_VREG(r1, r3) @ r1<- vB 5287 GET_VREG(r0, r9) @ r0<- vA 5288 .if 0 5289 cmp r1, #0 @ is second operand zero? 5290 beq common_errDivideByZero 5291 .endif 5292 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5293 5294 @ optional op; may set condition codes 5295 sub r0, r0, r1 @ r0<- op, r0-r3 changed 5296 GET_INST_OPCODE(ip) @ extract opcode from rINST 5297 SET_VREG(r0, r9) @ vAA<- r0 5298 GOTO_OPCODE(ip) @ jump to next instruction 5299 /* 10-13 instructions */ 5300 5301 5302/* ------------------------------ */ 5303 .balign 64 5304.L_OP_MUL_INT_2ADDR: /* 0xb2 */ 5305/* File: armv6t2/OP_MUL_INT_2ADDR.S */ 5306/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 5307/* File: armv6t2/binop2addr.S */ 5308 /* 5309 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5310 * that specifies an instruction that performs "result = r0 op r1". 5311 * This could be an ARM instruction or a function call. (If the result 5312 * comes back in a register other than r0, you can override "result".) 5313 * 5314 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5315 * vCC (r1). Useful for integer division and modulus. 5316 * 5317 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5318 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5319 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5320 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5321 */ 5322 /* binop/2addr vA, vB */ 5323 mov r3, rINST, lsr #12 @ r3<- B 5324 ubfx r9, rINST, #8, #4 @ r9<- A 5325 GET_VREG(r1, r3) @ r1<- vB 5326 GET_VREG(r0, r9) @ r0<- vA 5327 .if 0 5328 cmp r1, #0 @ is second operand zero? 5329 beq common_errDivideByZero 5330 .endif 5331 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5332 5333 @ optional op; may set condition codes 5334 mul r0, r1, r0 @ r0<- op, r0-r3 changed 5335 GET_INST_OPCODE(ip) @ extract opcode from rINST 5336 SET_VREG(r0, r9) @ vAA<- r0 5337 GOTO_OPCODE(ip) @ jump to next instruction 5338 /* 10-13 instructions */ 5339 5340 5341/* ------------------------------ */ 5342 .balign 64 5343.L_OP_DIV_INT_2ADDR: /* 0xb3 */ 5344/* File: armv6t2/OP_DIV_INT_2ADDR.S */ 5345/* File: armv6t2/binop2addr.S */ 5346 /* 5347 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5348 * that specifies an instruction that performs "result = r0 op r1". 5349 * This could be an ARM instruction or a function call. (If the result 5350 * comes back in a register other than r0, you can override "result".) 5351 * 5352 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5353 * vCC (r1). Useful for integer division and modulus. 5354 * 5355 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5356 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5357 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5358 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5359 */ 5360 /* binop/2addr vA, vB */ 5361 mov r3, rINST, lsr #12 @ r3<- B 5362 ubfx r9, rINST, #8, #4 @ r9<- A 5363 GET_VREG(r1, r3) @ r1<- vB 5364 GET_VREG(r0, r9) @ r0<- vA 5365 .if 1 5366 cmp r1, #0 @ is second operand zero? 5367 beq common_errDivideByZero 5368 .endif 5369 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5370 5371 @ optional op; may set condition codes 5372 bl __aeabi_idiv @ r0<- op, r0-r3 changed 5373 GET_INST_OPCODE(ip) @ extract opcode from rINST 5374 SET_VREG(r0, r9) @ vAA<- r0 5375 GOTO_OPCODE(ip) @ jump to next instruction 5376 /* 10-13 instructions */ 5377 5378 5379/* ------------------------------ */ 5380 .balign 64 5381.L_OP_REM_INT_2ADDR: /* 0xb4 */ 5382/* File: armv6t2/OP_REM_INT_2ADDR.S */ 5383/* idivmod returns quotient in r0 and remainder in r1 */ 5384/* File: armv6t2/binop2addr.S */ 5385 /* 5386 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5387 * that specifies an instruction that performs "result = r0 op r1". 5388 * This could be an ARM instruction or a function call. (If the result 5389 * comes back in a register other than r0, you can override "result".) 5390 * 5391 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5392 * vCC (r1). Useful for integer division and modulus. 5393 * 5394 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5395 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5396 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5397 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5398 */ 5399 /* binop/2addr vA, vB */ 5400 mov r3, rINST, lsr #12 @ r3<- B 5401 ubfx r9, rINST, #8, #4 @ r9<- A 5402 GET_VREG(r1, r3) @ r1<- vB 5403 GET_VREG(r0, r9) @ r0<- vA 5404 .if 1 5405 cmp r1, #0 @ is second operand zero? 5406 beq common_errDivideByZero 5407 .endif 5408 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5409 5410 @ optional op; may set condition codes 5411 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 5412 GET_INST_OPCODE(ip) @ extract opcode from rINST 5413 SET_VREG(r1, r9) @ vAA<- r1 5414 GOTO_OPCODE(ip) @ jump to next instruction 5415 /* 10-13 instructions */ 5416 5417 5418/* ------------------------------ */ 5419 .balign 64 5420.L_OP_AND_INT_2ADDR: /* 0xb5 */ 5421/* File: armv6t2/OP_AND_INT_2ADDR.S */ 5422/* File: armv6t2/binop2addr.S */ 5423 /* 5424 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5425 * that specifies an instruction that performs "result = r0 op r1". 5426 * This could be an ARM instruction or a function call. (If the result 5427 * comes back in a register other than r0, you can override "result".) 5428 * 5429 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5430 * vCC (r1). Useful for integer division and modulus. 5431 * 5432 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5433 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5434 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5435 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5436 */ 5437 /* binop/2addr vA, vB */ 5438 mov r3, rINST, lsr #12 @ r3<- B 5439 ubfx r9, rINST, #8, #4 @ r9<- A 5440 GET_VREG(r1, r3) @ r1<- vB 5441 GET_VREG(r0, r9) @ r0<- vA 5442 .if 0 5443 cmp r1, #0 @ is second operand zero? 5444 beq common_errDivideByZero 5445 .endif 5446 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5447 5448 @ optional op; may set condition codes 5449 and r0, r0, r1 @ r0<- op, r0-r3 changed 5450 GET_INST_OPCODE(ip) @ extract opcode from rINST 5451 SET_VREG(r0, r9) @ vAA<- r0 5452 GOTO_OPCODE(ip) @ jump to next instruction 5453 /* 10-13 instructions */ 5454 5455 5456/* ------------------------------ */ 5457 .balign 64 5458.L_OP_OR_INT_2ADDR: /* 0xb6 */ 5459/* File: armv6t2/OP_OR_INT_2ADDR.S */ 5460/* File: armv6t2/binop2addr.S */ 5461 /* 5462 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5463 * that specifies an instruction that performs "result = r0 op r1". 5464 * This could be an ARM instruction or a function call. (If the result 5465 * comes back in a register other than r0, you can override "result".) 5466 * 5467 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5468 * vCC (r1). Useful for integer division and modulus. 5469 * 5470 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5471 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5472 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5473 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5474 */ 5475 /* binop/2addr vA, vB */ 5476 mov r3, rINST, lsr #12 @ r3<- B 5477 ubfx r9, rINST, #8, #4 @ r9<- A 5478 GET_VREG(r1, r3) @ r1<- vB 5479 GET_VREG(r0, r9) @ r0<- vA 5480 .if 0 5481 cmp r1, #0 @ is second operand zero? 5482 beq common_errDivideByZero 5483 .endif 5484 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5485 5486 @ optional op; may set condition codes 5487 orr r0, r0, r1 @ r0<- op, r0-r3 changed 5488 GET_INST_OPCODE(ip) @ extract opcode from rINST 5489 SET_VREG(r0, r9) @ vAA<- r0 5490 GOTO_OPCODE(ip) @ jump to next instruction 5491 /* 10-13 instructions */ 5492 5493 5494/* ------------------------------ */ 5495 .balign 64 5496.L_OP_XOR_INT_2ADDR: /* 0xb7 */ 5497/* File: armv6t2/OP_XOR_INT_2ADDR.S */ 5498/* File: armv6t2/binop2addr.S */ 5499 /* 5500 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5501 * that specifies an instruction that performs "result = r0 op r1". 5502 * This could be an ARM instruction or a function call. (If the result 5503 * comes back in a register other than r0, you can override "result".) 5504 * 5505 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5506 * vCC (r1). Useful for integer division and modulus. 5507 * 5508 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5509 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5510 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5511 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5512 */ 5513 /* binop/2addr vA, vB */ 5514 mov r3, rINST, lsr #12 @ r3<- B 5515 ubfx r9, rINST, #8, #4 @ r9<- A 5516 GET_VREG(r1, r3) @ r1<- vB 5517 GET_VREG(r0, r9) @ r0<- vA 5518 .if 0 5519 cmp r1, #0 @ is second operand zero? 5520 beq common_errDivideByZero 5521 .endif 5522 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5523 5524 @ optional op; may set condition codes 5525 eor r0, r0, r1 @ r0<- op, r0-r3 changed 5526 GET_INST_OPCODE(ip) @ extract opcode from rINST 5527 SET_VREG(r0, r9) @ vAA<- r0 5528 GOTO_OPCODE(ip) @ jump to next instruction 5529 /* 10-13 instructions */ 5530 5531 5532/* ------------------------------ */ 5533 .balign 64 5534.L_OP_SHL_INT_2ADDR: /* 0xb8 */ 5535/* File: armv6t2/OP_SHL_INT_2ADDR.S */ 5536/* File: armv6t2/binop2addr.S */ 5537 /* 5538 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5539 * that specifies an instruction that performs "result = r0 op r1". 5540 * This could be an ARM instruction or a function call. (If the result 5541 * comes back in a register other than r0, you can override "result".) 5542 * 5543 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5544 * vCC (r1). Useful for integer division and modulus. 5545 * 5546 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5547 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5548 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5549 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5550 */ 5551 /* binop/2addr vA, vB */ 5552 mov r3, rINST, lsr #12 @ r3<- B 5553 ubfx r9, rINST, #8, #4 @ r9<- A 5554 GET_VREG(r1, r3) @ r1<- vB 5555 GET_VREG(r0, r9) @ r0<- vA 5556 .if 0 5557 cmp r1, #0 @ is second operand zero? 5558 beq common_errDivideByZero 5559 .endif 5560 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5561 5562 and r1, r1, #31 @ optional op; may set condition codes 5563 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 5564 GET_INST_OPCODE(ip) @ extract opcode from rINST 5565 SET_VREG(r0, r9) @ vAA<- r0 5566 GOTO_OPCODE(ip) @ jump to next instruction 5567 /* 10-13 instructions */ 5568 5569 5570/* ------------------------------ */ 5571 .balign 64 5572.L_OP_SHR_INT_2ADDR: /* 0xb9 */ 5573/* File: armv6t2/OP_SHR_INT_2ADDR.S */ 5574/* File: armv6t2/binop2addr.S */ 5575 /* 5576 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5577 * that specifies an instruction that performs "result = r0 op r1". 5578 * This could be an ARM instruction or a function call. (If the result 5579 * comes back in a register other than r0, you can override "result".) 5580 * 5581 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5582 * vCC (r1). Useful for integer division and modulus. 5583 * 5584 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5585 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5586 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5587 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5588 */ 5589 /* binop/2addr vA, vB */ 5590 mov r3, rINST, lsr #12 @ r3<- B 5591 ubfx r9, rINST, #8, #4 @ r9<- A 5592 GET_VREG(r1, r3) @ r1<- vB 5593 GET_VREG(r0, r9) @ r0<- vA 5594 .if 0 5595 cmp r1, #0 @ is second operand zero? 5596 beq common_errDivideByZero 5597 .endif 5598 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5599 5600 and r1, r1, #31 @ optional op; may set condition codes 5601 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 5602 GET_INST_OPCODE(ip) @ extract opcode from rINST 5603 SET_VREG(r0, r9) @ vAA<- r0 5604 GOTO_OPCODE(ip) @ jump to next instruction 5605 /* 10-13 instructions */ 5606 5607 5608/* ------------------------------ */ 5609 .balign 64 5610.L_OP_USHR_INT_2ADDR: /* 0xba */ 5611/* File: armv6t2/OP_USHR_INT_2ADDR.S */ 5612/* File: armv6t2/binop2addr.S */ 5613 /* 5614 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 5615 * that specifies an instruction that performs "result = r0 op r1". 5616 * This could be an ARM instruction or a function call. (If the result 5617 * comes back in a register other than r0, you can override "result".) 5618 * 5619 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5620 * vCC (r1). Useful for integer division and modulus. 5621 * 5622 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 5623 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 5624 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 5625 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 5626 */ 5627 /* binop/2addr vA, vB */ 5628 mov r3, rINST, lsr #12 @ r3<- B 5629 ubfx r9, rINST, #8, #4 @ r9<- A 5630 GET_VREG(r1, r3) @ r1<- vB 5631 GET_VREG(r0, r9) @ r0<- vA 5632 .if 0 5633 cmp r1, #0 @ is second operand zero? 5634 beq common_errDivideByZero 5635 .endif 5636 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5637 5638 and r1, r1, #31 @ optional op; may set condition codes 5639 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 5640 GET_INST_OPCODE(ip) @ extract opcode from rINST 5641 SET_VREG(r0, r9) @ vAA<- r0 5642 GOTO_OPCODE(ip) @ jump to next instruction 5643 /* 10-13 instructions */ 5644 5645 5646/* ------------------------------ */ 5647 .balign 64 5648.L_OP_ADD_LONG_2ADDR: /* 0xbb */ 5649/* File: armv6t2/OP_ADD_LONG_2ADDR.S */ 5650/* File: armv6t2/binopWide2addr.S */ 5651 /* 5652 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5653 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5654 * This could be an ARM instruction or a function call. (If the result 5655 * comes back in a register other than r0, you can override "result".) 5656 * 5657 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5658 * vCC (r1). Useful for integer division and modulus. 5659 * 5660 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5661 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5662 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5663 * rem-double/2addr 5664 */ 5665 /* binop/2addr vA, vB */ 5666 mov r1, rINST, lsr #12 @ r1<- B 5667 ubfx r9, rINST, #8, #4 @ r9<- A 5668 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5669 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5670 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5671 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5672 .if 0 5673 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5674 beq common_errDivideByZero 5675 .endif 5676 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5677 5678 adds r0, r0, r2 @ optional op; may set condition codes 5679 adc r1, r1, r3 @ result<- op, r0-r3 changed 5680 GET_INST_OPCODE(ip) @ extract opcode from rINST 5681 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5682 GOTO_OPCODE(ip) @ jump to next instruction 5683 /* 12-15 instructions */ 5684 5685 5686/* ------------------------------ */ 5687 .balign 64 5688.L_OP_SUB_LONG_2ADDR: /* 0xbc */ 5689/* File: armv6t2/OP_SUB_LONG_2ADDR.S */ 5690/* File: armv6t2/binopWide2addr.S */ 5691 /* 5692 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5693 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5694 * This could be an ARM instruction or a function call. (If the result 5695 * comes back in a register other than r0, you can override "result".) 5696 * 5697 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5698 * vCC (r1). Useful for integer division and modulus. 5699 * 5700 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5701 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5702 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5703 * rem-double/2addr 5704 */ 5705 /* binop/2addr vA, vB */ 5706 mov r1, rINST, lsr #12 @ r1<- B 5707 ubfx r9, rINST, #8, #4 @ r9<- A 5708 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5709 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5710 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5711 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5712 .if 0 5713 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5714 beq common_errDivideByZero 5715 .endif 5716 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5717 5718 subs r0, r0, r2 @ optional op; may set condition codes 5719 sbc r1, r1, r3 @ result<- op, r0-r3 changed 5720 GET_INST_OPCODE(ip) @ extract opcode from rINST 5721 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5722 GOTO_OPCODE(ip) @ jump to next instruction 5723 /* 12-15 instructions */ 5724 5725 5726/* ------------------------------ */ 5727 .balign 64 5728.L_OP_MUL_LONG_2ADDR: /* 0xbd */ 5729/* File: armv6t2/OP_MUL_LONG_2ADDR.S */ 5730 /* 5731 * Signed 64-bit integer multiply, "/2addr" version. 5732 * 5733 * See OP_MUL_LONG for an explanation. 5734 * 5735 * We get a little tight on registers, so to avoid looking up &fp[A] 5736 * again we stuff it into rINST. 5737 */ 5738 /* mul-long/2addr vA, vB */ 5739 mov r1, rINST, lsr #12 @ r1<- B 5740 ubfx r9, rINST, #8, #4 @ r9<- A 5741 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5742 add rINST, rFP, r9, lsl #2 @ rINST<- &fp[A] 5743 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5744 ldmia rINST, {r0-r1} @ r0/r1<- vAA/vAA+1 5745 mul ip, r2, r1 @ ip<- ZxW 5746 umull r9, r10, r2, r0 @ r9/r10 <- ZxX 5747 mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 5748 mov r0, rINST @ r0<- &fp[A] (free up rINST) 5749 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5750 add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 5751 GET_INST_OPCODE(ip) @ extract opcode from rINST 5752 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 5753 GOTO_OPCODE(ip) @ jump to next instruction 5754 5755/* ------------------------------ */ 5756 .balign 64 5757.L_OP_DIV_LONG_2ADDR: /* 0xbe */ 5758/* File: armv6t2/OP_DIV_LONG_2ADDR.S */ 5759/* File: armv6t2/binopWide2addr.S */ 5760 /* 5761 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5762 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5763 * This could be an ARM instruction or a function call. (If the result 5764 * comes back in a register other than r0, you can override "result".) 5765 * 5766 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5767 * vCC (r1). Useful for integer division and modulus. 5768 * 5769 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5770 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5771 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5772 * rem-double/2addr 5773 */ 5774 /* binop/2addr vA, vB */ 5775 mov r1, rINST, lsr #12 @ r1<- B 5776 ubfx r9, rINST, #8, #4 @ r9<- A 5777 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5778 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5779 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5780 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5781 .if 1 5782 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5783 beq common_errDivideByZero 5784 .endif 5785 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5786 5787 @ optional op; may set condition codes 5788 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5789 GET_INST_OPCODE(ip) @ extract opcode from rINST 5790 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5791 GOTO_OPCODE(ip) @ jump to next instruction 5792 /* 12-15 instructions */ 5793 5794 5795/* ------------------------------ */ 5796 .balign 64 5797.L_OP_REM_LONG_2ADDR: /* 0xbf */ 5798/* File: armv6t2/OP_REM_LONG_2ADDR.S */ 5799/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */ 5800/* File: armv6t2/binopWide2addr.S */ 5801 /* 5802 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5803 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5804 * This could be an ARM instruction or a function call. (If the result 5805 * comes back in a register other than r0, you can override "result".) 5806 * 5807 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5808 * vCC (r1). Useful for integer division and modulus. 5809 * 5810 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5811 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5812 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5813 * rem-double/2addr 5814 */ 5815 /* binop/2addr vA, vB */ 5816 mov r1, rINST, lsr #12 @ r1<- B 5817 ubfx r9, rINST, #8, #4 @ r9<- A 5818 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5819 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5820 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5821 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5822 .if 1 5823 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5824 beq common_errDivideByZero 5825 .endif 5826 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5827 5828 @ optional op; may set condition codes 5829 bl __aeabi_ldivmod @ result<- op, r0-r3 changed 5830 GET_INST_OPCODE(ip) @ extract opcode from rINST 5831 stmia r9, {r2,r3} @ vAA/vAA+1<- r2/r3 5832 GOTO_OPCODE(ip) @ jump to next instruction 5833 /* 12-15 instructions */ 5834 5835 5836/* ------------------------------ */ 5837 .balign 64 5838.L_OP_AND_LONG_2ADDR: /* 0xc0 */ 5839/* File: armv6t2/OP_AND_LONG_2ADDR.S */ 5840/* File: armv6t2/binopWide2addr.S */ 5841 /* 5842 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5843 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5844 * This could be an ARM instruction or a function call. (If the result 5845 * comes back in a register other than r0, you can override "result".) 5846 * 5847 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5848 * vCC (r1). Useful for integer division and modulus. 5849 * 5850 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5851 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5852 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5853 * rem-double/2addr 5854 */ 5855 /* binop/2addr vA, vB */ 5856 mov r1, rINST, lsr #12 @ r1<- B 5857 ubfx r9, rINST, #8, #4 @ r9<- A 5858 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5859 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5860 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5861 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5862 .if 0 5863 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5864 beq common_errDivideByZero 5865 .endif 5866 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5867 5868 and r0, r0, r2 @ optional op; may set condition codes 5869 and r1, r1, r3 @ result<- op, r0-r3 changed 5870 GET_INST_OPCODE(ip) @ extract opcode from rINST 5871 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5872 GOTO_OPCODE(ip) @ jump to next instruction 5873 /* 12-15 instructions */ 5874 5875 5876/* ------------------------------ */ 5877 .balign 64 5878.L_OP_OR_LONG_2ADDR: /* 0xc1 */ 5879/* File: armv6t2/OP_OR_LONG_2ADDR.S */ 5880/* File: armv6t2/binopWide2addr.S */ 5881 /* 5882 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5883 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5884 * This could be an ARM instruction or a function call. (If the result 5885 * comes back in a register other than r0, you can override "result".) 5886 * 5887 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5888 * vCC (r1). Useful for integer division and modulus. 5889 * 5890 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5891 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5892 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5893 * rem-double/2addr 5894 */ 5895 /* binop/2addr vA, vB */ 5896 mov r1, rINST, lsr #12 @ r1<- B 5897 ubfx r9, rINST, #8, #4 @ r9<- A 5898 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5899 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5900 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5901 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5902 .if 0 5903 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5904 beq common_errDivideByZero 5905 .endif 5906 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5907 5908 orr r0, r0, r2 @ optional op; may set condition codes 5909 orr r1, r1, r3 @ result<- op, r0-r3 changed 5910 GET_INST_OPCODE(ip) @ extract opcode from rINST 5911 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5912 GOTO_OPCODE(ip) @ jump to next instruction 5913 /* 12-15 instructions */ 5914 5915 5916/* ------------------------------ */ 5917 .balign 64 5918.L_OP_XOR_LONG_2ADDR: /* 0xc2 */ 5919/* File: armv6t2/OP_XOR_LONG_2ADDR.S */ 5920/* File: armv6t2/binopWide2addr.S */ 5921 /* 5922 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 5923 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 5924 * This could be an ARM instruction or a function call. (If the result 5925 * comes back in a register other than r0, you can override "result".) 5926 * 5927 * If "chkzero" is set to 1, we perform a divide-by-zero check on 5928 * vCC (r1). Useful for integer division and modulus. 5929 * 5930 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 5931 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 5932 * sub-double/2addr, mul-double/2addr, div-double/2addr, 5933 * rem-double/2addr 5934 */ 5935 /* binop/2addr vA, vB */ 5936 mov r1, rINST, lsr #12 @ r1<- B 5937 ubfx r9, rINST, #8, #4 @ r9<- A 5938 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 5939 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5940 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 5941 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5942 .if 0 5943 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 5944 beq common_errDivideByZero 5945 .endif 5946 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5947 5948 eor r0, r0, r2 @ optional op; may set condition codes 5949 eor r1, r1, r3 @ result<- op, r0-r3 changed 5950 GET_INST_OPCODE(ip) @ extract opcode from rINST 5951 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 5952 GOTO_OPCODE(ip) @ jump to next instruction 5953 /* 12-15 instructions */ 5954 5955 5956/* ------------------------------ */ 5957 .balign 64 5958.L_OP_SHL_LONG_2ADDR: /* 0xc3 */ 5959/* File: armv6t2/OP_SHL_LONG_2ADDR.S */ 5960 /* 5961 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5962 * 32-bit shift distance. 5963 */ 5964 /* shl-long/2addr vA, vB */ 5965 mov r3, rINST, lsr #12 @ r3<- B 5966 ubfx r9, rINST, #8, #4 @ r9<- A 5967 GET_VREG(r2, r3) @ r2<- vB 5968 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5969 and r2, r2, #63 @ r2<- r2 & 0x3f 5970 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5971 5972 mov r1, r1, asl r2 @ r1<- r1 << r2 5973 rsb r3, r2, #32 @ r3<- 32 - r2 5974 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 5975 subs ip, r2, #32 @ ip<- r2 - 32 5976 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 5977 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 5978 mov r0, r0, asl r2 @ r0<- r0 << r2 5979 b .LOP_SHL_LONG_2ADDR_finish 5980 5981/* ------------------------------ */ 5982 .balign 64 5983.L_OP_SHR_LONG_2ADDR: /* 0xc4 */ 5984/* File: armv6t2/OP_SHR_LONG_2ADDR.S */ 5985 /* 5986 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 5987 * 32-bit shift distance. 5988 */ 5989 /* shr-long/2addr vA, vB */ 5990 mov r3, rINST, lsr #12 @ r3<- B 5991 ubfx r9, rINST, #8, #4 @ r9<- A 5992 GET_VREG(r2, r3) @ r2<- vB 5993 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 5994 and r2, r2, #63 @ r2<- r2 & 0x3f 5995 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 5996 5997 mov r0, r0, lsr r2 @ r0<- r2 >> r2 5998 rsb r3, r2, #32 @ r3<- 32 - r2 5999 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 6000 subs ip, r2, #32 @ ip<- r2 - 32 6001 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6002 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 6003 mov r1, r1, asr r2 @ r1<- r1 >> r2 6004 b .LOP_SHR_LONG_2ADDR_finish 6005 6006/* ------------------------------ */ 6007 .balign 64 6008.L_OP_USHR_LONG_2ADDR: /* 0xc5 */ 6009/* File: armv6t2/OP_USHR_LONG_2ADDR.S */ 6010 /* 6011 * Long integer shift, 2addr version. vA is 64-bit value/result, vB is 6012 * 32-bit shift distance. 6013 */ 6014 /* ushr-long/2addr vA, vB */ 6015 mov r3, rINST, lsr #12 @ r3<- B 6016 ubfx r9, rINST, #8, #4 @ r9<- A 6017 GET_VREG(r2, r3) @ r2<- vB 6018 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6019 and r2, r2, #63 @ r2<- r2 & 0x3f 6020 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6021 6022 mov r0, r0, lsr r2 @ r0<- r2 >> r2 6023 rsb r3, r2, #32 @ r3<- 32 - r2 6024 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 6025 subs ip, r2, #32 @ ip<- r2 - 32 6026 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6027 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 6028 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 6029 b .LOP_USHR_LONG_2ADDR_finish 6030 6031/* ------------------------------ */ 6032 .balign 64 6033.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */ 6034/* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */ 6035/* File: arm-vfp/fbinop2addr.S */ 6036 /* 6037 * Generic 32-bit floating point "/2addr" binary operation. Provide 6038 * an "instr" line that specifies an instruction that performs 6039 * "s2 = s0 op s1". 6040 * 6041 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6042 */ 6043 /* binop/2addr vA, vB */ 6044 mov r3, rINST, lsr #12 @ r3<- B 6045 mov r9, rINST, lsr #8 @ r9<- A+ 6046 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6047 and r9, r9, #15 @ r9<- A 6048 flds s1, [r3] @ s1<- vB 6049 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6050 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6051 flds s0, [r9] @ s0<- vA 6052 6053 fadds s2, s0, s1 @ s2<- op 6054 GET_INST_OPCODE(ip) @ extract opcode from rINST 6055 fsts s2, [r9] @ vAA<- s2 6056 GOTO_OPCODE(ip) @ jump to next instruction 6057 6058 6059/* ------------------------------ */ 6060 .balign 64 6061.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */ 6062/* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */ 6063/* File: arm-vfp/fbinop2addr.S */ 6064 /* 6065 * Generic 32-bit floating point "/2addr" binary operation. Provide 6066 * an "instr" line that specifies an instruction that performs 6067 * "s2 = s0 op s1". 6068 * 6069 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6070 */ 6071 /* binop/2addr vA, vB */ 6072 mov r3, rINST, lsr #12 @ r3<- B 6073 mov r9, rINST, lsr #8 @ r9<- A+ 6074 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6075 and r9, r9, #15 @ r9<- A 6076 flds s1, [r3] @ s1<- vB 6077 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6078 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6079 flds s0, [r9] @ s0<- vA 6080 6081 fsubs s2, s0, s1 @ s2<- op 6082 GET_INST_OPCODE(ip) @ extract opcode from rINST 6083 fsts s2, [r9] @ vAA<- s2 6084 GOTO_OPCODE(ip) @ jump to next instruction 6085 6086 6087/* ------------------------------ */ 6088 .balign 64 6089.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */ 6090/* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */ 6091/* File: arm-vfp/fbinop2addr.S */ 6092 /* 6093 * Generic 32-bit floating point "/2addr" binary operation. Provide 6094 * an "instr" line that specifies an instruction that performs 6095 * "s2 = s0 op s1". 6096 * 6097 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6098 */ 6099 /* binop/2addr vA, vB */ 6100 mov r3, rINST, lsr #12 @ r3<- B 6101 mov r9, rINST, lsr #8 @ r9<- A+ 6102 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6103 and r9, r9, #15 @ r9<- A 6104 flds s1, [r3] @ s1<- vB 6105 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6106 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6107 flds s0, [r9] @ s0<- vA 6108 6109 fmuls s2, s0, s1 @ s2<- op 6110 GET_INST_OPCODE(ip) @ extract opcode from rINST 6111 fsts s2, [r9] @ vAA<- s2 6112 GOTO_OPCODE(ip) @ jump to next instruction 6113 6114 6115/* ------------------------------ */ 6116 .balign 64 6117.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */ 6118/* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */ 6119/* File: arm-vfp/fbinop2addr.S */ 6120 /* 6121 * Generic 32-bit floating point "/2addr" binary operation. Provide 6122 * an "instr" line that specifies an instruction that performs 6123 * "s2 = s0 op s1". 6124 * 6125 * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr 6126 */ 6127 /* binop/2addr vA, vB */ 6128 mov r3, rINST, lsr #12 @ r3<- B 6129 mov r9, rINST, lsr #8 @ r9<- A+ 6130 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6131 and r9, r9, #15 @ r9<- A 6132 flds s1, [r3] @ s1<- vB 6133 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6134 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6135 flds s0, [r9] @ s0<- vA 6136 6137 fdivs s2, s0, s1 @ s2<- op 6138 GET_INST_OPCODE(ip) @ extract opcode from rINST 6139 fsts s2, [r9] @ vAA<- s2 6140 GOTO_OPCODE(ip) @ jump to next instruction 6141 6142 6143/* ------------------------------ */ 6144 .balign 64 6145.L_OP_REM_FLOAT_2ADDR: /* 0xca */ 6146/* File: armv6t2/OP_REM_FLOAT_2ADDR.S */ 6147/* EABI doesn't define a float remainder function, but libm does */ 6148/* File: armv6t2/binop2addr.S */ 6149 /* 6150 * Generic 32-bit "/2addr" binary operation. Provide an "instr" line 6151 * that specifies an instruction that performs "result = r0 op r1". 6152 * This could be an ARM instruction or a function call. (If the result 6153 * comes back in a register other than r0, you can override "result".) 6154 * 6155 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6156 * vCC (r1). Useful for integer division and modulus. 6157 * 6158 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr, 6159 * rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr, 6160 * shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr, 6161 * sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr 6162 */ 6163 /* binop/2addr vA, vB */ 6164 mov r3, rINST, lsr #12 @ r3<- B 6165 ubfx r9, rINST, #8, #4 @ r9<- A 6166 GET_VREG(r1, r3) @ r1<- vB 6167 GET_VREG(r0, r9) @ r0<- vA 6168 .if 0 6169 cmp r1, #0 @ is second operand zero? 6170 beq common_errDivideByZero 6171 .endif 6172 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6173 6174 @ optional op; may set condition codes 6175 bl fmodf @ r0<- op, r0-r3 changed 6176 GET_INST_OPCODE(ip) @ extract opcode from rINST 6177 SET_VREG(r0, r9) @ vAA<- r0 6178 GOTO_OPCODE(ip) @ jump to next instruction 6179 /* 10-13 instructions */ 6180 6181 6182/* ------------------------------ */ 6183 .balign 64 6184.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */ 6185/* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */ 6186/* File: arm-vfp/fbinopWide2addr.S */ 6187 /* 6188 * Generic 64-bit floating point "/2addr" binary operation. Provide 6189 * an "instr" line that specifies an instruction that performs 6190 * "d2 = d0 op d1". 6191 * 6192 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6193 * div-double/2addr 6194 */ 6195 /* binop/2addr vA, vB */ 6196 mov r3, rINST, lsr #12 @ r3<- B 6197 mov r9, rINST, lsr #8 @ r9<- A+ 6198 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6199 and r9, r9, #15 @ r9<- A 6200 fldd d1, [r3] @ d1<- vB 6201 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6202 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6203 fldd d0, [r9] @ d0<- vA 6204 6205 faddd d2, d0, d1 @ d2<- op 6206 GET_INST_OPCODE(ip) @ extract opcode from rINST 6207 fstd d2, [r9] @ vAA<- d2 6208 GOTO_OPCODE(ip) @ jump to next instruction 6209 6210 6211/* ------------------------------ */ 6212 .balign 64 6213.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */ 6214/* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */ 6215/* File: arm-vfp/fbinopWide2addr.S */ 6216 /* 6217 * Generic 64-bit floating point "/2addr" binary operation. Provide 6218 * an "instr" line that specifies an instruction that performs 6219 * "d2 = d0 op d1". 6220 * 6221 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6222 * div-double/2addr 6223 */ 6224 /* binop/2addr vA, vB */ 6225 mov r3, rINST, lsr #12 @ r3<- B 6226 mov r9, rINST, lsr #8 @ r9<- A+ 6227 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6228 and r9, r9, #15 @ r9<- A 6229 fldd d1, [r3] @ d1<- vB 6230 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6231 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6232 fldd d0, [r9] @ d0<- vA 6233 6234 fsubd d2, d0, d1 @ d2<- op 6235 GET_INST_OPCODE(ip) @ extract opcode from rINST 6236 fstd d2, [r9] @ vAA<- d2 6237 GOTO_OPCODE(ip) @ jump to next instruction 6238 6239 6240/* ------------------------------ */ 6241 .balign 64 6242.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */ 6243/* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */ 6244/* File: arm-vfp/fbinopWide2addr.S */ 6245 /* 6246 * Generic 64-bit floating point "/2addr" binary operation. Provide 6247 * an "instr" line that specifies an instruction that performs 6248 * "d2 = d0 op d1". 6249 * 6250 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6251 * div-double/2addr 6252 */ 6253 /* binop/2addr vA, vB */ 6254 mov r3, rINST, lsr #12 @ r3<- B 6255 mov r9, rINST, lsr #8 @ r9<- A+ 6256 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6257 and r9, r9, #15 @ r9<- A 6258 fldd d1, [r3] @ d1<- vB 6259 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6260 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6261 fldd d0, [r9] @ d0<- vA 6262 6263 fmuld d2, d0, d1 @ d2<- op 6264 GET_INST_OPCODE(ip) @ extract opcode from rINST 6265 fstd d2, [r9] @ vAA<- d2 6266 GOTO_OPCODE(ip) @ jump to next instruction 6267 6268 6269/* ------------------------------ */ 6270 .balign 64 6271.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */ 6272/* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */ 6273/* File: arm-vfp/fbinopWide2addr.S */ 6274 /* 6275 * Generic 64-bit floating point "/2addr" binary operation. Provide 6276 * an "instr" line that specifies an instruction that performs 6277 * "d2 = d0 op d1". 6278 * 6279 * For: add-double/2addr, sub-double/2addr, mul-double/2addr, 6280 * div-double/2addr 6281 */ 6282 /* binop/2addr vA, vB */ 6283 mov r3, rINST, lsr #12 @ r3<- B 6284 mov r9, rINST, lsr #8 @ r9<- A+ 6285 VREG_INDEX_TO_ADDR(r3, r3) @ r3<- &vB 6286 and r9, r9, #15 @ r9<- A 6287 fldd d1, [r3] @ d1<- vB 6288 VREG_INDEX_TO_ADDR(r9, r9) @ r9<- &vA 6289 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6290 fldd d0, [r9] @ d0<- vA 6291 6292 fdivd d2, d0, d1 @ d2<- op 6293 GET_INST_OPCODE(ip) @ extract opcode from rINST 6294 fstd d2, [r9] @ vAA<- d2 6295 GOTO_OPCODE(ip) @ jump to next instruction 6296 6297 6298/* ------------------------------ */ 6299 .balign 64 6300.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */ 6301/* File: armv6t2/OP_REM_DOUBLE_2ADDR.S */ 6302/* EABI doesn't define a double remainder function, but libm does */ 6303/* File: armv6t2/binopWide2addr.S */ 6304 /* 6305 * Generic 64-bit "/2addr" binary operation. Provide an "instr" line 6306 * that specifies an instruction that performs "result = r0-r1 op r2-r3". 6307 * This could be an ARM instruction or a function call. (If the result 6308 * comes back in a register other than r0, you can override "result".) 6309 * 6310 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6311 * vCC (r1). Useful for integer division and modulus. 6312 * 6313 * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr, 6314 * and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr, 6315 * sub-double/2addr, mul-double/2addr, div-double/2addr, 6316 * rem-double/2addr 6317 */ 6318 /* binop/2addr vA, vB */ 6319 mov r1, rINST, lsr #12 @ r1<- B 6320 ubfx r9, rINST, #8, #4 @ r9<- A 6321 add r1, rFP, r1, lsl #2 @ r1<- &fp[B] 6322 add r9, rFP, r9, lsl #2 @ r9<- &fp[A] 6323 ldmia r1, {r2-r3} @ r2/r3<- vBB/vBB+1 6324 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 6325 .if 0 6326 orrs ip, r2, r3 @ second arg (r2-r3) is zero? 6327 beq common_errDivideByZero 6328 .endif 6329 FETCH_ADVANCE_INST(1) @ advance rPC, load rINST 6330 6331 @ optional op; may set condition codes 6332 bl fmod @ result<- op, r0-r3 changed 6333 GET_INST_OPCODE(ip) @ extract opcode from rINST 6334 stmia r9, {r0,r1} @ vAA/vAA+1<- r0/r1 6335 GOTO_OPCODE(ip) @ jump to next instruction 6336 /* 12-15 instructions */ 6337 6338 6339/* ------------------------------ */ 6340 .balign 64 6341.L_OP_ADD_INT_LIT16: /* 0xd0 */ 6342/* File: armv6t2/OP_ADD_INT_LIT16.S */ 6343/* File: armv6t2/binopLit16.S */ 6344 /* 6345 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6346 * that specifies an instruction that performs "result = r0 op r1". 6347 * This could be an ARM instruction or a function call. (If the result 6348 * comes back in a register other than r0, you can override "result".) 6349 * 6350 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6351 * vCC (r1). Useful for integer division and modulus. 6352 * 6353 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6354 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6355 */ 6356 /* binop/lit16 vA, vB, #+CCCC */ 6357 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6358 mov r2, rINST, lsr #12 @ r2<- B 6359 ubfx r9, rINST, #8, #4 @ r9<- A 6360 GET_VREG(r0, r2) @ r0<- vB 6361 .if 0 6362 cmp r1, #0 @ is second operand zero? 6363 beq common_errDivideByZero 6364 .endif 6365 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6366 6367 add r0, r0, r1 @ r0<- op, r0-r3 changed 6368 GET_INST_OPCODE(ip) @ extract opcode from rINST 6369 SET_VREG(r0, r9) @ vAA<- r0 6370 GOTO_OPCODE(ip) @ jump to next instruction 6371 /* 10-13 instructions */ 6372 6373 6374/* ------------------------------ */ 6375 .balign 64 6376.L_OP_RSUB_INT: /* 0xd1 */ 6377/* File: armv6t2/OP_RSUB_INT.S */ 6378/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */ 6379/* File: armv6t2/binopLit16.S */ 6380 /* 6381 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6382 * that specifies an instruction that performs "result = r0 op r1". 6383 * This could be an ARM instruction or a function call. (If the result 6384 * comes back in a register other than r0, you can override "result".) 6385 * 6386 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6387 * vCC (r1). Useful for integer division and modulus. 6388 * 6389 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6390 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6391 */ 6392 /* binop/lit16 vA, vB, #+CCCC */ 6393 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6394 mov r2, rINST, lsr #12 @ r2<- B 6395 ubfx r9, rINST, #8, #4 @ r9<- A 6396 GET_VREG(r0, r2) @ r0<- vB 6397 .if 0 6398 cmp r1, #0 @ is second operand zero? 6399 beq common_errDivideByZero 6400 .endif 6401 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6402 6403 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6404 GET_INST_OPCODE(ip) @ extract opcode from rINST 6405 SET_VREG(r0, r9) @ vAA<- r0 6406 GOTO_OPCODE(ip) @ jump to next instruction 6407 /* 10-13 instructions */ 6408 6409 6410/* ------------------------------ */ 6411 .balign 64 6412.L_OP_MUL_INT_LIT16: /* 0xd2 */ 6413/* File: armv6t2/OP_MUL_INT_LIT16.S */ 6414/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6415/* File: armv6t2/binopLit16.S */ 6416 /* 6417 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6418 * that specifies an instruction that performs "result = r0 op r1". 6419 * This could be an ARM instruction or a function call. (If the result 6420 * comes back in a register other than r0, you can override "result".) 6421 * 6422 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6423 * vCC (r1). Useful for integer division and modulus. 6424 * 6425 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6426 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6427 */ 6428 /* binop/lit16 vA, vB, #+CCCC */ 6429 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6430 mov r2, rINST, lsr #12 @ r2<- B 6431 ubfx r9, rINST, #8, #4 @ r9<- A 6432 GET_VREG(r0, r2) @ r0<- vB 6433 .if 0 6434 cmp r1, #0 @ is second operand zero? 6435 beq common_errDivideByZero 6436 .endif 6437 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6438 6439 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6440 GET_INST_OPCODE(ip) @ extract opcode from rINST 6441 SET_VREG(r0, r9) @ vAA<- r0 6442 GOTO_OPCODE(ip) @ jump to next instruction 6443 /* 10-13 instructions */ 6444 6445 6446/* ------------------------------ */ 6447 .balign 64 6448.L_OP_DIV_INT_LIT16: /* 0xd3 */ 6449/* File: armv6t2/OP_DIV_INT_LIT16.S */ 6450/* File: armv6t2/binopLit16.S */ 6451 /* 6452 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6453 * that specifies an instruction that performs "result = r0 op r1". 6454 * This could be an ARM instruction or a function call. (If the result 6455 * comes back in a register other than r0, you can override "result".) 6456 * 6457 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6458 * vCC (r1). Useful for integer division and modulus. 6459 * 6460 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6461 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6462 */ 6463 /* binop/lit16 vA, vB, #+CCCC */ 6464 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6465 mov r2, rINST, lsr #12 @ r2<- B 6466 ubfx r9, rINST, #8, #4 @ r9<- A 6467 GET_VREG(r0, r2) @ r0<- vB 6468 .if 1 6469 cmp r1, #0 @ is second operand zero? 6470 beq common_errDivideByZero 6471 .endif 6472 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6473 6474 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6475 GET_INST_OPCODE(ip) @ extract opcode from rINST 6476 SET_VREG(r0, r9) @ vAA<- r0 6477 GOTO_OPCODE(ip) @ jump to next instruction 6478 /* 10-13 instructions */ 6479 6480 6481/* ------------------------------ */ 6482 .balign 64 6483.L_OP_REM_INT_LIT16: /* 0xd4 */ 6484/* File: armv6t2/OP_REM_INT_LIT16.S */ 6485/* idivmod returns quotient in r0 and remainder in r1 */ 6486/* File: armv6t2/binopLit16.S */ 6487 /* 6488 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6489 * that specifies an instruction that performs "result = r0 op r1". 6490 * This could be an ARM instruction or a function call. (If the result 6491 * comes back in a register other than r0, you can override "result".) 6492 * 6493 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6494 * vCC (r1). Useful for integer division and modulus. 6495 * 6496 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6497 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6498 */ 6499 /* binop/lit16 vA, vB, #+CCCC */ 6500 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6501 mov r2, rINST, lsr #12 @ r2<- B 6502 ubfx r9, rINST, #8, #4 @ r9<- A 6503 GET_VREG(r0, r2) @ r0<- vB 6504 .if 1 6505 cmp r1, #0 @ is second operand zero? 6506 beq common_errDivideByZero 6507 .endif 6508 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6509 6510 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6511 GET_INST_OPCODE(ip) @ extract opcode from rINST 6512 SET_VREG(r1, r9) @ vAA<- r1 6513 GOTO_OPCODE(ip) @ jump to next instruction 6514 /* 10-13 instructions */ 6515 6516 6517/* ------------------------------ */ 6518 .balign 64 6519.L_OP_AND_INT_LIT16: /* 0xd5 */ 6520/* File: armv6t2/OP_AND_INT_LIT16.S */ 6521/* File: armv6t2/binopLit16.S */ 6522 /* 6523 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6524 * that specifies an instruction that performs "result = r0 op r1". 6525 * This could be an ARM instruction or a function call. (If the result 6526 * comes back in a register other than r0, you can override "result".) 6527 * 6528 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6529 * vCC (r1). Useful for integer division and modulus. 6530 * 6531 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6532 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6533 */ 6534 /* binop/lit16 vA, vB, #+CCCC */ 6535 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6536 mov r2, rINST, lsr #12 @ r2<- B 6537 ubfx r9, rINST, #8, #4 @ r9<- A 6538 GET_VREG(r0, r2) @ r0<- vB 6539 .if 0 6540 cmp r1, #0 @ is second operand zero? 6541 beq common_errDivideByZero 6542 .endif 6543 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6544 6545 and r0, r0, r1 @ r0<- op, r0-r3 changed 6546 GET_INST_OPCODE(ip) @ extract opcode from rINST 6547 SET_VREG(r0, r9) @ vAA<- r0 6548 GOTO_OPCODE(ip) @ jump to next instruction 6549 /* 10-13 instructions */ 6550 6551 6552/* ------------------------------ */ 6553 .balign 64 6554.L_OP_OR_INT_LIT16: /* 0xd6 */ 6555/* File: armv6t2/OP_OR_INT_LIT16.S */ 6556/* File: armv6t2/binopLit16.S */ 6557 /* 6558 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6559 * that specifies an instruction that performs "result = r0 op r1". 6560 * This could be an ARM instruction or a function call. (If the result 6561 * comes back in a register other than r0, you can override "result".) 6562 * 6563 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6564 * vCC (r1). Useful for integer division and modulus. 6565 * 6566 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6567 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6568 */ 6569 /* binop/lit16 vA, vB, #+CCCC */ 6570 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6571 mov r2, rINST, lsr #12 @ r2<- B 6572 ubfx r9, rINST, #8, #4 @ r9<- A 6573 GET_VREG(r0, r2) @ r0<- vB 6574 .if 0 6575 cmp r1, #0 @ is second operand zero? 6576 beq common_errDivideByZero 6577 .endif 6578 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6579 6580 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6581 GET_INST_OPCODE(ip) @ extract opcode from rINST 6582 SET_VREG(r0, r9) @ vAA<- r0 6583 GOTO_OPCODE(ip) @ jump to next instruction 6584 /* 10-13 instructions */ 6585 6586 6587/* ------------------------------ */ 6588 .balign 64 6589.L_OP_XOR_INT_LIT16: /* 0xd7 */ 6590/* File: armv6t2/OP_XOR_INT_LIT16.S */ 6591/* File: armv6t2/binopLit16.S */ 6592 /* 6593 * Generic 32-bit "lit16" binary operation. Provide an "instr" line 6594 * that specifies an instruction that performs "result = r0 op r1". 6595 * This could be an ARM instruction or a function call. (If the result 6596 * comes back in a register other than r0, you can override "result".) 6597 * 6598 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6599 * vCC (r1). Useful for integer division and modulus. 6600 * 6601 * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16, 6602 * rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16 6603 */ 6604 /* binop/lit16 vA, vB, #+CCCC */ 6605 FETCH_S(r1, 1) @ r1<- ssssCCCC (sign-extended) 6606 mov r2, rINST, lsr #12 @ r2<- B 6607 ubfx r9, rINST, #8, #4 @ r9<- A 6608 GET_VREG(r0, r2) @ r0<- vB 6609 .if 0 6610 cmp r1, #0 @ is second operand zero? 6611 beq common_errDivideByZero 6612 .endif 6613 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6614 6615 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6616 GET_INST_OPCODE(ip) @ extract opcode from rINST 6617 SET_VREG(r0, r9) @ vAA<- r0 6618 GOTO_OPCODE(ip) @ jump to next instruction 6619 /* 10-13 instructions */ 6620 6621 6622/* ------------------------------ */ 6623 .balign 64 6624.L_OP_ADD_INT_LIT8: /* 0xd8 */ 6625/* File: armv5te/OP_ADD_INT_LIT8.S */ 6626/* File: armv5te/binopLit8.S */ 6627 /* 6628 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6629 * that specifies an instruction that performs "result = r0 op r1". 6630 * This could be an ARM instruction or a function call. (If the result 6631 * comes back in a register other than r0, you can override "result".) 6632 * 6633 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6634 * vCC (r1). Useful for integer division and modulus. 6635 * 6636 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6637 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6638 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6639 */ 6640 /* binop/lit8 vAA, vBB, #+CC */ 6641 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6642 mov r9, rINST, lsr #8 @ r9<- AA 6643 and r2, r3, #255 @ r2<- BB 6644 GET_VREG(r0, r2) @ r0<- vBB 6645 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6646 .if 0 6647 @cmp r1, #0 @ is second operand zero? 6648 beq common_errDivideByZero 6649 .endif 6650 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6651 6652 @ optional op; may set condition codes 6653 add r0, r0, r1 @ r0<- op, r0-r3 changed 6654 GET_INST_OPCODE(ip) @ extract opcode from rINST 6655 SET_VREG(r0, r9) @ vAA<- r0 6656 GOTO_OPCODE(ip) @ jump to next instruction 6657 /* 10-12 instructions */ 6658 6659 6660/* ------------------------------ */ 6661 .balign 64 6662.L_OP_RSUB_INT_LIT8: /* 0xd9 */ 6663/* File: armv5te/OP_RSUB_INT_LIT8.S */ 6664/* File: armv5te/binopLit8.S */ 6665 /* 6666 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6667 * that specifies an instruction that performs "result = r0 op r1". 6668 * This could be an ARM instruction or a function call. (If the result 6669 * comes back in a register other than r0, you can override "result".) 6670 * 6671 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6672 * vCC (r1). Useful for integer division and modulus. 6673 * 6674 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6675 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6676 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6677 */ 6678 /* binop/lit8 vAA, vBB, #+CC */ 6679 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6680 mov r9, rINST, lsr #8 @ r9<- AA 6681 and r2, r3, #255 @ r2<- BB 6682 GET_VREG(r0, r2) @ r0<- vBB 6683 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6684 .if 0 6685 @cmp r1, #0 @ is second operand zero? 6686 beq common_errDivideByZero 6687 .endif 6688 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6689 6690 @ optional op; may set condition codes 6691 rsb r0, r0, r1 @ r0<- op, r0-r3 changed 6692 GET_INST_OPCODE(ip) @ extract opcode from rINST 6693 SET_VREG(r0, r9) @ vAA<- r0 6694 GOTO_OPCODE(ip) @ jump to next instruction 6695 /* 10-12 instructions */ 6696 6697 6698/* ------------------------------ */ 6699 .balign 64 6700.L_OP_MUL_INT_LIT8: /* 0xda */ 6701/* File: armv5te/OP_MUL_INT_LIT8.S */ 6702/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */ 6703/* File: armv5te/binopLit8.S */ 6704 /* 6705 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6706 * that specifies an instruction that performs "result = r0 op r1". 6707 * This could be an ARM instruction or a function call. (If the result 6708 * comes back in a register other than r0, you can override "result".) 6709 * 6710 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6711 * vCC (r1). Useful for integer division and modulus. 6712 * 6713 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6714 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6715 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6716 */ 6717 /* binop/lit8 vAA, vBB, #+CC */ 6718 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6719 mov r9, rINST, lsr #8 @ r9<- AA 6720 and r2, r3, #255 @ r2<- BB 6721 GET_VREG(r0, r2) @ r0<- vBB 6722 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6723 .if 0 6724 @cmp r1, #0 @ is second operand zero? 6725 beq common_errDivideByZero 6726 .endif 6727 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6728 6729 @ optional op; may set condition codes 6730 mul r0, r1, r0 @ r0<- op, r0-r3 changed 6731 GET_INST_OPCODE(ip) @ extract opcode from rINST 6732 SET_VREG(r0, r9) @ vAA<- r0 6733 GOTO_OPCODE(ip) @ jump to next instruction 6734 /* 10-12 instructions */ 6735 6736 6737/* ------------------------------ */ 6738 .balign 64 6739.L_OP_DIV_INT_LIT8: /* 0xdb */ 6740/* File: armv5te/OP_DIV_INT_LIT8.S */ 6741/* File: armv5te/binopLit8.S */ 6742 /* 6743 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6744 * that specifies an instruction that performs "result = r0 op r1". 6745 * This could be an ARM instruction or a function call. (If the result 6746 * comes back in a register other than r0, you can override "result".) 6747 * 6748 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6749 * vCC (r1). Useful for integer division and modulus. 6750 * 6751 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6752 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6753 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6754 */ 6755 /* binop/lit8 vAA, vBB, #+CC */ 6756 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6757 mov r9, rINST, lsr #8 @ r9<- AA 6758 and r2, r3, #255 @ r2<- BB 6759 GET_VREG(r0, r2) @ r0<- vBB 6760 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6761 .if 1 6762 @cmp r1, #0 @ is second operand zero? 6763 beq common_errDivideByZero 6764 .endif 6765 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6766 6767 @ optional op; may set condition codes 6768 bl __aeabi_idiv @ r0<- op, r0-r3 changed 6769 GET_INST_OPCODE(ip) @ extract opcode from rINST 6770 SET_VREG(r0, r9) @ vAA<- r0 6771 GOTO_OPCODE(ip) @ jump to next instruction 6772 /* 10-12 instructions */ 6773 6774 6775/* ------------------------------ */ 6776 .balign 64 6777.L_OP_REM_INT_LIT8: /* 0xdc */ 6778/* File: armv5te/OP_REM_INT_LIT8.S */ 6779/* idivmod returns quotient in r0 and remainder in r1 */ 6780/* File: armv5te/binopLit8.S */ 6781 /* 6782 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6783 * that specifies an instruction that performs "result = r0 op r1". 6784 * This could be an ARM instruction or a function call. (If the result 6785 * comes back in a register other than r0, you can override "result".) 6786 * 6787 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6788 * vCC (r1). Useful for integer division and modulus. 6789 * 6790 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6791 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6792 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6793 */ 6794 /* binop/lit8 vAA, vBB, #+CC */ 6795 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6796 mov r9, rINST, lsr #8 @ r9<- AA 6797 and r2, r3, #255 @ r2<- BB 6798 GET_VREG(r0, r2) @ r0<- vBB 6799 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6800 .if 1 6801 @cmp r1, #0 @ is second operand zero? 6802 beq common_errDivideByZero 6803 .endif 6804 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6805 6806 @ optional op; may set condition codes 6807 bl __aeabi_idivmod @ r1<- op, r0-r3 changed 6808 GET_INST_OPCODE(ip) @ extract opcode from rINST 6809 SET_VREG(r1, r9) @ vAA<- r1 6810 GOTO_OPCODE(ip) @ jump to next instruction 6811 /* 10-12 instructions */ 6812 6813 6814/* ------------------------------ */ 6815 .balign 64 6816.L_OP_AND_INT_LIT8: /* 0xdd */ 6817/* File: armv5te/OP_AND_INT_LIT8.S */ 6818/* File: armv5te/binopLit8.S */ 6819 /* 6820 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6821 * that specifies an instruction that performs "result = r0 op r1". 6822 * This could be an ARM instruction or a function call. (If the result 6823 * comes back in a register other than r0, you can override "result".) 6824 * 6825 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6826 * vCC (r1). Useful for integer division and modulus. 6827 * 6828 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6829 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6830 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6831 */ 6832 /* binop/lit8 vAA, vBB, #+CC */ 6833 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6834 mov r9, rINST, lsr #8 @ r9<- AA 6835 and r2, r3, #255 @ r2<- BB 6836 GET_VREG(r0, r2) @ r0<- vBB 6837 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6838 .if 0 6839 @cmp r1, #0 @ is second operand zero? 6840 beq common_errDivideByZero 6841 .endif 6842 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6843 6844 @ optional op; may set condition codes 6845 and r0, r0, r1 @ r0<- op, r0-r3 changed 6846 GET_INST_OPCODE(ip) @ extract opcode from rINST 6847 SET_VREG(r0, r9) @ vAA<- r0 6848 GOTO_OPCODE(ip) @ jump to next instruction 6849 /* 10-12 instructions */ 6850 6851 6852/* ------------------------------ */ 6853 .balign 64 6854.L_OP_OR_INT_LIT8: /* 0xde */ 6855/* File: armv5te/OP_OR_INT_LIT8.S */ 6856/* File: armv5te/binopLit8.S */ 6857 /* 6858 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6859 * that specifies an instruction that performs "result = r0 op r1". 6860 * This could be an ARM instruction or a function call. (If the result 6861 * comes back in a register other than r0, you can override "result".) 6862 * 6863 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6864 * vCC (r1). Useful for integer division and modulus. 6865 * 6866 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6867 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6868 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6869 */ 6870 /* binop/lit8 vAA, vBB, #+CC */ 6871 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6872 mov r9, rINST, lsr #8 @ r9<- AA 6873 and r2, r3, #255 @ r2<- BB 6874 GET_VREG(r0, r2) @ r0<- vBB 6875 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6876 .if 0 6877 @cmp r1, #0 @ is second operand zero? 6878 beq common_errDivideByZero 6879 .endif 6880 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6881 6882 @ optional op; may set condition codes 6883 orr r0, r0, r1 @ r0<- op, r0-r3 changed 6884 GET_INST_OPCODE(ip) @ extract opcode from rINST 6885 SET_VREG(r0, r9) @ vAA<- r0 6886 GOTO_OPCODE(ip) @ jump to next instruction 6887 /* 10-12 instructions */ 6888 6889 6890/* ------------------------------ */ 6891 .balign 64 6892.L_OP_XOR_INT_LIT8: /* 0xdf */ 6893/* File: armv5te/OP_XOR_INT_LIT8.S */ 6894/* File: armv5te/binopLit8.S */ 6895 /* 6896 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6897 * that specifies an instruction that performs "result = r0 op r1". 6898 * This could be an ARM instruction or a function call. (If the result 6899 * comes back in a register other than r0, you can override "result".) 6900 * 6901 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6902 * vCC (r1). Useful for integer division and modulus. 6903 * 6904 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6905 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6906 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6907 */ 6908 /* binop/lit8 vAA, vBB, #+CC */ 6909 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6910 mov r9, rINST, lsr #8 @ r9<- AA 6911 and r2, r3, #255 @ r2<- BB 6912 GET_VREG(r0, r2) @ r0<- vBB 6913 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6914 .if 0 6915 @cmp r1, #0 @ is second operand zero? 6916 beq common_errDivideByZero 6917 .endif 6918 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6919 6920 @ optional op; may set condition codes 6921 eor r0, r0, r1 @ r0<- op, r0-r3 changed 6922 GET_INST_OPCODE(ip) @ extract opcode from rINST 6923 SET_VREG(r0, r9) @ vAA<- r0 6924 GOTO_OPCODE(ip) @ jump to next instruction 6925 /* 10-12 instructions */ 6926 6927 6928/* ------------------------------ */ 6929 .balign 64 6930.L_OP_SHL_INT_LIT8: /* 0xe0 */ 6931/* File: armv5te/OP_SHL_INT_LIT8.S */ 6932/* File: armv5te/binopLit8.S */ 6933 /* 6934 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6935 * that specifies an instruction that performs "result = r0 op r1". 6936 * This could be an ARM instruction or a function call. (If the result 6937 * comes back in a register other than r0, you can override "result".) 6938 * 6939 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6940 * vCC (r1). Useful for integer division and modulus. 6941 * 6942 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6943 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6944 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6945 */ 6946 /* binop/lit8 vAA, vBB, #+CC */ 6947 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6948 mov r9, rINST, lsr #8 @ r9<- AA 6949 and r2, r3, #255 @ r2<- BB 6950 GET_VREG(r0, r2) @ r0<- vBB 6951 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6952 .if 0 6953 @cmp r1, #0 @ is second operand zero? 6954 beq common_errDivideByZero 6955 .endif 6956 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6957 6958 and r1, r1, #31 @ optional op; may set condition codes 6959 mov r0, r0, asl r1 @ r0<- op, r0-r3 changed 6960 GET_INST_OPCODE(ip) @ extract opcode from rINST 6961 SET_VREG(r0, r9) @ vAA<- r0 6962 GOTO_OPCODE(ip) @ jump to next instruction 6963 /* 10-12 instructions */ 6964 6965 6966/* ------------------------------ */ 6967 .balign 64 6968.L_OP_SHR_INT_LIT8: /* 0xe1 */ 6969/* File: armv5te/OP_SHR_INT_LIT8.S */ 6970/* File: armv5te/binopLit8.S */ 6971 /* 6972 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 6973 * that specifies an instruction that performs "result = r0 op r1". 6974 * This could be an ARM instruction or a function call. (If the result 6975 * comes back in a register other than r0, you can override "result".) 6976 * 6977 * If "chkzero" is set to 1, we perform a divide-by-zero check on 6978 * vCC (r1). Useful for integer division and modulus. 6979 * 6980 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 6981 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 6982 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 6983 */ 6984 /* binop/lit8 vAA, vBB, #+CC */ 6985 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 6986 mov r9, rINST, lsr #8 @ r9<- AA 6987 and r2, r3, #255 @ r2<- BB 6988 GET_VREG(r0, r2) @ r0<- vBB 6989 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 6990 .if 0 6991 @cmp r1, #0 @ is second operand zero? 6992 beq common_errDivideByZero 6993 .endif 6994 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 6995 6996 and r1, r1, #31 @ optional op; may set condition codes 6997 mov r0, r0, asr r1 @ r0<- op, r0-r3 changed 6998 GET_INST_OPCODE(ip) @ extract opcode from rINST 6999 SET_VREG(r0, r9) @ vAA<- r0 7000 GOTO_OPCODE(ip) @ jump to next instruction 7001 /* 10-12 instructions */ 7002 7003 7004/* ------------------------------ */ 7005 .balign 64 7006.L_OP_USHR_INT_LIT8: /* 0xe2 */ 7007/* File: armv5te/OP_USHR_INT_LIT8.S */ 7008/* File: armv5te/binopLit8.S */ 7009 /* 7010 * Generic 32-bit "lit8" binary operation. Provide an "instr" line 7011 * that specifies an instruction that performs "result = r0 op r1". 7012 * This could be an ARM instruction or a function call. (If the result 7013 * comes back in a register other than r0, you can override "result".) 7014 * 7015 * If "chkzero" is set to 1, we perform a divide-by-zero check on 7016 * vCC (r1). Useful for integer division and modulus. 7017 * 7018 * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8, 7019 * rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8, 7020 * shl-int/lit8, shr-int/lit8, ushr-int/lit8 7021 */ 7022 /* binop/lit8 vAA, vBB, #+CC */ 7023 FETCH_S(r3, 1) @ r3<- ssssCCBB (sign-extended for CC) 7024 mov r9, rINST, lsr #8 @ r9<- AA 7025 and r2, r3, #255 @ r2<- BB 7026 GET_VREG(r0, r2) @ r0<- vBB 7027 movs r1, r3, asr #8 @ r1<- ssssssCC (sign extended) 7028 .if 0 7029 @cmp r1, #0 @ is second operand zero? 7030 beq common_errDivideByZero 7031 .endif 7032 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7033 7034 and r1, r1, #31 @ optional op; may set condition codes 7035 mov r0, r0, lsr r1 @ r0<- op, r0-r3 changed 7036 GET_INST_OPCODE(ip) @ extract opcode from rINST 7037 SET_VREG(r0, r9) @ vAA<- r0 7038 GOTO_OPCODE(ip) @ jump to next instruction 7039 /* 10-12 instructions */ 7040 7041 7042/* ------------------------------ */ 7043 .balign 64 7044.L_OP_IGET_VOLATILE: /* 0xe3 */ 7045/* File: armv5te/OP_IGET_VOLATILE.S */ 7046/* File: armv5te/OP_IGET.S */ 7047 /* 7048 * General 32-bit instance field get. 7049 * 7050 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7051 */ 7052 /* op vA, vB, field@CCCC */ 7053 mov r0, rINST, lsr #12 @ r0<- B 7054 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7055 FETCH(r1, 1) @ r1<- field ref CCCC 7056 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7057 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7058 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7059 cmp r0, #0 @ is resolved entry null? 7060 bne .LOP_IGET_VOLATILE_finish @ no, already resolved 70618: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7062 EXPORT_PC() @ resolve() could throw 7063 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7064 bl dvmResolveInstField @ r0<- resolved InstField ptr 7065 cmp r0, #0 7066 bne .LOP_IGET_VOLATILE_finish 7067 b common_exceptionThrown 7068 7069 7070/* ------------------------------ */ 7071 .balign 64 7072.L_OP_IPUT_VOLATILE: /* 0xe4 */ 7073/* File: armv5te/OP_IPUT_VOLATILE.S */ 7074/* File: armv5te/OP_IPUT.S */ 7075 /* 7076 * General 32-bit instance field put. 7077 * 7078 * for: iput, iput-boolean, iput-byte, iput-char, iput-short 7079 */ 7080 /* op vA, vB, field@CCCC */ 7081 mov r0, rINST, lsr #12 @ r0<- B 7082 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7083 FETCH(r1, 1) @ r1<- field ref CCCC 7084 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7085 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7086 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7087 cmp r0, #0 @ is resolved entry null? 7088 bne .LOP_IPUT_VOLATILE_finish @ no, already resolved 70898: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7090 EXPORT_PC() @ resolve() could throw 7091 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7092 bl dvmResolveInstField @ r0<- resolved InstField ptr 7093 cmp r0, #0 @ success? 7094 bne .LOP_IPUT_VOLATILE_finish @ yes, finish up 7095 b common_exceptionThrown 7096 7097 7098/* ------------------------------ */ 7099 .balign 64 7100.L_OP_SGET_VOLATILE: /* 0xe5 */ 7101/* File: armv5te/OP_SGET_VOLATILE.S */ 7102/* File: armv5te/OP_SGET.S */ 7103 /* 7104 * General 32-bit SGET handler. 7105 * 7106 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7107 */ 7108 /* op vAA, field@BBBB */ 7109 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7110 FETCH(r1, 1) @ r1<- field ref BBBB 7111 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7112 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7113 cmp r0, #0 @ is resolved entry null? 7114 beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve 7115.LOP_SGET_VOLATILE_finish: @ field ptr in r0 7116 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7117 SMP_DMB @ acquiring load 7118 mov r2, rINST, lsr #8 @ r2<- AA 7119 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7120 SET_VREG(r1, r2) @ fp[AA]<- r1 7121 GET_INST_OPCODE(ip) @ extract opcode from rINST 7122 GOTO_OPCODE(ip) @ jump to next instruction 7123 7124 7125/* ------------------------------ */ 7126 .balign 64 7127.L_OP_SPUT_VOLATILE: /* 0xe6 */ 7128/* File: armv5te/OP_SPUT_VOLATILE.S */ 7129/* File: armv5te/OP_SPUT.S */ 7130 /* 7131 * General 32-bit SPUT handler. 7132 * 7133 * for: sput, sput-boolean, sput-byte, sput-char, sput-short 7134 */ 7135 /* op vAA, field@BBBB */ 7136 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7137 FETCH(r1, 1) @ r1<- field ref BBBB 7138 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7139 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7140 cmp r0, #0 @ is resolved entry null? 7141 beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve 7142.LOP_SPUT_VOLATILE_finish: @ field ptr in r0 7143 mov r2, rINST, lsr #8 @ r2<- AA 7144 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7145 GET_VREG(r1, r2) @ r1<- fp[AA] 7146 GET_INST_OPCODE(ip) @ extract opcode from rINST 7147 SMP_DMB @ releasing store 7148 str r1, [r0, #offStaticField_value] @ field<- vAA 7149 GOTO_OPCODE(ip) @ jump to next instruction 7150 7151 7152/* ------------------------------ */ 7153 .balign 64 7154.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */ 7155/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */ 7156/* File: armv5te/OP_IGET.S */ 7157 /* 7158 * General 32-bit instance field get. 7159 * 7160 * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short 7161 */ 7162 /* op vA, vB, field@CCCC */ 7163 mov r0, rINST, lsr #12 @ r0<- B 7164 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7165 FETCH(r1, 1) @ r1<- field ref CCCC 7166 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7167 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7168 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7169 cmp r0, #0 @ is resolved entry null? 7170 bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved 71718: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7172 EXPORT_PC() @ resolve() could throw 7173 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7174 bl dvmResolveInstField @ r0<- resolved InstField ptr 7175 cmp r0, #0 7176 bne .LOP_IGET_OBJECT_VOLATILE_finish 7177 b common_exceptionThrown 7178 7179 7180/* ------------------------------ */ 7181 .balign 64 7182.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */ 7183/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */ 7184/* File: armv5te/OP_IGET_WIDE.S */ 7185 /* 7186 * Wide 32-bit instance field get. 7187 */ 7188 /* iget-wide vA, vB, field@CCCC */ 7189 mov r0, rINST, lsr #12 @ r0<- B 7190 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7191 FETCH(r1, 1) @ r1<- field ref CCCC 7192 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7193 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7194 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7195 cmp r0, #0 @ is resolved entry null? 7196 bne .LOP_IGET_WIDE_VOLATILE_finish @ no, already resolved 71978: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7198 EXPORT_PC() @ resolve() could throw 7199 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7200 bl dvmResolveInstField @ r0<- resolved InstField ptr 7201 cmp r0, #0 7202 bne .LOP_IGET_WIDE_VOLATILE_finish 7203 b common_exceptionThrown 7204 7205 7206/* ------------------------------ */ 7207 .balign 64 7208.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */ 7209/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */ 7210/* File: armv5te/OP_IPUT_WIDE.S */ 7211 /* iput-wide vA, vB, field@CCCC */ 7212 mov r0, rINST, lsr #12 @ r0<- B 7213 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7214 FETCH(r1, 1) @ r1<- field ref CCCC 7215 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7216 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7217 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7218 cmp r0, #0 @ is resolved entry null? 7219 bne .LOP_IPUT_WIDE_VOLATILE_finish @ no, already resolved 72208: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7221 EXPORT_PC() @ resolve() could throw 7222 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7223 bl dvmResolveInstField @ r0<- resolved InstField ptr 7224 cmp r0, #0 @ success? 7225 bne .LOP_IPUT_WIDE_VOLATILE_finish @ yes, finish up 7226 b common_exceptionThrown 7227 7228 7229/* ------------------------------ */ 7230 .balign 64 7231.L_OP_SGET_WIDE_VOLATILE: /* 0xea */ 7232/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */ 7233/* File: armv5te/OP_SGET_WIDE.S */ 7234 /* 7235 * 64-bit SGET handler. 7236 */ 7237 /* sget-wide vAA, field@BBBB */ 7238 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7239 FETCH(r1, 1) @ r1<- field ref BBBB 7240 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7241 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7242 cmp r0, #0 @ is resolved entry null? 7243 beq .LOP_SGET_WIDE_VOLATILE_resolve @ yes, do resolve 7244.LOP_SGET_WIDE_VOLATILE_finish: 7245 mov r9, rINST, lsr #8 @ r9<- AA 7246 .if 1 7247 add r0, r0, #offStaticField_value @ r0<- pointer to data 7248 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 7249 .else 7250 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 7251 .endif 7252 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7253 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7254 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 7255 GET_INST_OPCODE(ip) @ extract opcode from rINST 7256 GOTO_OPCODE(ip) @ jump to next instruction 7257 7258 7259/* ------------------------------ */ 7260 .balign 64 7261.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */ 7262/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */ 7263/* File: armv5te/OP_SPUT_WIDE.S */ 7264 /* 7265 * 64-bit SPUT handler. 7266 */ 7267 /* sput-wide vAA, field@BBBB */ 7268 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- DvmDex 7269 FETCH(r1, 1) @ r1<- field ref BBBB 7270 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 7271 mov r9, rINST, lsr #8 @ r9<- AA 7272 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 7273 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 7274 cmp r2, #0 @ is resolved entry null? 7275 beq .LOP_SPUT_WIDE_VOLATILE_resolve @ yes, do resolve 7276.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9 7277 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7278 ldmia r9, {r0-r1} @ r0/r1<- vAA/vAA+1 7279 GET_INST_OPCODE(r10) @ extract opcode from rINST 7280 .if 1 7281 add r2, r2, #offStaticField_value @ r2<- pointer to data 7282 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 7283 .else 7284 strd r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1 7285 .endif 7286 GOTO_OPCODE(r10) @ jump to next instruction 7287 7288 7289/* ------------------------------ */ 7290 .balign 64 7291.L_OP_BREAKPOINT: /* 0xec */ 7292/* File: armv5te/OP_BREAKPOINT.S */ 7293/* File: armv5te/unused.S */ 7294 bl common_abort 7295 7296 7297/* ------------------------------ */ 7298 .balign 64 7299.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */ 7300/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */ 7301 /* 7302 * Handle a throw-verification-error instruction. This throws an 7303 * exception for an error discovered during verification. The 7304 * exception is indicated by AA, with some detail provided by BBBB. 7305 */ 7306 /* op AA, ref@BBBB */ 7307 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 7308 FETCH(r2, 1) @ r2<- BBBB 7309 EXPORT_PC() @ export the PC 7310 mov r1, rINST, lsr #8 @ r1<- AA 7311 bl dvmThrowVerificationError @ always throws 7312 b common_exceptionThrown @ handle exception 7313 7314/* ------------------------------ */ 7315 .balign 64 7316.L_OP_EXECUTE_INLINE: /* 0xee */ 7317/* File: armv5te/OP_EXECUTE_INLINE.S */ 7318 /* 7319 * Execute a "native inline" instruction. 7320 * 7321 * We need to call an InlineOp4Func: 7322 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7323 * 7324 * The first four args are in r0-r3, pointer to return value storage 7325 * is on the stack. The function's return value is a flag that tells 7326 * us if an exception was thrown. 7327 */ 7328 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 7329 FETCH(r10, 1) @ r10<- BBBB 7330 add r1, rGLUE, #offGlue_retval @ r1<- &glue->retval 7331 EXPORT_PC() @ can throw 7332 sub sp, sp, #8 @ make room for arg, +64 bit align 7333 mov r0, rINST, lsr #12 @ r0<- B 7334 str r1, [sp] @ push &glue->retval 7335 bl .LOP_EXECUTE_INLINE_continue @ make call; will return after 7336 add sp, sp, #8 @ pop stack 7337 cmp r0, #0 @ test boolean result of inline 7338 beq common_exceptionThrown @ returned false, handle exception 7339 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7340 GET_INST_OPCODE(ip) @ extract opcode from rINST 7341 GOTO_OPCODE(ip) @ jump to next instruction 7342 7343/* ------------------------------ */ 7344 .balign 64 7345.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */ 7346/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */ 7347 /* 7348 * Execute a "native inline" instruction, using "/range" semantics. 7349 * Same idea as execute-inline, but we get the args differently. 7350 * 7351 * We need to call an InlineOp4Func: 7352 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 7353 * 7354 * The first four args are in r0-r3, pointer to return value storage 7355 * is on the stack. The function's return value is a flag that tells 7356 * us if an exception was thrown. 7357 */ 7358 /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */ 7359 FETCH(r10, 1) @ r10<- BBBB 7360 add r1, rGLUE, #offGlue_retval @ r1<- &glue->retval 7361 EXPORT_PC() @ can throw 7362 sub sp, sp, #8 @ make room for arg, +64 bit align 7363 mov r0, rINST, lsr #8 @ r0<- AA 7364 str r1, [sp] @ push &glue->retval 7365 bl .LOP_EXECUTE_INLINE_RANGE_continue @ make call; will return after 7366 add sp, sp, #8 @ pop stack 7367 cmp r0, #0 @ test boolean result of inline 7368 beq common_exceptionThrown @ returned false, handle exception 7369 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 7370 GET_INST_OPCODE(ip) @ extract opcode from rINST 7371 GOTO_OPCODE(ip) @ jump to next instruction 7372 7373/* ------------------------------ */ 7374 .balign 64 7375.L_OP_INVOKE_DIRECT_EMPTY: /* 0xf0 */ 7376/* File: armv5te/OP_INVOKE_DIRECT_EMPTY.S */ 7377 /* 7378 * invoke-direct-empty is a no-op in a "standard" interpreter. 7379 */ 7380 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 7381 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 7382 GOTO_OPCODE(ip) @ execute it 7383 7384/* ------------------------------ */ 7385 .balign 64 7386.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */ 7387/* File: armv5te/OP_RETURN_VOID_BARRIER.S */ 7388 SMP_DMB_ST 7389 b common_returnFromMethod 7390 7391/* ------------------------------ */ 7392 .balign 64 7393.L_OP_IGET_QUICK: /* 0xf2 */ 7394/* File: armv6t2/OP_IGET_QUICK.S */ 7395 /* For: iget-quick, iget-object-quick */ 7396 /* op vA, vB, offset@CCCC */ 7397 mov r2, rINST, lsr #12 @ r2<- B 7398 FETCH(r1, 1) @ r1<- field byte offset 7399 GET_VREG(r3, r2) @ r3<- object we're operating on 7400 ubfx r2, rINST, #8, #4 @ r2<- A 7401 cmp r3, #0 @ check object for null 7402 beq common_errNullObject @ object was null 7403 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7404 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7405 GET_INST_OPCODE(ip) @ extract opcode from rINST 7406 SET_VREG(r0, r2) @ fp[A]<- r0 7407 GOTO_OPCODE(ip) @ jump to next instruction 7408 7409/* ------------------------------ */ 7410 .balign 64 7411.L_OP_IGET_WIDE_QUICK: /* 0xf3 */ 7412/* File: armv6t2/OP_IGET_WIDE_QUICK.S */ 7413 /* iget-wide-quick vA, vB, offset@CCCC */ 7414 mov r2, rINST, lsr #12 @ r2<- B 7415 FETCH(ip, 1) @ ip<- field byte offset 7416 GET_VREG(r3, r2) @ r3<- object we're operating on 7417 ubfx r2, rINST, #8, #4 @ r2<- A 7418 cmp r3, #0 @ check object for null 7419 beq common_errNullObject @ object was null 7420 ldrd r0, [r3, ip] @ r0<- obj.field (64 bits, aligned) 7421 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7422 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 7423 GET_INST_OPCODE(ip) @ extract opcode from rINST 7424 stmia r3, {r0-r1} @ fp[A]<- r0/r1 7425 GOTO_OPCODE(ip) @ jump to next instruction 7426 7427/* ------------------------------ */ 7428 .balign 64 7429.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */ 7430/* File: armv5te/OP_IGET_OBJECT_QUICK.S */ 7431/* File: armv5te/OP_IGET_QUICK.S */ 7432 /* For: iget-quick, iget-object-quick */ 7433 /* op vA, vB, offset@CCCC */ 7434 mov r2, rINST, lsr #12 @ r2<- B 7435 GET_VREG(r3, r2) @ r3<- object we're operating on 7436 FETCH(r1, 1) @ r1<- field byte offset 7437 cmp r3, #0 @ check object for null 7438 mov r2, rINST, lsr #8 @ r2<- A(+) 7439 beq common_errNullObject @ object was null 7440 ldr r0, [r3, r1] @ r0<- obj.field (always 32 bits) 7441 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7442 and r2, r2, #15 7443 GET_INST_OPCODE(ip) @ extract opcode from rINST 7444 SET_VREG(r0, r2) @ fp[A]<- r0 7445 GOTO_OPCODE(ip) @ jump to next instruction 7446 7447 7448/* ------------------------------ */ 7449 .balign 64 7450.L_OP_IPUT_QUICK: /* 0xf5 */ 7451/* File: armv6t2/OP_IPUT_QUICK.S */ 7452 /* For: iput-quick, iput-object-quick */ 7453 /* op vA, vB, offset@CCCC */ 7454 mov r2, rINST, lsr #12 @ r2<- B 7455 FETCH(r1, 1) @ r1<- field byte offset 7456 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7457 ubfx r2, rINST, #8, #4 @ r2<- A 7458 cmp r3, #0 @ check object for null 7459 beq common_errNullObject @ object was null 7460 GET_VREG(r0, r2) @ r0<- fp[A] 7461 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7462 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7463 GET_INST_OPCODE(ip) @ extract opcode from rINST 7464 GOTO_OPCODE(ip) @ jump to next instruction 7465 7466/* ------------------------------ */ 7467 .balign 64 7468.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */ 7469/* File: armv6t2/OP_IPUT_WIDE_QUICK.S */ 7470 /* iput-wide-quick vA, vB, offset@CCCC */ 7471 mov r1, rINST, lsr #12 @ r1<- B 7472 ubfx r0, rINST, #8, #4 @ r0<- A 7473 GET_VREG(r2, r1) @ r2<- fp[B], the object pointer 7474 add r3, rFP, r0, lsl #2 @ r3<- &fp[A] 7475 cmp r2, #0 @ check object for null 7476 ldmia r3, {r0-r1} @ r0/r1<- fp[A] 7477 beq common_errNullObject @ object was null 7478 FETCH(r3, 1) @ r3<- field byte offset 7479 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7480 strd r0, [r2, r3] @ obj.field (64 bits, aligned)<- r0/r1 7481 GET_INST_OPCODE(ip) @ extract opcode from rINST 7482 GOTO_OPCODE(ip) @ jump to next instruction 7483 7484/* ------------------------------ */ 7485 .balign 64 7486.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */ 7487/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */ 7488 /* For: iput-object-quick */ 7489 /* op vA, vB, offset@CCCC */ 7490 mov r2, rINST, lsr #12 @ r2<- B 7491 GET_VREG(r3, r2) @ r3<- fp[B], the object pointer 7492 FETCH(r1, 1) @ r1<- field byte offset 7493 cmp r3, #0 @ check object for null 7494 mov r2, rINST, lsr #8 @ r2<- A(+) 7495 beq common_errNullObject @ object was null 7496 and r2, r2, #15 7497 GET_VREG(r0, r2) @ r0<- fp[A] 7498 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 7499 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7500 str r0, [r3, r1] @ obj.field (always 32 bits)<- r0 7501 cmp r0, #0 7502 strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head 7503 GET_INST_OPCODE(ip) @ extract opcode from rINST 7504 GOTO_OPCODE(ip) @ jump to next instruction 7505 7506/* ------------------------------ */ 7507 .balign 64 7508.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */ 7509/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7510 /* 7511 * Handle an optimized virtual method call. 7512 * 7513 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7514 */ 7515 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7516 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7517 FETCH(r3, 2) @ r3<- FEDC or CCCC 7518 FETCH(r1, 1) @ r1<- BBBB 7519 .if (!0) 7520 and r3, r3, #15 @ r3<- C (or stays CCCC) 7521 .endif 7522 GET_VREG(r2, r3) @ r2<- vC ("this" ptr) 7523 cmp r2, #0 @ is "this" null? 7524 beq common_errNullObject @ null "this", throw exception 7525 ldr r2, [r2, #offObject_clazz] @ r2<- thisPtr->clazz 7526 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7527 EXPORT_PC() @ invoke must export 7528 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7529 bl common_invokeMethodNoRange @ continue on 7530 7531/* ------------------------------ */ 7532 .balign 64 7533.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */ 7534/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */ 7535/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */ 7536 /* 7537 * Handle an optimized virtual method call. 7538 * 7539 * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range 7540 */ 7541 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7542 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7543 FETCH(r3, 2) @ r3<- FEDC or CCCC 7544 FETCH(r1, 1) @ r1<- BBBB 7545 .if (!1) 7546 and r3, r3, #15 @ r3<- C (or stays CCCC) 7547 .endif 7548 GET_VREG(r2, r3) @ r2<- vC ("this" ptr) 7549 cmp r2, #0 @ is "this" null? 7550 beq common_errNullObject @ null "this", throw exception 7551 ldr r2, [r2, #offObject_clazz] @ r2<- thisPtr->clazz 7552 ldr r2, [r2, #offClassObject_vtable] @ r2<- thisPtr->clazz->vtable 7553 EXPORT_PC() @ invoke must export 7554 ldr r0, [r2, r1, lsl #2] @ r3<- vtable[BBBB] 7555 bl common_invokeMethodRange @ continue on 7556 7557 7558/* ------------------------------ */ 7559 .balign 64 7560.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */ 7561/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7562 /* 7563 * Handle an optimized "super" method call. 7564 * 7565 * for: [opt] invoke-super-quick, invoke-super-quick/range 7566 */ 7567 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7568 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7569 FETCH(r10, 2) @ r10<- GFED or CCCC 7570 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7571 .if (!0) 7572 and r10, r10, #15 @ r10<- D (or stays CCCC) 7573 .endif 7574 FETCH(r1, 1) @ r1<- BBBB 7575 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7576 EXPORT_PC() @ must export for invoke 7577 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7578 GET_VREG(r3, r10) @ r3<- "this" 7579 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7580 cmp r3, #0 @ null "this" ref? 7581 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7582 beq common_errNullObject @ "this" is null, throw exception 7583 bl common_invokeMethodNoRange @ continue on 7584 7585/* ------------------------------ */ 7586 .balign 64 7587.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */ 7588/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */ 7589/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */ 7590 /* 7591 * Handle an optimized "super" method call. 7592 * 7593 * for: [opt] invoke-super-quick, invoke-super-quick/range 7594 */ 7595 /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */ 7596 /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */ 7597 FETCH(r10, 2) @ r10<- GFED or CCCC 7598 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7599 .if (!1) 7600 and r10, r10, #15 @ r10<- D (or stays CCCC) 7601 .endif 7602 FETCH(r1, 1) @ r1<- BBBB 7603 ldr r2, [r2, #offMethod_clazz] @ r2<- method->clazz 7604 EXPORT_PC() @ must export for invoke 7605 ldr r2, [r2, #offClassObject_super] @ r2<- method->clazz->super 7606 GET_VREG(r3, r10) @ r3<- "this" 7607 ldr r2, [r2, #offClassObject_vtable] @ r2<- ...clazz->super->vtable 7608 cmp r3, #0 @ null "this" ref? 7609 ldr r0, [r2, r1, lsl #2] @ r0<- super->vtable[BBBB] 7610 beq common_errNullObject @ "this" is null, throw exception 7611 bl common_invokeMethodRange @ continue on 7612 7613 7614/* ------------------------------ */ 7615 .balign 64 7616.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */ 7617/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */ 7618/* File: armv5te/OP_IPUT_OBJECT.S */ 7619 /* 7620 * 32-bit instance field put. 7621 * 7622 * for: iput-object, iput-object-volatile 7623 */ 7624 /* op vA, vB, field@CCCC */ 7625 mov r0, rINST, lsr #12 @ r0<- B 7626 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7627 FETCH(r1, 1) @ r1<- field ref CCCC 7628 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7629 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 7630 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7631 cmp r0, #0 @ is resolved entry null? 7632 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved 76338: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7634 EXPORT_PC() @ resolve() could throw 7635 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7636 bl dvmResolveInstField @ r0<- resolved InstField ptr 7637 cmp r0, #0 @ success? 7638 bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up 7639 b common_exceptionThrown 7640 7641 7642/* ------------------------------ */ 7643 .balign 64 7644.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */ 7645/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */ 7646/* File: armv5te/OP_SGET.S */ 7647 /* 7648 * General 32-bit SGET handler. 7649 * 7650 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short 7651 */ 7652 /* op vAA, field@BBBB */ 7653 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7654 FETCH(r1, 1) @ r1<- field ref BBBB 7655 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7656 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7657 cmp r0, #0 @ is resolved entry null? 7658 beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve 7659.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0 7660 ldr r1, [r0, #offStaticField_value] @ r1<- field value 7661 SMP_DMB @ acquiring load 7662 mov r2, rINST, lsr #8 @ r2<- AA 7663 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 7664 SET_VREG(r1, r2) @ fp[AA]<- r1 7665 GET_INST_OPCODE(ip) @ extract opcode from rINST 7666 GOTO_OPCODE(ip) @ jump to next instruction 7667 7668 7669/* ------------------------------ */ 7670 .balign 64 7671.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */ 7672/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */ 7673/* File: armv5te/OP_SPUT_OBJECT.S */ 7674 /* 7675 * 32-bit SPUT handler for objects 7676 * 7677 * for: sput-object, sput-object-volatile 7678 */ 7679 /* op vAA, field@BBBB */ 7680 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 7681 FETCH(r1, 1) @ r1<- field ref BBBB 7682 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 7683 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 7684 cmp r0, #0 @ is resolved entry null? 7685 bne .LOP_SPUT_OBJECT_VOLATILE_finish @ no, continue 7686 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 7687 EXPORT_PC() @ resolve() could throw, so export now 7688 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 7689 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 7690 cmp r0, #0 @ success? 7691 bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish 7692 b common_exceptionThrown @ no, handle exception 7693 7694 7695 7696/* ------------------------------ */ 7697 .balign 64 7698.L_OP_DISPATCH_FF: /* 0xff */ 7699/* File: armv5te/OP_DISPATCH_FF.S */ 7700 mov ip, rINST, lsr #8 @ r9<- extended opcode 7701 add ip, ip, #256 @ add offset for extended opcodes 7702 GOTO_OPCODE(ip) @ go to proper extended handler 7703 7704 7705/* ------------------------------ */ 7706 .balign 64 7707.L_OP_CONST_CLASS_JUMBO: /* 0x100 */ 7708/* File: armv5te/OP_CONST_CLASS_JUMBO.S */ 7709 /* const-class/jumbo vBBBB, Class@AAAAAAAA */ 7710 FETCH(r0, 1) @ r0<- aaaa (lo) 7711 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- glue->methodClassDex 7712 FETCH(r1, 2) @ r1<- AAAA (hi) 7713 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- dvmDex->pResClasses 7714 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 7715 FETCH(r9, 3) @ r9<- BBBB 7716 ldr r0, [r2, r1, lsl #2] @ r0<- pResClasses[AAAAaaaa] 7717 cmp r0, #0 @ not yet resolved? 7718 beq .LOP_CONST_CLASS_JUMBO_resolve 7719 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 7720 GET_INST_OPCODE(ip) @ extract opcode from rINST 7721 SET_VREG(r0, r9) @ vBBBB<- r0 7722 GOTO_OPCODE(ip) @ jump to next instruction 7723 7724/* ------------------------------ */ 7725 .balign 64 7726.L_OP_CHECK_CAST_JUMBO: /* 0x101 */ 7727/* File: armv5te/OP_CHECK_CAST_JUMBO.S */ 7728 /* 7729 * Check to see if a cast from one class to another is allowed. 7730 */ 7731 /* check-cast/jumbo vBBBB, class@AAAAAAAA */ 7732 FETCH(r0, 1) @ r0<- aaaa (lo) 7733 FETCH(r2, 2) @ r2<- AAAA (hi) 7734 FETCH(r3, 3) @ r3<- BBBB 7735 orr r2, r0, r2, lsl #16 @ r2<- AAAAaaaa 7736 GET_VREG(r9, r3) @ r9<- object 7737 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- pDvmDex 7738 cmp r9, #0 @ is object null? 7739 ldr r0, [r0, #offDvmDex_pResClasses] @ r0<- pDvmDex->pResClasses 7740 beq .LOP_CHECK_CAST_JUMBO_okay @ null obj, cast always succeeds 7741 ldr r1, [r0, r2, lsl #2] @ r1<- resolved class 7742 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 7743 cmp r1, #0 @ have we resolved this before? 7744 beq .LOP_CHECK_CAST_JUMBO_resolve @ not resolved, do it now 7745.LOP_CHECK_CAST_JUMBO_resolved: 7746 cmp r0, r1 @ same class (trivial success)? 7747 bne .LOP_CHECK_CAST_JUMBO_fullcheck @ no, do full check 7748 b .LOP_CHECK_CAST_JUMBO_okay @ yes, finish up 7749 7750/* ------------------------------ */ 7751 .balign 64 7752.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */ 7753/* File: armv5te/OP_INSTANCE_OF_JUMBO.S */ 7754 /* 7755 * Check to see if an object reference is an instance of a class. 7756 * 7757 * Most common situation is a non-null object, being compared against 7758 * an already-resolved class. 7759 * 7760 * TODO: convert most of this into a common subroutine, shared with 7761 * OP_INSTANCE_OF.S. 7762 */ 7763 /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 7764 FETCH(r3, 4) @ r3<- vCCCC 7765 FETCH(r9, 3) @ r9<- vBBBB 7766 GET_VREG(r0, r3) @ r0<- vCCCC (object) 7767 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- pDvmDex 7768 cmp r0, #0 @ is object null? 7769 beq .LOP_INSTANCE_OF_JUMBO_store @ null obj, not an instance, store r0 7770 FETCH(r1, 1) @ r1<- aaaa (lo) 7771 FETCH(r3, 2) @ r3<- AAAA (hi) 7772 ldr r2, [r2, #offDvmDex_pResClasses] @ r2<- pDvmDex->pResClasses 7773 orr r3, r1, r3, lsl #16 @ r3<- AAAAaaaa 7774 ldr r1, [r2, r3, lsl #2] @ r1<- resolved class 7775 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 7776 cmp r1, #0 @ have we resolved this before? 7777 beq .LOP_INSTANCE_OF_JUMBO_resolve @ not resolved, do it now 7778 b .LOP_INSTANCE_OF_JUMBO_resolved @ resolved, continue 7779 7780/* ------------------------------ */ 7781 .balign 64 7782.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */ 7783/* File: armv5te/OP_NEW_INSTANCE_JUMBO.S */ 7784 /* 7785 * Create a new instance of a class. 7786 */ 7787 /* new-instance/jumbo vBBBB, class@AAAAAAAA */ 7788 FETCH(r0, 1) @ r0<- aaaa (lo) 7789 FETCH(r1, 2) @ r1<- AAAA (hi) 7790 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 7791 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 7792 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 7793 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 7794 EXPORT_PC() @ req'd for init, resolve, alloc 7795 cmp r0, #0 @ already resolved? 7796 beq .LOP_NEW_INSTANCE_JUMBO_resolve @ no, resolve it now 7797.LOP_NEW_INSTANCE_JUMBO_resolved: @ r0=class 7798 ldrb r1, [r0, #offClassObject_status] @ r1<- ClassStatus enum 7799 cmp r1, #CLASS_INITIALIZED @ has class been initialized? 7800 bne .LOP_NEW_INSTANCE_JUMBO_needinit @ no, init class now 7801.LOP_NEW_INSTANCE_JUMBO_initialized: @ r0=class 7802 mov r1, #ALLOC_DONT_TRACK @ flags for alloc call 7803 bl dvmAllocObject @ r0<- new object 7804 b .LOP_NEW_INSTANCE_JUMBO_finish @ continue 7805 7806/* ------------------------------ */ 7807 .balign 64 7808.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */ 7809/* File: armv5te/OP_NEW_ARRAY_JUMBO.S */ 7810 /* 7811 * Allocate an array of objects, specified with the array class 7812 * and a count. 7813 * 7814 * The verifier guarantees that this is an array class, so we don't 7815 * check for it here. 7816 */ 7817 /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 7818 FETCH(r2, 1) @ r2<- aaaa (lo) 7819 FETCH(r3, 2) @ r3<- AAAA (hi) 7820 FETCH(r0, 4) @ r0<- vCCCC 7821 orr r2, r2, r3, lsl #16 @ r2<- AAAAaaaa 7822 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 7823 GET_VREG(r1, r0) @ r1<- vCCCC (array length) 7824 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 7825 cmp r1, #0 @ check length 7826 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 7827 bmi common_errNegativeArraySize @ negative length, bail 7828 cmp r0, #0 @ already resolved? 7829 EXPORT_PC() @ req'd for resolve, alloc 7830 bne .LOP_NEW_ARRAY_JUMBO_finish @ resolved, continue 7831 b .LOP_NEW_ARRAY_JUMBO_resolve @ do resolve now 7832 7833/* ------------------------------ */ 7834 .balign 64 7835.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */ 7836/* File: armv5te/OP_FILLED_NEW_ARRAY_JUMBO.S */ 7837 /* 7838 * Create a new array with elements filled from registers. 7839 * 7840 * TODO: convert most of this into a common subroutine, shared with 7841 * OP_FILLED_NEW_ARRAY.S. 7842 */ 7843 /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */ 7844 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 7845 FETCH(r0, 1) @ r0<- aaaa (lo) 7846 FETCH(r1, 2) @ r1<- AAAA (hi) 7847 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 7848 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 7849 ldr r0, [r3, r1, lsl #2] @ r0<- resolved class 7850 EXPORT_PC() @ need for resolve and alloc 7851 cmp r0, #0 @ already resolved? 7852 bne .LOP_FILLED_NEW_ARRAY_JUMBO_continue @ yes, continue on 78538: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 7854 mov r2, #0 @ r2<- false 7855 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 7856 bl dvmResolveClass @ r0<- call(clazz, ref) 7857 cmp r0, #0 @ got null? 7858 beq common_exceptionThrown @ yes, handle exception 7859 b .LOP_FILLED_NEW_ARRAY_JUMBO_continue 7860 7861/* ------------------------------ */ 7862 .balign 64 7863.L_OP_IGET_JUMBO: /* 0x106 */ 7864/* File: armv5te/OP_IGET_JUMBO.S */ 7865 /* 7866 * Jumbo 32-bit instance field get. 7867 * 7868 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7869 * iget-char/jumbo, iget-short/jumbo 7870 */ 7871 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 7872 FETCH(r1, 1) @ r1<- aaaa (lo) 7873 FETCH(r2, 2) @ r2<- AAAA (hi) 7874 FETCH(r0, 4) @ r0<- CCCC 7875 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7876 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7877 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7878 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7879 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7880 cmp r0, #0 @ is resolved entry null? 7881 bne .LOP_IGET_JUMBO_finish @ no, already resolved 78828: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7883 EXPORT_PC() @ resolve() could throw 7884 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7885 bl dvmResolveInstField @ r0<- resolved InstField ptr 7886 b .LOP_IGET_JUMBO_resolved @ resolved, continue 7887 7888/* ------------------------------ */ 7889 .balign 64 7890.L_OP_IGET_WIDE_JUMBO: /* 0x107 */ 7891/* File: armv5te/OP_IGET_WIDE_JUMBO.S */ 7892 /* 7893 * Jumbo 64-bit instance field get. 7894 */ 7895 /* iget-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 7896 FETCH(r1, 1) @ r1<- aaaa (lo) 7897 FETCH(r2, 2) @ r2<- AAAA (hi) 7898 FETCH(r0, 4) @ r0<- CCCC 7899 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7900 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7901 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 7902 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7903 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7904 cmp r0, #0 @ is resolved entry null? 7905 bne .LOP_IGET_WIDE_JUMBO_finish @ no, already resolved 79068: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7907 EXPORT_PC() @ resolve() could throw 7908 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7909 bl dvmResolveInstField @ r0<- resolved InstField ptr 7910 b .LOP_IGET_WIDE_JUMBO_resolved @ resolved, continue 7911 7912/* ------------------------------ */ 7913 .balign 64 7914.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */ 7915/* File: armv5te/OP_IGET_OBJECT_JUMBO.S */ 7916/* File: armv5te/OP_IGET_JUMBO.S */ 7917 /* 7918 * Jumbo 32-bit instance field get. 7919 * 7920 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7921 * iget-char/jumbo, iget-short/jumbo 7922 */ 7923 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 7924 FETCH(r1, 1) @ r1<- aaaa (lo) 7925 FETCH(r2, 2) @ r2<- AAAA (hi) 7926 FETCH(r0, 4) @ r0<- CCCC 7927 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7928 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7929 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7930 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7931 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7932 cmp r0, #0 @ is resolved entry null? 7933 bne .LOP_IGET_OBJECT_JUMBO_finish @ no, already resolved 79348: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7935 EXPORT_PC() @ resolve() could throw 7936 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7937 bl dvmResolveInstField @ r0<- resolved InstField ptr 7938 b .LOP_IGET_OBJECT_JUMBO_resolved @ resolved, continue 7939 7940 7941/* ------------------------------ */ 7942 .balign 64 7943.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */ 7944/* File: armv5te/OP_IGET_BOOLEAN_JUMBO.S */ 7945@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrb", "sqnum":"1" } 7946/* File: armv5te/OP_IGET_JUMBO.S */ 7947 /* 7948 * Jumbo 32-bit instance field get. 7949 * 7950 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7951 * iget-char/jumbo, iget-short/jumbo 7952 */ 7953 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 7954 FETCH(r1, 1) @ r1<- aaaa (lo) 7955 FETCH(r2, 2) @ r2<- AAAA (hi) 7956 FETCH(r0, 4) @ r0<- CCCC 7957 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7958 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7959 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7960 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7961 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7962 cmp r0, #0 @ is resolved entry null? 7963 bne .LOP_IGET_BOOLEAN_JUMBO_finish @ no, already resolved 79648: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7965 EXPORT_PC() @ resolve() could throw 7966 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7967 bl dvmResolveInstField @ r0<- resolved InstField ptr 7968 b .LOP_IGET_BOOLEAN_JUMBO_resolved @ resolved, continue 7969 7970 7971/* ------------------------------ */ 7972 .balign 64 7973.L_OP_IGET_BYTE_JUMBO: /* 0x10a */ 7974/* File: armv5te/OP_IGET_BYTE_JUMBO.S */ 7975@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsb", "sqnum":"2" } 7976/* File: armv5te/OP_IGET_JUMBO.S */ 7977 /* 7978 * Jumbo 32-bit instance field get. 7979 * 7980 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 7981 * iget-char/jumbo, iget-short/jumbo 7982 */ 7983 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 7984 FETCH(r1, 1) @ r1<- aaaa (lo) 7985 FETCH(r2, 2) @ r2<- AAAA (hi) 7986 FETCH(r0, 4) @ r0<- CCCC 7987 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 7988 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 7989 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 7990 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 7991 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 7992 cmp r0, #0 @ is resolved entry null? 7993 bne .LOP_IGET_BYTE_JUMBO_finish @ no, already resolved 79948: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 7995 EXPORT_PC() @ resolve() could throw 7996 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 7997 bl dvmResolveInstField @ r0<- resolved InstField ptr 7998 b .LOP_IGET_BYTE_JUMBO_resolved @ resolved, continue 7999 8000 8001/* ------------------------------ */ 8002 .balign 64 8003.L_OP_IGET_CHAR_JUMBO: /* 0x10b */ 8004/* File: armv5te/OP_IGET_CHAR_JUMBO.S */ 8005@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrh", "sqnum":"3" } 8006/* File: armv5te/OP_IGET_JUMBO.S */ 8007 /* 8008 * Jumbo 32-bit instance field get. 8009 * 8010 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8011 * iget-char/jumbo, iget-short/jumbo 8012 */ 8013 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8014 FETCH(r1, 1) @ r1<- aaaa (lo) 8015 FETCH(r2, 2) @ r2<- AAAA (hi) 8016 FETCH(r0, 4) @ r0<- CCCC 8017 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8018 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8019 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8020 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8021 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8022 cmp r0, #0 @ is resolved entry null? 8023 bne .LOP_IGET_CHAR_JUMBO_finish @ no, already resolved 80248: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8025 EXPORT_PC() @ resolve() could throw 8026 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8027 bl dvmResolveInstField @ r0<- resolved InstField ptr 8028 b .LOP_IGET_CHAR_JUMBO_resolved @ resolved, continue 8029 8030 8031/* ------------------------------ */ 8032 .balign 64 8033.L_OP_IGET_SHORT_JUMBO: /* 0x10c */ 8034/* File: armv5te/OP_IGET_SHORT_JUMBO.S */ 8035@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsh", "sqnum":"4" } 8036/* File: armv5te/OP_IGET_JUMBO.S */ 8037 /* 8038 * Jumbo 32-bit instance field get. 8039 * 8040 * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo, 8041 * iget-char/jumbo, iget-short/jumbo 8042 */ 8043 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8044 FETCH(r1, 1) @ r1<- aaaa (lo) 8045 FETCH(r2, 2) @ r2<- AAAA (hi) 8046 FETCH(r0, 4) @ r0<- CCCC 8047 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8048 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8049 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8050 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8051 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8052 cmp r0, #0 @ is resolved entry null? 8053 bne .LOP_IGET_SHORT_JUMBO_finish @ no, already resolved 80548: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8055 EXPORT_PC() @ resolve() could throw 8056 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8057 bl dvmResolveInstField @ r0<- resolved InstField ptr 8058 b .LOP_IGET_SHORT_JUMBO_resolved @ resolved, continue 8059 8060 8061/* ------------------------------ */ 8062 .balign 64 8063.L_OP_IPUT_JUMBO: /* 0x10d */ 8064/* File: armv5te/OP_IPUT_JUMBO.S */ 8065 /* 8066 * Jumbo 32-bit instance field put. 8067 * 8068 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8069 * iput-short/jumbo 8070 */ 8071 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8072 FETCH(r1, 1) @ r1<- aaaa (lo) 8073 FETCH(r2, 2) @ r2<- AAAA (hi) 8074 FETCH(r0, 4) @ r0<- CCCC 8075 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8076 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8077 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8078 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8079 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8080 cmp r0, #0 @ is resolved entry null? 8081 bne .LOP_IPUT_JUMBO_finish @ no, already resolved 80828: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8083 EXPORT_PC() @ resolve() could throw 8084 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8085 bl dvmResolveInstField @ r0<- resolved InstField ptr 8086 b .LOP_IPUT_JUMBO_resolved @ resolved, continue 8087 8088/* ------------------------------ */ 8089 .balign 64 8090.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */ 8091/* File: armv5te/OP_IPUT_WIDE_JUMBO.S */ 8092 /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 8093 FETCH(r1, 1) @ r1<- aaaa (lo) 8094 FETCH(r2, 2) @ r2<- AAAA (hi) 8095 FETCH(r0, 4) @ r0<- CCCC 8096 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8097 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8098 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields 8099 GET_VREG(r9, r0) @ r9<- fp[B], the object pointer 8100 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8101 cmp r0, #0 @ is resolved entry null? 8102 bne .LOP_IPUT_WIDE_JUMBO_finish @ no, already resolved 81038: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8104 EXPORT_PC() @ resolve() could throw 8105 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8106 bl dvmResolveInstField @ r0<- resolved InstField ptr 8107 b .LOP_IPUT_WIDE_JUMBO_resolved @ resolved, continue 8108 8109/* ------------------------------ */ 8110 .balign 64 8111.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */ 8112/* File: armv5te/OP_IPUT_OBJECT_JUMBO.S */ 8113 /* 8114 * Jumbo 32-bit instance field put. 8115 */ 8116 /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */ 8117 FETCH(r1, 1) @ r1<- aaaa (lo) 8118 FETCH(r2, 2) @ r2<- AAAA (hi) 8119 FETCH(r0, 4) @ r0<- CCCC 8120 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8121 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8122 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8123 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8124 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8125 cmp r0, #0 @ is resolved entry null? 8126 bne .LOP_IPUT_OBJECT_JUMBO_finish @ no, already resolved 81278: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8128 EXPORT_PC() @ resolve() could throw 8129 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8130 bl dvmResolveInstField @ r0<- resolved InstField ptr 8131 b .LOP_IPUT_OBJECT_JUMBO_resolved @ resolved, continue 8132 8133/* ------------------------------ */ 8134 .balign 64 8135.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */ 8136/* File: armv5te/OP_IPUT_BOOLEAN_JUMBO.S */ 8137@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"1" } 8138/* File: armv5te/OP_IPUT_JUMBO.S */ 8139 /* 8140 * Jumbo 32-bit instance field put. 8141 * 8142 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8143 * iput-short/jumbo 8144 */ 8145 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8146 FETCH(r1, 1) @ r1<- aaaa (lo) 8147 FETCH(r2, 2) @ r2<- AAAA (hi) 8148 FETCH(r0, 4) @ r0<- CCCC 8149 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8150 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8151 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8152 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8153 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8154 cmp r0, #0 @ is resolved entry null? 8155 bne .LOP_IPUT_BOOLEAN_JUMBO_finish @ no, already resolved 81568: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8157 EXPORT_PC() @ resolve() could throw 8158 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8159 bl dvmResolveInstField @ r0<- resolved InstField ptr 8160 b .LOP_IPUT_BOOLEAN_JUMBO_resolved @ resolved, continue 8161 8162 8163/* ------------------------------ */ 8164 .balign 64 8165.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */ 8166/* File: armv5te/OP_IPUT_BYTE_JUMBO.S */ 8167@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"2" } 8168/* File: armv5te/OP_IPUT_JUMBO.S */ 8169 /* 8170 * Jumbo 32-bit instance field put. 8171 * 8172 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8173 * iput-short/jumbo 8174 */ 8175 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8176 FETCH(r1, 1) @ r1<- aaaa (lo) 8177 FETCH(r2, 2) @ r2<- AAAA (hi) 8178 FETCH(r0, 4) @ r0<- CCCC 8179 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8180 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8181 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8182 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8183 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8184 cmp r0, #0 @ is resolved entry null? 8185 bne .LOP_IPUT_BYTE_JUMBO_finish @ no, already resolved 81868: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8187 EXPORT_PC() @ resolve() could throw 8188 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8189 bl dvmResolveInstField @ r0<- resolved InstField ptr 8190 b .LOP_IPUT_BYTE_JUMBO_resolved @ resolved, continue 8191 8192 8193/* ------------------------------ */ 8194 .balign 64 8195.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */ 8196/* File: armv5te/OP_IPUT_CHAR_JUMBO.S */ 8197@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"3" } 8198/* File: armv5te/OP_IPUT_JUMBO.S */ 8199 /* 8200 * Jumbo 32-bit instance field put. 8201 * 8202 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8203 * iput-short/jumbo 8204 */ 8205 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8206 FETCH(r1, 1) @ r1<- aaaa (lo) 8207 FETCH(r2, 2) @ r2<- AAAA (hi) 8208 FETCH(r0, 4) @ r0<- CCCC 8209 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8210 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8211 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8212 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8213 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8214 cmp r0, #0 @ is resolved entry null? 8215 bne .LOP_IPUT_CHAR_JUMBO_finish @ no, already resolved 82168: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8217 EXPORT_PC() @ resolve() could throw 8218 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8219 bl dvmResolveInstField @ r0<- resolved InstField ptr 8220 b .LOP_IPUT_CHAR_JUMBO_resolved @ resolved, continue 8221 8222 8223/* ------------------------------ */ 8224 .balign 64 8225.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */ 8226/* File: armv5te/OP_IPUT_SHORT_JUMBO.S */ 8227@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"4" } 8228/* File: armv5te/OP_IPUT_JUMBO.S */ 8229 /* 8230 * Jumbo 32-bit instance field put. 8231 * 8232 * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo, 8233 * iput-short/jumbo 8234 */ 8235 /* exop vBBBB, vCCCC, field@AAAAAAAA */ 8236 FETCH(r1, 1) @ r1<- aaaa (lo) 8237 FETCH(r2, 2) @ r2<- AAAA (hi) 8238 FETCH(r0, 4) @ r0<- CCCC 8239 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex 8240 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8241 ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields 8242 GET_VREG(r9, r0) @ r9<- fp[CCCC], the object pointer 8243 ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr 8244 cmp r0, #0 @ is resolved entry null? 8245 bne .LOP_IPUT_SHORT_JUMBO_finish @ no, already resolved 82468: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 8247 EXPORT_PC() @ resolve() could throw 8248 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 8249 bl dvmResolveInstField @ r0<- resolved InstField ptr 8250 b .LOP_IPUT_SHORT_JUMBO_resolved @ resolved, continue 8251 8252 8253/* ------------------------------ */ 8254 .balign 64 8255.L_OP_SGET_JUMBO: /* 0x114 */ 8256/* File: armv5te/OP_SGET_JUMBO.S */ 8257 /* 8258 * Jumbo 32-bit SGET handler. 8259 * 8260 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8261 * sget-char/jumbo, sget-short/jumbo 8262 */ 8263 /* exop vBBBB, field@AAAAAAAA */ 8264 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8265 FETCH(r0, 1) @ r0<- aaaa (lo) 8266 FETCH(r1, 2) @ r1<- AAAA (hi) 8267 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8268 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8269 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8270 cmp r0, #0 @ is resolved entry null? 8271 beq .LOP_SGET_JUMBO_resolve @ yes, do resolve 8272.LOP_SGET_JUMBO_finish: @ field ptr in r0 8273 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8274 @ no-op @ acquiring load 8275 FETCH(r2, 3) @ r2<- BBBB 8276 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8277 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8278 GET_INST_OPCODE(ip) @ extract opcode from rINST 8279 GOTO_OPCODE(ip) @ jump to next instruction 8280 8281/* ------------------------------ */ 8282 .balign 64 8283.L_OP_SGET_WIDE_JUMBO: /* 0x115 */ 8284/* File: armv5te/OP_SGET_WIDE_JUMBO.S */ 8285 /* 8286 * Jumbo 64-bit SGET handler. 8287 */ 8288 /* sget-wide/jumbo vBBBB, field@AAAAAAAA */ 8289 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8290 FETCH(r0, 1) @ r0<- aaaa (lo) 8291 FETCH(r1, 2) @ r1<- AAAA (hi) 8292 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8293 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8294 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8295 cmp r0, #0 @ is resolved entry null? 8296 beq .LOP_SGET_WIDE_JUMBO_resolve @ yes, do resolve 8297.LOP_SGET_WIDE_JUMBO_finish: 8298 FETCH(r9, 3) @ r9<- BBBB 8299 ldrd r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned) 8300 add r9, rFP, r9, lsl #2 @ r9<- &fp[BBBB] 8301 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8302 stmia r9, {r0-r1} @ vBBBB/vBBBB+1<- r0/r1 8303 GET_INST_OPCODE(ip) @ extract opcode from rINST 8304 GOTO_OPCODE(ip) @ jump to next instruction 8305 8306/* ------------------------------ */ 8307 .balign 64 8308.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */ 8309/* File: armv5te/OP_SGET_OBJECT_JUMBO.S */ 8310/* File: armv5te/OP_SGET_JUMBO.S */ 8311 /* 8312 * Jumbo 32-bit SGET handler. 8313 * 8314 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8315 * sget-char/jumbo, sget-short/jumbo 8316 */ 8317 /* exop vBBBB, field@AAAAAAAA */ 8318 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8319 FETCH(r0, 1) @ r0<- aaaa (lo) 8320 FETCH(r1, 2) @ r1<- AAAA (hi) 8321 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8322 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8323 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8324 cmp r0, #0 @ is resolved entry null? 8325 beq .LOP_SGET_OBJECT_JUMBO_resolve @ yes, do resolve 8326.LOP_SGET_OBJECT_JUMBO_finish: @ field ptr in r0 8327 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8328 @ no-op @ acquiring load 8329 FETCH(r2, 3) @ r2<- BBBB 8330 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8331 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8332 GET_INST_OPCODE(ip) @ extract opcode from rINST 8333 GOTO_OPCODE(ip) @ jump to next instruction 8334 8335 8336/* ------------------------------ */ 8337 .balign 64 8338.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */ 8339/* File: armv5te/OP_SGET_BOOLEAN_JUMBO.S */ 8340/* File: armv5te/OP_SGET_JUMBO.S */ 8341 /* 8342 * Jumbo 32-bit SGET handler. 8343 * 8344 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8345 * sget-char/jumbo, sget-short/jumbo 8346 */ 8347 /* exop vBBBB, field@AAAAAAAA */ 8348 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8349 FETCH(r0, 1) @ r0<- aaaa (lo) 8350 FETCH(r1, 2) @ r1<- AAAA (hi) 8351 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8352 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8353 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8354 cmp r0, #0 @ is resolved entry null? 8355 beq .LOP_SGET_BOOLEAN_JUMBO_resolve @ yes, do resolve 8356.LOP_SGET_BOOLEAN_JUMBO_finish: @ field ptr in r0 8357 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8358 @ no-op @ acquiring load 8359 FETCH(r2, 3) @ r2<- BBBB 8360 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8361 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8362 GET_INST_OPCODE(ip) @ extract opcode from rINST 8363 GOTO_OPCODE(ip) @ jump to next instruction 8364 8365 8366/* ------------------------------ */ 8367 .balign 64 8368.L_OP_SGET_BYTE_JUMBO: /* 0x118 */ 8369/* File: armv5te/OP_SGET_BYTE_JUMBO.S */ 8370/* File: armv5te/OP_SGET_JUMBO.S */ 8371 /* 8372 * Jumbo 32-bit SGET handler. 8373 * 8374 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8375 * sget-char/jumbo, sget-short/jumbo 8376 */ 8377 /* exop vBBBB, field@AAAAAAAA */ 8378 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8379 FETCH(r0, 1) @ r0<- aaaa (lo) 8380 FETCH(r1, 2) @ r1<- AAAA (hi) 8381 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8382 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8383 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8384 cmp r0, #0 @ is resolved entry null? 8385 beq .LOP_SGET_BYTE_JUMBO_resolve @ yes, do resolve 8386.LOP_SGET_BYTE_JUMBO_finish: @ field ptr in r0 8387 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8388 @ no-op @ acquiring load 8389 FETCH(r2, 3) @ r2<- BBBB 8390 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8391 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8392 GET_INST_OPCODE(ip) @ extract opcode from rINST 8393 GOTO_OPCODE(ip) @ jump to next instruction 8394 8395 8396/* ------------------------------ */ 8397 .balign 64 8398.L_OP_SGET_CHAR_JUMBO: /* 0x119 */ 8399/* File: armv5te/OP_SGET_CHAR_JUMBO.S */ 8400/* File: armv5te/OP_SGET_JUMBO.S */ 8401 /* 8402 * Jumbo 32-bit SGET handler. 8403 * 8404 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8405 * sget-char/jumbo, sget-short/jumbo 8406 */ 8407 /* exop vBBBB, field@AAAAAAAA */ 8408 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8409 FETCH(r0, 1) @ r0<- aaaa (lo) 8410 FETCH(r1, 2) @ r1<- AAAA (hi) 8411 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8412 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8413 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8414 cmp r0, #0 @ is resolved entry null? 8415 beq .LOP_SGET_CHAR_JUMBO_resolve @ yes, do resolve 8416.LOP_SGET_CHAR_JUMBO_finish: @ field ptr in r0 8417 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8418 @ no-op @ acquiring load 8419 FETCH(r2, 3) @ r2<- BBBB 8420 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8421 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8422 GET_INST_OPCODE(ip) @ extract opcode from rINST 8423 GOTO_OPCODE(ip) @ jump to next instruction 8424 8425 8426/* ------------------------------ */ 8427 .balign 64 8428.L_OP_SGET_SHORT_JUMBO: /* 0x11a */ 8429/* File: armv5te/OP_SGET_SHORT_JUMBO.S */ 8430/* File: armv5te/OP_SGET_JUMBO.S */ 8431 /* 8432 * Jumbo 32-bit SGET handler. 8433 * 8434 * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo, 8435 * sget-char/jumbo, sget-short/jumbo 8436 */ 8437 /* exop vBBBB, field@AAAAAAAA */ 8438 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8439 FETCH(r0, 1) @ r0<- aaaa (lo) 8440 FETCH(r1, 2) @ r1<- AAAA (hi) 8441 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8442 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8443 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8444 cmp r0, #0 @ is resolved entry null? 8445 beq .LOP_SGET_SHORT_JUMBO_resolve @ yes, do resolve 8446.LOP_SGET_SHORT_JUMBO_finish: @ field ptr in r0 8447 ldr r1, [r0, #offStaticField_value] @ r1<- field value 8448 @ no-op @ acquiring load 8449 FETCH(r2, 3) @ r2<- BBBB 8450 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8451 SET_VREG(r1, r2) @ fp[BBBB]<- r1 8452 GET_INST_OPCODE(ip) @ extract opcode from rINST 8453 GOTO_OPCODE(ip) @ jump to next instruction 8454 8455 8456/* ------------------------------ */ 8457 .balign 64 8458.L_OP_SPUT_JUMBO: /* 0x11b */ 8459/* File: armv5te/OP_SPUT_JUMBO.S */ 8460 /* 8461 * Jumbo 32-bit SPUT handler. 8462 * 8463 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8464 * sput-short/jumbo 8465 */ 8466 /* exop vBBBB, field@AAAAAAAA */ 8467 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8468 FETCH(r0, 1) @ r0<- aaaa (lo) 8469 FETCH(r1, 2) @ r1<- AAAA (hi) 8470 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8471 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8472 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8473 cmp r0, #0 @ is resolved entry null? 8474 beq .LOP_SPUT_JUMBO_resolve @ yes, do resolve 8475.LOP_SPUT_JUMBO_finish: @ field ptr in r0 8476 FETCH(r2, 3) @ r2<- BBBB 8477 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8478 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8479 GET_INST_OPCODE(ip) @ extract opcode from rINST 8480 @ no-op @ releasing store 8481 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8482 GOTO_OPCODE(ip) @ jump to next instruction 8483 8484/* ------------------------------ */ 8485 .balign 64 8486.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */ 8487/* File: armv5te/OP_SPUT_WIDE_JUMBO.S */ 8488 /* 8489 * Jumbo 64-bit SPUT handler. 8490 */ 8491 /* sput-wide/jumbo vBBBB, field@AAAAAAAA */ 8492 ldr r0, [rGLUE, #offGlue_methodClassDex] @ r0<- DvmDex 8493 FETCH(r1, 1) @ r1<- aaaa (lo) 8494 FETCH(r2, 2) @ r2<- AAAA (hi) 8495 ldr r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields 8496 orr r1, r1, r2, lsl #16 @ r1<- AAAAaaaa 8497 FETCH(r9, 3) @ r9<- BBBB 8498 ldr r2, [r0, r1, lsl #2] @ r2<- resolved StaticField ptr 8499 add r9, rFP, r9, lsl #2 @ r9<- &fp[BBBB] 8500 cmp r2, #0 @ is resolved entry null? 8501 beq .LOP_SPUT_WIDE_JUMBO_resolve @ yes, do resolve 8502.LOP_SPUT_WIDE_JUMBO_finish: @ field ptr in r2, BBBB in r9 8503 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8504 ldmia r9, {r0-r1} @ r0/r1<- vBBBB/vBBBB+1 8505 GET_INST_OPCODE(r10) @ extract opcode from rINST 8506 strd r0, [r2, #offStaticField_value] @ field<- vBBBB/vBBBB+1 8507 GOTO_OPCODE(r10) @ jump to next instruction 8508 8509/* ------------------------------ */ 8510 .balign 64 8511.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */ 8512/* File: armv5te/OP_SPUT_OBJECT_JUMBO.S */ 8513 /* 8514 * Jumbo 32-bit SPUT handler for objects 8515 */ 8516 /* sput-object/jumbo vBBBB, field@AAAAAAAA */ 8517 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8518 FETCH(r0, 1) @ r0<- aaaa (lo) 8519 FETCH(r1, 2) @ r1<- AAAA (hi) 8520 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8521 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8522 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8523 cmp r0, #0 @ is resolved entry null? 8524 bne .LOP_SPUT_OBJECT_JUMBO_finish @ no, continue 8525 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 8526 EXPORT_PC() @ resolve() could throw, so export now 8527 ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz 8528 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 8529 cmp r0, #0 @ success? 8530 bne .LOP_SPUT_OBJECT_JUMBO_finish @ yes, finish 8531 b common_exceptionThrown @ no, handle exception 8532 8533/* ------------------------------ */ 8534 .balign 64 8535.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */ 8536/* File: armv5te/OP_SPUT_BOOLEAN_JUMBO.S */ 8537/* File: armv5te/OP_SPUT_JUMBO.S */ 8538 /* 8539 * Jumbo 32-bit SPUT handler. 8540 * 8541 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8542 * sput-short/jumbo 8543 */ 8544 /* exop vBBBB, field@AAAAAAAA */ 8545 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8546 FETCH(r0, 1) @ r0<- aaaa (lo) 8547 FETCH(r1, 2) @ r1<- AAAA (hi) 8548 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8549 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8550 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8551 cmp r0, #0 @ is resolved entry null? 8552 beq .LOP_SPUT_BOOLEAN_JUMBO_resolve @ yes, do resolve 8553.LOP_SPUT_BOOLEAN_JUMBO_finish: @ field ptr in r0 8554 FETCH(r2, 3) @ r2<- BBBB 8555 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8556 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8557 GET_INST_OPCODE(ip) @ extract opcode from rINST 8558 @ no-op @ releasing store 8559 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8560 GOTO_OPCODE(ip) @ jump to next instruction 8561 8562 8563/* ------------------------------ */ 8564 .balign 64 8565.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */ 8566/* File: armv5te/OP_SPUT_BYTE_JUMBO.S */ 8567/* File: armv5te/OP_SPUT_JUMBO.S */ 8568 /* 8569 * Jumbo 32-bit SPUT handler. 8570 * 8571 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8572 * sput-short/jumbo 8573 */ 8574 /* exop vBBBB, field@AAAAAAAA */ 8575 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8576 FETCH(r0, 1) @ r0<- aaaa (lo) 8577 FETCH(r1, 2) @ r1<- AAAA (hi) 8578 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8579 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8580 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8581 cmp r0, #0 @ is resolved entry null? 8582 beq .LOP_SPUT_BYTE_JUMBO_resolve @ yes, do resolve 8583.LOP_SPUT_BYTE_JUMBO_finish: @ field ptr in r0 8584 FETCH(r2, 3) @ r2<- BBBB 8585 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8586 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8587 GET_INST_OPCODE(ip) @ extract opcode from rINST 8588 @ no-op @ releasing store 8589 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8590 GOTO_OPCODE(ip) @ jump to next instruction 8591 8592 8593/* ------------------------------ */ 8594 .balign 64 8595.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */ 8596/* File: armv5te/OP_SPUT_CHAR_JUMBO.S */ 8597/* File: armv5te/OP_SPUT_JUMBO.S */ 8598 /* 8599 * Jumbo 32-bit SPUT handler. 8600 * 8601 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8602 * sput-short/jumbo 8603 */ 8604 /* exop vBBBB, field@AAAAAAAA */ 8605 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8606 FETCH(r0, 1) @ r0<- aaaa (lo) 8607 FETCH(r1, 2) @ r1<- AAAA (hi) 8608 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8609 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8610 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8611 cmp r0, #0 @ is resolved entry null? 8612 beq .LOP_SPUT_CHAR_JUMBO_resolve @ yes, do resolve 8613.LOP_SPUT_CHAR_JUMBO_finish: @ field ptr in r0 8614 FETCH(r2, 3) @ r2<- BBBB 8615 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8616 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8617 GET_INST_OPCODE(ip) @ extract opcode from rINST 8618 @ no-op @ releasing store 8619 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8620 GOTO_OPCODE(ip) @ jump to next instruction 8621 8622 8623/* ------------------------------ */ 8624 .balign 64 8625.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */ 8626/* File: armv5te/OP_SPUT_SHORT_JUMBO.S */ 8627/* File: armv5te/OP_SPUT_JUMBO.S */ 8628 /* 8629 * Jumbo 32-bit SPUT handler. 8630 * 8631 * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo, 8632 * sput-short/jumbo 8633 */ 8634 /* exop vBBBB, field@AAAAAAAA */ 8635 ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex 8636 FETCH(r0, 1) @ r0<- aaaa (lo) 8637 FETCH(r1, 2) @ r1<- AAAA (hi) 8638 ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields 8639 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8640 ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr 8641 cmp r0, #0 @ is resolved entry null? 8642 beq .LOP_SPUT_SHORT_JUMBO_resolve @ yes, do resolve 8643.LOP_SPUT_SHORT_JUMBO_finish: @ field ptr in r0 8644 FETCH(r2, 3) @ r2<- BBBB 8645 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 8646 GET_VREG(r1, r2) @ r1<- fp[BBBB] 8647 GET_INST_OPCODE(ip) @ extract opcode from rINST 8648 @ no-op @ releasing store 8649 str r1, [r0, #offStaticField_value] @ field<- vBBBB 8650 GOTO_OPCODE(ip) @ jump to next instruction 8651 8652 8653/* ------------------------------ */ 8654 .balign 64 8655.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */ 8656/* File: armv5te/OP_INVOKE_VIRTUAL_JUMBO.S */ 8657 /* 8658 * Handle a virtual method call. 8659 */ 8660 /* invoke-virtual/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8661 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8662 FETCH(r0, 1) @ r1<- aaaa (lo) 8663 FETCH(r1, 2) @ r1<- AAAA (hi) 8664 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8665 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8666 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 8667 cmp r0, #0 @ already resolved? 8668 EXPORT_PC() @ must export for invoke 8669 bne .LOP_INVOKE_VIRTUAL_JUMBO_continue @ yes, continue on 8670 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 8671 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8672 mov r2, #METHOD_VIRTUAL @ resolver method type 8673 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8674 cmp r0, #0 @ got null? 8675 bne .LOP_INVOKE_VIRTUAL_JUMBO_continue @ no, continue 8676 b common_exceptionThrown @ yes, handle exception 8677 8678/* ------------------------------ */ 8679 .balign 64 8680.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */ 8681/* File: armv5te/OP_INVOKE_SUPER_JUMBO.S */ 8682 /* 8683 * Handle a "super" method call. 8684 */ 8685 /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8686 FETCH(r10, 4) @ r10<- CCCC 8687 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8688 FETCH(r0, 1) @ r1<- aaaa (lo) 8689 FETCH(r1, 2) @ r1<- AAAA (hi) 8690 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8691 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8692 GET_VREG(r2, r10) @ r2<- "this" ptr 8693 ldr r0, [r3, r1, lsl #2] @ r0<- resolved baseMethod 8694 cmp r2, #0 @ null "this"? 8695 ldr r9, [rGLUE, #offGlue_method] @ r9<- current method 8696 beq common_errNullObject @ null "this", throw exception 8697 cmp r0, #0 @ already resolved? 8698 ldr r9, [r9, #offMethod_clazz] @ r9<- method->clazz 8699 EXPORT_PC() @ must export for invoke 8700 bne .LOP_INVOKE_SUPER_JUMBO_continue @ resolved, continue on 8701 b .LOP_INVOKE_SUPER_JUMBO_resolve @ do resolve now 8702 8703/* ------------------------------ */ 8704 .balign 64 8705.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */ 8706/* File: armv5te/OP_INVOKE_DIRECT_JUMBO.S */ 8707 /* 8708 * Handle a direct method call. 8709 * 8710 * (We could defer the "is 'this' pointer null" test to the common 8711 * method invocation code, and use a flag to indicate that static 8712 * calls don't count. If we do this as part of copying the arguments 8713 * out we could avoiding loading the first arg twice.) 8714 * 8715 */ 8716 /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8717 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8718 FETCH(r0, 1) @ r1<- aaaa (lo) 8719 FETCH(r1, 2) @ r1<- AAAA (hi) 8720 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8721 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8722 FETCH(r10, 4) @ r10<- CCCC 8723 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 8724 cmp r0, #0 @ already resolved? 8725 EXPORT_PC() @ must export for invoke 8726 GET_VREG(r2, r10) @ r2<- "this" ptr 8727 beq .LOP_INVOKE_DIRECT_JUMBO_resolve @ not resolved, do it now 8728.LOP_INVOKE_DIRECT_JUMBO_finish: 8729 cmp r2, #0 @ null "this" ref? 8730 bne common_invokeMethodJumbo @ no, continue on 8731 b common_errNullObject @ yes, throw exception 8732 8733/* ------------------------------ */ 8734 .balign 64 8735.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */ 8736/* File: armv5te/OP_INVOKE_STATIC_JUMBO.S */ 8737 /* 8738 * Handle a static method call. 8739 */ 8740 /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8741 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- pDvmDex 8742 FETCH(r0, 1) @ r1<- aaaa (lo) 8743 FETCH(r1, 2) @ r1<- AAAA (hi) 8744 ldr r3, [r3, #offDvmDex_pResMethods] @ r3<- pDvmDex->pResMethods 8745 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8746 ldr r0, [r3, r1, lsl #2] @ r0<- resolved methodToCall 8747 cmp r0, #0 @ already resolved? 8748 EXPORT_PC() @ must export for invoke 8749 bne common_invokeMethodJumbo @ yes, continue on 87500: ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 8751 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 8752 mov r2, #METHOD_STATIC @ resolver method type 8753 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 8754 cmp r0, #0 @ got null? 8755 bne common_invokeMethodJumbo @ no, continue 8756 b common_exceptionThrown @ yes, handle exception 8757 8758/* ------------------------------ */ 8759 .balign 64 8760.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */ 8761/* File: armv5te/OP_INVOKE_INTERFACE_JUMBO.S */ 8762 /* 8763 * Handle an interface method call. 8764 */ 8765 /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */ 8766 FETCH(r2, 4) @ r2<- CCCC 8767 FETCH(r0, 1) @ r0<- aaaa (lo) 8768 FETCH(r1, 2) @ r1<- AAAA (hi) 8769 EXPORT_PC() @ must export for invoke 8770 orr r1, r0, r1, lsl #16 @ r1<- AAAAaaaa 8771 GET_VREG(r0, r2) @ r0<- first arg ("this") 8772 ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- methodClassDex 8773 cmp r0, #0 @ null obj? 8774 ldr r2, [rGLUE, #offGlue_method] @ r2<- method 8775 beq common_errNullObject @ yes, fail 8776 ldr r0, [r0, #offObject_clazz] @ r0<- thisPtr->clazz 8777 bl dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex) 8778 cmp r0, #0 @ failed? 8779 beq common_exceptionThrown @ yes, handle exception 8780 b common_invokeMethodJumbo @ jump to common handler 8781 8782/* ------------------------------ */ 8783 .balign 64 8784.L_OP_UNUSED_27FF: /* 0x127 */ 8785/* File: armv5te/OP_UNUSED_27FF.S */ 8786/* File: armv5te/unused.S */ 8787 bl common_abort 8788 8789 8790/* ------------------------------ */ 8791 .balign 64 8792.L_OP_UNUSED_28FF: /* 0x128 */ 8793/* File: armv5te/OP_UNUSED_28FF.S */ 8794/* File: armv5te/unused.S */ 8795 bl common_abort 8796 8797 8798/* ------------------------------ */ 8799 .balign 64 8800.L_OP_UNUSED_29FF: /* 0x129 */ 8801/* File: armv5te/OP_UNUSED_29FF.S */ 8802/* File: armv5te/unused.S */ 8803 bl common_abort 8804 8805 8806/* ------------------------------ */ 8807 .balign 64 8808.L_OP_UNUSED_2AFF: /* 0x12a */ 8809/* File: armv5te/OP_UNUSED_2AFF.S */ 8810/* File: armv5te/unused.S */ 8811 bl common_abort 8812 8813 8814/* ------------------------------ */ 8815 .balign 64 8816.L_OP_UNUSED_2BFF: /* 0x12b */ 8817/* File: armv5te/OP_UNUSED_2BFF.S */ 8818/* File: armv5te/unused.S */ 8819 bl common_abort 8820 8821 8822/* ------------------------------ */ 8823 .balign 64 8824.L_OP_UNUSED_2CFF: /* 0x12c */ 8825/* File: armv5te/OP_UNUSED_2CFF.S */ 8826/* File: armv5te/unused.S */ 8827 bl common_abort 8828 8829 8830/* ------------------------------ */ 8831 .balign 64 8832.L_OP_UNUSED_2DFF: /* 0x12d */ 8833/* File: armv5te/OP_UNUSED_2DFF.S */ 8834/* File: armv5te/unused.S */ 8835 bl common_abort 8836 8837 8838/* ------------------------------ */ 8839 .balign 64 8840.L_OP_UNUSED_2EFF: /* 0x12e */ 8841/* File: armv5te/OP_UNUSED_2EFF.S */ 8842/* File: armv5te/unused.S */ 8843 bl common_abort 8844 8845 8846/* ------------------------------ */ 8847 .balign 64 8848.L_OP_UNUSED_2FFF: /* 0x12f */ 8849/* File: armv5te/OP_UNUSED_2FFF.S */ 8850/* File: armv5te/unused.S */ 8851 bl common_abort 8852 8853 8854/* ------------------------------ */ 8855 .balign 64 8856.L_OP_UNUSED_30FF: /* 0x130 */ 8857/* File: armv5te/OP_UNUSED_30FF.S */ 8858/* File: armv5te/unused.S */ 8859 bl common_abort 8860 8861 8862/* ------------------------------ */ 8863 .balign 64 8864.L_OP_UNUSED_31FF: /* 0x131 */ 8865/* File: armv5te/OP_UNUSED_31FF.S */ 8866/* File: armv5te/unused.S */ 8867 bl common_abort 8868 8869 8870/* ------------------------------ */ 8871 .balign 64 8872.L_OP_UNUSED_32FF: /* 0x132 */ 8873/* File: armv5te/OP_UNUSED_32FF.S */ 8874/* File: armv5te/unused.S */ 8875 bl common_abort 8876 8877 8878/* ------------------------------ */ 8879 .balign 64 8880.L_OP_UNUSED_33FF: /* 0x133 */ 8881/* File: armv5te/OP_UNUSED_33FF.S */ 8882/* File: armv5te/unused.S */ 8883 bl common_abort 8884 8885 8886/* ------------------------------ */ 8887 .balign 64 8888.L_OP_UNUSED_34FF: /* 0x134 */ 8889/* File: armv5te/OP_UNUSED_34FF.S */ 8890/* File: armv5te/unused.S */ 8891 bl common_abort 8892 8893 8894/* ------------------------------ */ 8895 .balign 64 8896.L_OP_UNUSED_35FF: /* 0x135 */ 8897/* File: armv5te/OP_UNUSED_35FF.S */ 8898/* File: armv5te/unused.S */ 8899 bl common_abort 8900 8901 8902/* ------------------------------ */ 8903 .balign 64 8904.L_OP_UNUSED_36FF: /* 0x136 */ 8905/* File: armv5te/OP_UNUSED_36FF.S */ 8906/* File: armv5te/unused.S */ 8907 bl common_abort 8908 8909 8910/* ------------------------------ */ 8911 .balign 64 8912.L_OP_UNUSED_37FF: /* 0x137 */ 8913/* File: armv5te/OP_UNUSED_37FF.S */ 8914/* File: armv5te/unused.S */ 8915 bl common_abort 8916 8917 8918/* ------------------------------ */ 8919 .balign 64 8920.L_OP_UNUSED_38FF: /* 0x138 */ 8921/* File: armv5te/OP_UNUSED_38FF.S */ 8922/* File: armv5te/unused.S */ 8923 bl common_abort 8924 8925 8926/* ------------------------------ */ 8927 .balign 64 8928.L_OP_UNUSED_39FF: /* 0x139 */ 8929/* File: armv5te/OP_UNUSED_39FF.S */ 8930/* File: armv5te/unused.S */ 8931 bl common_abort 8932 8933 8934/* ------------------------------ */ 8935 .balign 64 8936.L_OP_UNUSED_3AFF: /* 0x13a */ 8937/* File: armv5te/OP_UNUSED_3AFF.S */ 8938/* File: armv5te/unused.S */ 8939 bl common_abort 8940 8941 8942/* ------------------------------ */ 8943 .balign 64 8944.L_OP_UNUSED_3BFF: /* 0x13b */ 8945/* File: armv5te/OP_UNUSED_3BFF.S */ 8946/* File: armv5te/unused.S */ 8947 bl common_abort 8948 8949 8950/* ------------------------------ */ 8951 .balign 64 8952.L_OP_UNUSED_3CFF: /* 0x13c */ 8953/* File: armv5te/OP_UNUSED_3CFF.S */ 8954/* File: armv5te/unused.S */ 8955 bl common_abort 8956 8957 8958/* ------------------------------ */ 8959 .balign 64 8960.L_OP_UNUSED_3DFF: /* 0x13d */ 8961/* File: armv5te/OP_UNUSED_3DFF.S */ 8962/* File: armv5te/unused.S */ 8963 bl common_abort 8964 8965 8966/* ------------------------------ */ 8967 .balign 64 8968.L_OP_UNUSED_3EFF: /* 0x13e */ 8969/* File: armv5te/OP_UNUSED_3EFF.S */ 8970/* File: armv5te/unused.S */ 8971 bl common_abort 8972 8973 8974/* ------------------------------ */ 8975 .balign 64 8976.L_OP_UNUSED_3FFF: /* 0x13f */ 8977/* File: armv5te/OP_UNUSED_3FFF.S */ 8978/* File: armv5te/unused.S */ 8979 bl common_abort 8980 8981 8982/* ------------------------------ */ 8983 .balign 64 8984.L_OP_UNUSED_40FF: /* 0x140 */ 8985/* File: armv5te/OP_UNUSED_40FF.S */ 8986/* File: armv5te/unused.S */ 8987 bl common_abort 8988 8989 8990/* ------------------------------ */ 8991 .balign 64 8992.L_OP_UNUSED_41FF: /* 0x141 */ 8993/* File: armv5te/OP_UNUSED_41FF.S */ 8994/* File: armv5te/unused.S */ 8995 bl common_abort 8996 8997 8998/* ------------------------------ */ 8999 .balign 64 9000.L_OP_UNUSED_42FF: /* 0x142 */ 9001/* File: armv5te/OP_UNUSED_42FF.S */ 9002/* File: armv5te/unused.S */ 9003 bl common_abort 9004 9005 9006/* ------------------------------ */ 9007 .balign 64 9008.L_OP_UNUSED_43FF: /* 0x143 */ 9009/* File: armv5te/OP_UNUSED_43FF.S */ 9010/* File: armv5te/unused.S */ 9011 bl common_abort 9012 9013 9014/* ------------------------------ */ 9015 .balign 64 9016.L_OP_UNUSED_44FF: /* 0x144 */ 9017/* File: armv5te/OP_UNUSED_44FF.S */ 9018/* File: armv5te/unused.S */ 9019 bl common_abort 9020 9021 9022/* ------------------------------ */ 9023 .balign 64 9024.L_OP_UNUSED_45FF: /* 0x145 */ 9025/* File: armv5te/OP_UNUSED_45FF.S */ 9026/* File: armv5te/unused.S */ 9027 bl common_abort 9028 9029 9030/* ------------------------------ */ 9031 .balign 64 9032.L_OP_UNUSED_46FF: /* 0x146 */ 9033/* File: armv5te/OP_UNUSED_46FF.S */ 9034/* File: armv5te/unused.S */ 9035 bl common_abort 9036 9037 9038/* ------------------------------ */ 9039 .balign 64 9040.L_OP_UNUSED_47FF: /* 0x147 */ 9041/* File: armv5te/OP_UNUSED_47FF.S */ 9042/* File: armv5te/unused.S */ 9043 bl common_abort 9044 9045 9046/* ------------------------------ */ 9047 .balign 64 9048.L_OP_UNUSED_48FF: /* 0x148 */ 9049/* File: armv5te/OP_UNUSED_48FF.S */ 9050/* File: armv5te/unused.S */ 9051 bl common_abort 9052 9053 9054/* ------------------------------ */ 9055 .balign 64 9056.L_OP_UNUSED_49FF: /* 0x149 */ 9057/* File: armv5te/OP_UNUSED_49FF.S */ 9058/* File: armv5te/unused.S */ 9059 bl common_abort 9060 9061 9062/* ------------------------------ */ 9063 .balign 64 9064.L_OP_UNUSED_4AFF: /* 0x14a */ 9065/* File: armv5te/OP_UNUSED_4AFF.S */ 9066/* File: armv5te/unused.S */ 9067 bl common_abort 9068 9069 9070/* ------------------------------ */ 9071 .balign 64 9072.L_OP_UNUSED_4BFF: /* 0x14b */ 9073/* File: armv5te/OP_UNUSED_4BFF.S */ 9074/* File: armv5te/unused.S */ 9075 bl common_abort 9076 9077 9078/* ------------------------------ */ 9079 .balign 64 9080.L_OP_UNUSED_4CFF: /* 0x14c */ 9081/* File: armv5te/OP_UNUSED_4CFF.S */ 9082/* File: armv5te/unused.S */ 9083 bl common_abort 9084 9085 9086/* ------------------------------ */ 9087 .balign 64 9088.L_OP_UNUSED_4DFF: /* 0x14d */ 9089/* File: armv5te/OP_UNUSED_4DFF.S */ 9090/* File: armv5te/unused.S */ 9091 bl common_abort 9092 9093 9094/* ------------------------------ */ 9095 .balign 64 9096.L_OP_UNUSED_4EFF: /* 0x14e */ 9097/* File: armv5te/OP_UNUSED_4EFF.S */ 9098/* File: armv5te/unused.S */ 9099 bl common_abort 9100 9101 9102/* ------------------------------ */ 9103 .balign 64 9104.L_OP_UNUSED_4FFF: /* 0x14f */ 9105/* File: armv5te/OP_UNUSED_4FFF.S */ 9106/* File: armv5te/unused.S */ 9107 bl common_abort 9108 9109 9110/* ------------------------------ */ 9111 .balign 64 9112.L_OP_UNUSED_50FF: /* 0x150 */ 9113/* File: armv5te/OP_UNUSED_50FF.S */ 9114/* File: armv5te/unused.S */ 9115 bl common_abort 9116 9117 9118/* ------------------------------ */ 9119 .balign 64 9120.L_OP_UNUSED_51FF: /* 0x151 */ 9121/* File: armv5te/OP_UNUSED_51FF.S */ 9122/* File: armv5te/unused.S */ 9123 bl common_abort 9124 9125 9126/* ------------------------------ */ 9127 .balign 64 9128.L_OP_UNUSED_52FF: /* 0x152 */ 9129/* File: armv5te/OP_UNUSED_52FF.S */ 9130/* File: armv5te/unused.S */ 9131 bl common_abort 9132 9133 9134/* ------------------------------ */ 9135 .balign 64 9136.L_OP_UNUSED_53FF: /* 0x153 */ 9137/* File: armv5te/OP_UNUSED_53FF.S */ 9138/* File: armv5te/unused.S */ 9139 bl common_abort 9140 9141 9142/* ------------------------------ */ 9143 .balign 64 9144.L_OP_UNUSED_54FF: /* 0x154 */ 9145/* File: armv5te/OP_UNUSED_54FF.S */ 9146/* File: armv5te/unused.S */ 9147 bl common_abort 9148 9149 9150/* ------------------------------ */ 9151 .balign 64 9152.L_OP_UNUSED_55FF: /* 0x155 */ 9153/* File: armv5te/OP_UNUSED_55FF.S */ 9154/* File: armv5te/unused.S */ 9155 bl common_abort 9156 9157 9158/* ------------------------------ */ 9159 .balign 64 9160.L_OP_UNUSED_56FF: /* 0x156 */ 9161/* File: armv5te/OP_UNUSED_56FF.S */ 9162/* File: armv5te/unused.S */ 9163 bl common_abort 9164 9165 9166/* ------------------------------ */ 9167 .balign 64 9168.L_OP_UNUSED_57FF: /* 0x157 */ 9169/* File: armv5te/OP_UNUSED_57FF.S */ 9170/* File: armv5te/unused.S */ 9171 bl common_abort 9172 9173 9174/* ------------------------------ */ 9175 .balign 64 9176.L_OP_UNUSED_58FF: /* 0x158 */ 9177/* File: armv5te/OP_UNUSED_58FF.S */ 9178/* File: armv5te/unused.S */ 9179 bl common_abort 9180 9181 9182/* ------------------------------ */ 9183 .balign 64 9184.L_OP_UNUSED_59FF: /* 0x159 */ 9185/* File: armv5te/OP_UNUSED_59FF.S */ 9186/* File: armv5te/unused.S */ 9187 bl common_abort 9188 9189 9190/* ------------------------------ */ 9191 .balign 64 9192.L_OP_UNUSED_5AFF: /* 0x15a */ 9193/* File: armv5te/OP_UNUSED_5AFF.S */ 9194/* File: armv5te/unused.S */ 9195 bl common_abort 9196 9197 9198/* ------------------------------ */ 9199 .balign 64 9200.L_OP_UNUSED_5BFF: /* 0x15b */ 9201/* File: armv5te/OP_UNUSED_5BFF.S */ 9202/* File: armv5te/unused.S */ 9203 bl common_abort 9204 9205 9206/* ------------------------------ */ 9207 .balign 64 9208.L_OP_UNUSED_5CFF: /* 0x15c */ 9209/* File: armv5te/OP_UNUSED_5CFF.S */ 9210/* File: armv5te/unused.S */ 9211 bl common_abort 9212 9213 9214/* ------------------------------ */ 9215 .balign 64 9216.L_OP_UNUSED_5DFF: /* 0x15d */ 9217/* File: armv5te/OP_UNUSED_5DFF.S */ 9218/* File: armv5te/unused.S */ 9219 bl common_abort 9220 9221 9222/* ------------------------------ */ 9223 .balign 64 9224.L_OP_UNUSED_5EFF: /* 0x15e */ 9225/* File: armv5te/OP_UNUSED_5EFF.S */ 9226/* File: armv5te/unused.S */ 9227 bl common_abort 9228 9229 9230/* ------------------------------ */ 9231 .balign 64 9232.L_OP_UNUSED_5FFF: /* 0x15f */ 9233/* File: armv5te/OP_UNUSED_5FFF.S */ 9234/* File: armv5te/unused.S */ 9235 bl common_abort 9236 9237 9238/* ------------------------------ */ 9239 .balign 64 9240.L_OP_UNUSED_60FF: /* 0x160 */ 9241/* File: armv5te/OP_UNUSED_60FF.S */ 9242/* File: armv5te/unused.S */ 9243 bl common_abort 9244 9245 9246/* ------------------------------ */ 9247 .balign 64 9248.L_OP_UNUSED_61FF: /* 0x161 */ 9249/* File: armv5te/OP_UNUSED_61FF.S */ 9250/* File: armv5te/unused.S */ 9251 bl common_abort 9252 9253 9254/* ------------------------------ */ 9255 .balign 64 9256.L_OP_UNUSED_62FF: /* 0x162 */ 9257/* File: armv5te/OP_UNUSED_62FF.S */ 9258/* File: armv5te/unused.S */ 9259 bl common_abort 9260 9261 9262/* ------------------------------ */ 9263 .balign 64 9264.L_OP_UNUSED_63FF: /* 0x163 */ 9265/* File: armv5te/OP_UNUSED_63FF.S */ 9266/* File: armv5te/unused.S */ 9267 bl common_abort 9268 9269 9270/* ------------------------------ */ 9271 .balign 64 9272.L_OP_UNUSED_64FF: /* 0x164 */ 9273/* File: armv5te/OP_UNUSED_64FF.S */ 9274/* File: armv5te/unused.S */ 9275 bl common_abort 9276 9277 9278/* ------------------------------ */ 9279 .balign 64 9280.L_OP_UNUSED_65FF: /* 0x165 */ 9281/* File: armv5te/OP_UNUSED_65FF.S */ 9282/* File: armv5te/unused.S */ 9283 bl common_abort 9284 9285 9286/* ------------------------------ */ 9287 .balign 64 9288.L_OP_UNUSED_66FF: /* 0x166 */ 9289/* File: armv5te/OP_UNUSED_66FF.S */ 9290/* File: armv5te/unused.S */ 9291 bl common_abort 9292 9293 9294/* ------------------------------ */ 9295 .balign 64 9296.L_OP_UNUSED_67FF: /* 0x167 */ 9297/* File: armv5te/OP_UNUSED_67FF.S */ 9298/* File: armv5te/unused.S */ 9299 bl common_abort 9300 9301 9302/* ------------------------------ */ 9303 .balign 64 9304.L_OP_UNUSED_68FF: /* 0x168 */ 9305/* File: armv5te/OP_UNUSED_68FF.S */ 9306/* File: armv5te/unused.S */ 9307 bl common_abort 9308 9309 9310/* ------------------------------ */ 9311 .balign 64 9312.L_OP_UNUSED_69FF: /* 0x169 */ 9313/* File: armv5te/OP_UNUSED_69FF.S */ 9314/* File: armv5te/unused.S */ 9315 bl common_abort 9316 9317 9318/* ------------------------------ */ 9319 .balign 64 9320.L_OP_UNUSED_6AFF: /* 0x16a */ 9321/* File: armv5te/OP_UNUSED_6AFF.S */ 9322/* File: armv5te/unused.S */ 9323 bl common_abort 9324 9325 9326/* ------------------------------ */ 9327 .balign 64 9328.L_OP_UNUSED_6BFF: /* 0x16b */ 9329/* File: armv5te/OP_UNUSED_6BFF.S */ 9330/* File: armv5te/unused.S */ 9331 bl common_abort 9332 9333 9334/* ------------------------------ */ 9335 .balign 64 9336.L_OP_UNUSED_6CFF: /* 0x16c */ 9337/* File: armv5te/OP_UNUSED_6CFF.S */ 9338/* File: armv5te/unused.S */ 9339 bl common_abort 9340 9341 9342/* ------------------------------ */ 9343 .balign 64 9344.L_OP_UNUSED_6DFF: /* 0x16d */ 9345/* File: armv5te/OP_UNUSED_6DFF.S */ 9346/* File: armv5te/unused.S */ 9347 bl common_abort 9348 9349 9350/* ------------------------------ */ 9351 .balign 64 9352.L_OP_UNUSED_6EFF: /* 0x16e */ 9353/* File: armv5te/OP_UNUSED_6EFF.S */ 9354/* File: armv5te/unused.S */ 9355 bl common_abort 9356 9357 9358/* ------------------------------ */ 9359 .balign 64 9360.L_OP_UNUSED_6FFF: /* 0x16f */ 9361/* File: armv5te/OP_UNUSED_6FFF.S */ 9362/* File: armv5te/unused.S */ 9363 bl common_abort 9364 9365 9366/* ------------------------------ */ 9367 .balign 64 9368.L_OP_UNUSED_70FF: /* 0x170 */ 9369/* File: armv5te/OP_UNUSED_70FF.S */ 9370/* File: armv5te/unused.S */ 9371 bl common_abort 9372 9373 9374/* ------------------------------ */ 9375 .balign 64 9376.L_OP_UNUSED_71FF: /* 0x171 */ 9377/* File: armv5te/OP_UNUSED_71FF.S */ 9378/* File: armv5te/unused.S */ 9379 bl common_abort 9380 9381 9382/* ------------------------------ */ 9383 .balign 64 9384.L_OP_UNUSED_72FF: /* 0x172 */ 9385/* File: armv5te/OP_UNUSED_72FF.S */ 9386/* File: armv5te/unused.S */ 9387 bl common_abort 9388 9389 9390/* ------------------------------ */ 9391 .balign 64 9392.L_OP_UNUSED_73FF: /* 0x173 */ 9393/* File: armv5te/OP_UNUSED_73FF.S */ 9394/* File: armv5te/unused.S */ 9395 bl common_abort 9396 9397 9398/* ------------------------------ */ 9399 .balign 64 9400.L_OP_UNUSED_74FF: /* 0x174 */ 9401/* File: armv5te/OP_UNUSED_74FF.S */ 9402/* File: armv5te/unused.S */ 9403 bl common_abort 9404 9405 9406/* ------------------------------ */ 9407 .balign 64 9408.L_OP_UNUSED_75FF: /* 0x175 */ 9409/* File: armv5te/OP_UNUSED_75FF.S */ 9410/* File: armv5te/unused.S */ 9411 bl common_abort 9412 9413 9414/* ------------------------------ */ 9415 .balign 64 9416.L_OP_UNUSED_76FF: /* 0x176 */ 9417/* File: armv5te/OP_UNUSED_76FF.S */ 9418/* File: armv5te/unused.S */ 9419 bl common_abort 9420 9421 9422/* ------------------------------ */ 9423 .balign 64 9424.L_OP_UNUSED_77FF: /* 0x177 */ 9425/* File: armv5te/OP_UNUSED_77FF.S */ 9426/* File: armv5te/unused.S */ 9427 bl common_abort 9428 9429 9430/* ------------------------------ */ 9431 .balign 64 9432.L_OP_UNUSED_78FF: /* 0x178 */ 9433/* File: armv5te/OP_UNUSED_78FF.S */ 9434/* File: armv5te/unused.S */ 9435 bl common_abort 9436 9437 9438/* ------------------------------ */ 9439 .balign 64 9440.L_OP_UNUSED_79FF: /* 0x179 */ 9441/* File: armv5te/OP_UNUSED_79FF.S */ 9442/* File: armv5te/unused.S */ 9443 bl common_abort 9444 9445 9446/* ------------------------------ */ 9447 .balign 64 9448.L_OP_UNUSED_7AFF: /* 0x17a */ 9449/* File: armv5te/OP_UNUSED_7AFF.S */ 9450/* File: armv5te/unused.S */ 9451 bl common_abort 9452 9453 9454/* ------------------------------ */ 9455 .balign 64 9456.L_OP_UNUSED_7BFF: /* 0x17b */ 9457/* File: armv5te/OP_UNUSED_7BFF.S */ 9458/* File: armv5te/unused.S */ 9459 bl common_abort 9460 9461 9462/* ------------------------------ */ 9463 .balign 64 9464.L_OP_UNUSED_7CFF: /* 0x17c */ 9465/* File: armv5te/OP_UNUSED_7CFF.S */ 9466/* File: armv5te/unused.S */ 9467 bl common_abort 9468 9469 9470/* ------------------------------ */ 9471 .balign 64 9472.L_OP_UNUSED_7DFF: /* 0x17d */ 9473/* File: armv5te/OP_UNUSED_7DFF.S */ 9474/* File: armv5te/unused.S */ 9475 bl common_abort 9476 9477 9478/* ------------------------------ */ 9479 .balign 64 9480.L_OP_UNUSED_7EFF: /* 0x17e */ 9481/* File: armv5te/OP_UNUSED_7EFF.S */ 9482/* File: armv5te/unused.S */ 9483 bl common_abort 9484 9485 9486/* ------------------------------ */ 9487 .balign 64 9488.L_OP_UNUSED_7FFF: /* 0x17f */ 9489/* File: armv5te/OP_UNUSED_7FFF.S */ 9490/* File: armv5te/unused.S */ 9491 bl common_abort 9492 9493 9494/* ------------------------------ */ 9495 .balign 64 9496.L_OP_UNUSED_80FF: /* 0x180 */ 9497/* File: armv5te/OP_UNUSED_80FF.S */ 9498/* File: armv5te/unused.S */ 9499 bl common_abort 9500 9501 9502/* ------------------------------ */ 9503 .balign 64 9504.L_OP_UNUSED_81FF: /* 0x181 */ 9505/* File: armv5te/OP_UNUSED_81FF.S */ 9506/* File: armv5te/unused.S */ 9507 bl common_abort 9508 9509 9510/* ------------------------------ */ 9511 .balign 64 9512.L_OP_UNUSED_82FF: /* 0x182 */ 9513/* File: armv5te/OP_UNUSED_82FF.S */ 9514/* File: armv5te/unused.S */ 9515 bl common_abort 9516 9517 9518/* ------------------------------ */ 9519 .balign 64 9520.L_OP_UNUSED_83FF: /* 0x183 */ 9521/* File: armv5te/OP_UNUSED_83FF.S */ 9522/* File: armv5te/unused.S */ 9523 bl common_abort 9524 9525 9526/* ------------------------------ */ 9527 .balign 64 9528.L_OP_UNUSED_84FF: /* 0x184 */ 9529/* File: armv5te/OP_UNUSED_84FF.S */ 9530/* File: armv5te/unused.S */ 9531 bl common_abort 9532 9533 9534/* ------------------------------ */ 9535 .balign 64 9536.L_OP_UNUSED_85FF: /* 0x185 */ 9537/* File: armv5te/OP_UNUSED_85FF.S */ 9538/* File: armv5te/unused.S */ 9539 bl common_abort 9540 9541 9542/* ------------------------------ */ 9543 .balign 64 9544.L_OP_UNUSED_86FF: /* 0x186 */ 9545/* File: armv5te/OP_UNUSED_86FF.S */ 9546/* File: armv5te/unused.S */ 9547 bl common_abort 9548 9549 9550/* ------------------------------ */ 9551 .balign 64 9552.L_OP_UNUSED_87FF: /* 0x187 */ 9553/* File: armv5te/OP_UNUSED_87FF.S */ 9554/* File: armv5te/unused.S */ 9555 bl common_abort 9556 9557 9558/* ------------------------------ */ 9559 .balign 64 9560.L_OP_UNUSED_88FF: /* 0x188 */ 9561/* File: armv5te/OP_UNUSED_88FF.S */ 9562/* File: armv5te/unused.S */ 9563 bl common_abort 9564 9565 9566/* ------------------------------ */ 9567 .balign 64 9568.L_OP_UNUSED_89FF: /* 0x189 */ 9569/* File: armv5te/OP_UNUSED_89FF.S */ 9570/* File: armv5te/unused.S */ 9571 bl common_abort 9572 9573 9574/* ------------------------------ */ 9575 .balign 64 9576.L_OP_UNUSED_8AFF: /* 0x18a */ 9577/* File: armv5te/OP_UNUSED_8AFF.S */ 9578/* File: armv5te/unused.S */ 9579 bl common_abort 9580 9581 9582/* ------------------------------ */ 9583 .balign 64 9584.L_OP_UNUSED_8BFF: /* 0x18b */ 9585/* File: armv5te/OP_UNUSED_8BFF.S */ 9586/* File: armv5te/unused.S */ 9587 bl common_abort 9588 9589 9590/* ------------------------------ */ 9591 .balign 64 9592.L_OP_UNUSED_8CFF: /* 0x18c */ 9593/* File: armv5te/OP_UNUSED_8CFF.S */ 9594/* File: armv5te/unused.S */ 9595 bl common_abort 9596 9597 9598/* ------------------------------ */ 9599 .balign 64 9600.L_OP_UNUSED_8DFF: /* 0x18d */ 9601/* File: armv5te/OP_UNUSED_8DFF.S */ 9602/* File: armv5te/unused.S */ 9603 bl common_abort 9604 9605 9606/* ------------------------------ */ 9607 .balign 64 9608.L_OP_UNUSED_8EFF: /* 0x18e */ 9609/* File: armv5te/OP_UNUSED_8EFF.S */ 9610/* File: armv5te/unused.S */ 9611 bl common_abort 9612 9613 9614/* ------------------------------ */ 9615 .balign 64 9616.L_OP_UNUSED_8FFF: /* 0x18f */ 9617/* File: armv5te/OP_UNUSED_8FFF.S */ 9618/* File: armv5te/unused.S */ 9619 bl common_abort 9620 9621 9622/* ------------------------------ */ 9623 .balign 64 9624.L_OP_UNUSED_90FF: /* 0x190 */ 9625/* File: armv5te/OP_UNUSED_90FF.S */ 9626/* File: armv5te/unused.S */ 9627 bl common_abort 9628 9629 9630/* ------------------------------ */ 9631 .balign 64 9632.L_OP_UNUSED_91FF: /* 0x191 */ 9633/* File: armv5te/OP_UNUSED_91FF.S */ 9634/* File: armv5te/unused.S */ 9635 bl common_abort 9636 9637 9638/* ------------------------------ */ 9639 .balign 64 9640.L_OP_UNUSED_92FF: /* 0x192 */ 9641/* File: armv5te/OP_UNUSED_92FF.S */ 9642/* File: armv5te/unused.S */ 9643 bl common_abort 9644 9645 9646/* ------------------------------ */ 9647 .balign 64 9648.L_OP_UNUSED_93FF: /* 0x193 */ 9649/* File: armv5te/OP_UNUSED_93FF.S */ 9650/* File: armv5te/unused.S */ 9651 bl common_abort 9652 9653 9654/* ------------------------------ */ 9655 .balign 64 9656.L_OP_UNUSED_94FF: /* 0x194 */ 9657/* File: armv5te/OP_UNUSED_94FF.S */ 9658/* File: armv5te/unused.S */ 9659 bl common_abort 9660 9661 9662/* ------------------------------ */ 9663 .balign 64 9664.L_OP_UNUSED_95FF: /* 0x195 */ 9665/* File: armv5te/OP_UNUSED_95FF.S */ 9666/* File: armv5te/unused.S */ 9667 bl common_abort 9668 9669 9670/* ------------------------------ */ 9671 .balign 64 9672.L_OP_UNUSED_96FF: /* 0x196 */ 9673/* File: armv5te/OP_UNUSED_96FF.S */ 9674/* File: armv5te/unused.S */ 9675 bl common_abort 9676 9677 9678/* ------------------------------ */ 9679 .balign 64 9680.L_OP_UNUSED_97FF: /* 0x197 */ 9681/* File: armv5te/OP_UNUSED_97FF.S */ 9682/* File: armv5te/unused.S */ 9683 bl common_abort 9684 9685 9686/* ------------------------------ */ 9687 .balign 64 9688.L_OP_UNUSED_98FF: /* 0x198 */ 9689/* File: armv5te/OP_UNUSED_98FF.S */ 9690/* File: armv5te/unused.S */ 9691 bl common_abort 9692 9693 9694/* ------------------------------ */ 9695 .balign 64 9696.L_OP_UNUSED_99FF: /* 0x199 */ 9697/* File: armv5te/OP_UNUSED_99FF.S */ 9698/* File: armv5te/unused.S */ 9699 bl common_abort 9700 9701 9702/* ------------------------------ */ 9703 .balign 64 9704.L_OP_UNUSED_9AFF: /* 0x19a */ 9705/* File: armv5te/OP_UNUSED_9AFF.S */ 9706/* File: armv5te/unused.S */ 9707 bl common_abort 9708 9709 9710/* ------------------------------ */ 9711 .balign 64 9712.L_OP_UNUSED_9BFF: /* 0x19b */ 9713/* File: armv5te/OP_UNUSED_9BFF.S */ 9714/* File: armv5te/unused.S */ 9715 bl common_abort 9716 9717 9718/* ------------------------------ */ 9719 .balign 64 9720.L_OP_UNUSED_9CFF: /* 0x19c */ 9721/* File: armv5te/OP_UNUSED_9CFF.S */ 9722/* File: armv5te/unused.S */ 9723 bl common_abort 9724 9725 9726/* ------------------------------ */ 9727 .balign 64 9728.L_OP_UNUSED_9DFF: /* 0x19d */ 9729/* File: armv5te/OP_UNUSED_9DFF.S */ 9730/* File: armv5te/unused.S */ 9731 bl common_abort 9732 9733 9734/* ------------------------------ */ 9735 .balign 64 9736.L_OP_UNUSED_9EFF: /* 0x19e */ 9737/* File: armv5te/OP_UNUSED_9EFF.S */ 9738/* File: armv5te/unused.S */ 9739 bl common_abort 9740 9741 9742/* ------------------------------ */ 9743 .balign 64 9744.L_OP_UNUSED_9FFF: /* 0x19f */ 9745/* File: armv5te/OP_UNUSED_9FFF.S */ 9746/* File: armv5te/unused.S */ 9747 bl common_abort 9748 9749 9750/* ------------------------------ */ 9751 .balign 64 9752.L_OP_UNUSED_A0FF: /* 0x1a0 */ 9753/* File: armv5te/OP_UNUSED_A0FF.S */ 9754/* File: armv5te/unused.S */ 9755 bl common_abort 9756 9757 9758/* ------------------------------ */ 9759 .balign 64 9760.L_OP_UNUSED_A1FF: /* 0x1a1 */ 9761/* File: armv5te/OP_UNUSED_A1FF.S */ 9762/* File: armv5te/unused.S */ 9763 bl common_abort 9764 9765 9766/* ------------------------------ */ 9767 .balign 64 9768.L_OP_UNUSED_A2FF: /* 0x1a2 */ 9769/* File: armv5te/OP_UNUSED_A2FF.S */ 9770/* File: armv5te/unused.S */ 9771 bl common_abort 9772 9773 9774/* ------------------------------ */ 9775 .balign 64 9776.L_OP_UNUSED_A3FF: /* 0x1a3 */ 9777/* File: armv5te/OP_UNUSED_A3FF.S */ 9778/* File: armv5te/unused.S */ 9779 bl common_abort 9780 9781 9782/* ------------------------------ */ 9783 .balign 64 9784.L_OP_UNUSED_A4FF: /* 0x1a4 */ 9785/* File: armv5te/OP_UNUSED_A4FF.S */ 9786/* File: armv5te/unused.S */ 9787 bl common_abort 9788 9789 9790/* ------------------------------ */ 9791 .balign 64 9792.L_OP_UNUSED_A5FF: /* 0x1a5 */ 9793/* File: armv5te/OP_UNUSED_A5FF.S */ 9794/* File: armv5te/unused.S */ 9795 bl common_abort 9796 9797 9798/* ------------------------------ */ 9799 .balign 64 9800.L_OP_UNUSED_A6FF: /* 0x1a6 */ 9801/* File: armv5te/OP_UNUSED_A6FF.S */ 9802/* File: armv5te/unused.S */ 9803 bl common_abort 9804 9805 9806/* ------------------------------ */ 9807 .balign 64 9808.L_OP_UNUSED_A7FF: /* 0x1a7 */ 9809/* File: armv5te/OP_UNUSED_A7FF.S */ 9810/* File: armv5te/unused.S */ 9811 bl common_abort 9812 9813 9814/* ------------------------------ */ 9815 .balign 64 9816.L_OP_UNUSED_A8FF: /* 0x1a8 */ 9817/* File: armv5te/OP_UNUSED_A8FF.S */ 9818/* File: armv5te/unused.S */ 9819 bl common_abort 9820 9821 9822/* ------------------------------ */ 9823 .balign 64 9824.L_OP_UNUSED_A9FF: /* 0x1a9 */ 9825/* File: armv5te/OP_UNUSED_A9FF.S */ 9826/* File: armv5te/unused.S */ 9827 bl common_abort 9828 9829 9830/* ------------------------------ */ 9831 .balign 64 9832.L_OP_UNUSED_AAFF: /* 0x1aa */ 9833/* File: armv5te/OP_UNUSED_AAFF.S */ 9834/* File: armv5te/unused.S */ 9835 bl common_abort 9836 9837 9838/* ------------------------------ */ 9839 .balign 64 9840.L_OP_UNUSED_ABFF: /* 0x1ab */ 9841/* File: armv5te/OP_UNUSED_ABFF.S */ 9842/* File: armv5te/unused.S */ 9843 bl common_abort 9844 9845 9846/* ------------------------------ */ 9847 .balign 64 9848.L_OP_UNUSED_ACFF: /* 0x1ac */ 9849/* File: armv5te/OP_UNUSED_ACFF.S */ 9850/* File: armv5te/unused.S */ 9851 bl common_abort 9852 9853 9854/* ------------------------------ */ 9855 .balign 64 9856.L_OP_UNUSED_ADFF: /* 0x1ad */ 9857/* File: armv5te/OP_UNUSED_ADFF.S */ 9858/* File: armv5te/unused.S */ 9859 bl common_abort 9860 9861 9862/* ------------------------------ */ 9863 .balign 64 9864.L_OP_UNUSED_AEFF: /* 0x1ae */ 9865/* File: armv5te/OP_UNUSED_AEFF.S */ 9866/* File: armv5te/unused.S */ 9867 bl common_abort 9868 9869 9870/* ------------------------------ */ 9871 .balign 64 9872.L_OP_UNUSED_AFFF: /* 0x1af */ 9873/* File: armv5te/OP_UNUSED_AFFF.S */ 9874/* File: armv5te/unused.S */ 9875 bl common_abort 9876 9877 9878/* ------------------------------ */ 9879 .balign 64 9880.L_OP_UNUSED_B0FF: /* 0x1b0 */ 9881/* File: armv5te/OP_UNUSED_B0FF.S */ 9882/* File: armv5te/unused.S */ 9883 bl common_abort 9884 9885 9886/* ------------------------------ */ 9887 .balign 64 9888.L_OP_UNUSED_B1FF: /* 0x1b1 */ 9889/* File: armv5te/OP_UNUSED_B1FF.S */ 9890/* File: armv5te/unused.S */ 9891 bl common_abort 9892 9893 9894/* ------------------------------ */ 9895 .balign 64 9896.L_OP_UNUSED_B2FF: /* 0x1b2 */ 9897/* File: armv5te/OP_UNUSED_B2FF.S */ 9898/* File: armv5te/unused.S */ 9899 bl common_abort 9900 9901 9902/* ------------------------------ */ 9903 .balign 64 9904.L_OP_UNUSED_B3FF: /* 0x1b3 */ 9905/* File: armv5te/OP_UNUSED_B3FF.S */ 9906/* File: armv5te/unused.S */ 9907 bl common_abort 9908 9909 9910/* ------------------------------ */ 9911 .balign 64 9912.L_OP_UNUSED_B4FF: /* 0x1b4 */ 9913/* File: armv5te/OP_UNUSED_B4FF.S */ 9914/* File: armv5te/unused.S */ 9915 bl common_abort 9916 9917 9918/* ------------------------------ */ 9919 .balign 64 9920.L_OP_UNUSED_B5FF: /* 0x1b5 */ 9921/* File: armv5te/OP_UNUSED_B5FF.S */ 9922/* File: armv5te/unused.S */ 9923 bl common_abort 9924 9925 9926/* ------------------------------ */ 9927 .balign 64 9928.L_OP_UNUSED_B6FF: /* 0x1b6 */ 9929/* File: armv5te/OP_UNUSED_B6FF.S */ 9930/* File: armv5te/unused.S */ 9931 bl common_abort 9932 9933 9934/* ------------------------------ */ 9935 .balign 64 9936.L_OP_UNUSED_B7FF: /* 0x1b7 */ 9937/* File: armv5te/OP_UNUSED_B7FF.S */ 9938/* File: armv5te/unused.S */ 9939 bl common_abort 9940 9941 9942/* ------------------------------ */ 9943 .balign 64 9944.L_OP_UNUSED_B8FF: /* 0x1b8 */ 9945/* File: armv5te/OP_UNUSED_B8FF.S */ 9946/* File: armv5te/unused.S */ 9947 bl common_abort 9948 9949 9950/* ------------------------------ */ 9951 .balign 64 9952.L_OP_UNUSED_B9FF: /* 0x1b9 */ 9953/* File: armv5te/OP_UNUSED_B9FF.S */ 9954/* File: armv5te/unused.S */ 9955 bl common_abort 9956 9957 9958/* ------------------------------ */ 9959 .balign 64 9960.L_OP_UNUSED_BAFF: /* 0x1ba */ 9961/* File: armv5te/OP_UNUSED_BAFF.S */ 9962/* File: armv5te/unused.S */ 9963 bl common_abort 9964 9965 9966/* ------------------------------ */ 9967 .balign 64 9968.L_OP_UNUSED_BBFF: /* 0x1bb */ 9969/* File: armv5te/OP_UNUSED_BBFF.S */ 9970/* File: armv5te/unused.S */ 9971 bl common_abort 9972 9973 9974/* ------------------------------ */ 9975 .balign 64 9976.L_OP_UNUSED_BCFF: /* 0x1bc */ 9977/* File: armv5te/OP_UNUSED_BCFF.S */ 9978/* File: armv5te/unused.S */ 9979 bl common_abort 9980 9981 9982/* ------------------------------ */ 9983 .balign 64 9984.L_OP_UNUSED_BDFF: /* 0x1bd */ 9985/* File: armv5te/OP_UNUSED_BDFF.S */ 9986/* File: armv5te/unused.S */ 9987 bl common_abort 9988 9989 9990/* ------------------------------ */ 9991 .balign 64 9992.L_OP_UNUSED_BEFF: /* 0x1be */ 9993/* File: armv5te/OP_UNUSED_BEFF.S */ 9994/* File: armv5te/unused.S */ 9995 bl common_abort 9996 9997 9998/* ------------------------------ */ 9999 .balign 64 10000.L_OP_UNUSED_BFFF: /* 0x1bf */ 10001/* File: armv5te/OP_UNUSED_BFFF.S */ 10002/* File: armv5te/unused.S */ 10003 bl common_abort 10004 10005 10006/* ------------------------------ */ 10007 .balign 64 10008.L_OP_UNUSED_C0FF: /* 0x1c0 */ 10009/* File: armv5te/OP_UNUSED_C0FF.S */ 10010/* File: armv5te/unused.S */ 10011 bl common_abort 10012 10013 10014/* ------------------------------ */ 10015 .balign 64 10016.L_OP_UNUSED_C1FF: /* 0x1c1 */ 10017/* File: armv5te/OP_UNUSED_C1FF.S */ 10018/* File: armv5te/unused.S */ 10019 bl common_abort 10020 10021 10022/* ------------------------------ */ 10023 .balign 64 10024.L_OP_UNUSED_C2FF: /* 0x1c2 */ 10025/* File: armv5te/OP_UNUSED_C2FF.S */ 10026/* File: armv5te/unused.S */ 10027 bl common_abort 10028 10029 10030/* ------------------------------ */ 10031 .balign 64 10032.L_OP_UNUSED_C3FF: /* 0x1c3 */ 10033/* File: armv5te/OP_UNUSED_C3FF.S */ 10034/* File: armv5te/unused.S */ 10035 bl common_abort 10036 10037 10038/* ------------------------------ */ 10039 .balign 64 10040.L_OP_UNUSED_C4FF: /* 0x1c4 */ 10041/* File: armv5te/OP_UNUSED_C4FF.S */ 10042/* File: armv5te/unused.S */ 10043 bl common_abort 10044 10045 10046/* ------------------------------ */ 10047 .balign 64 10048.L_OP_UNUSED_C5FF: /* 0x1c5 */ 10049/* File: armv5te/OP_UNUSED_C5FF.S */ 10050/* File: armv5te/unused.S */ 10051 bl common_abort 10052 10053 10054/* ------------------------------ */ 10055 .balign 64 10056.L_OP_UNUSED_C6FF: /* 0x1c6 */ 10057/* File: armv5te/OP_UNUSED_C6FF.S */ 10058/* File: armv5te/unused.S */ 10059 bl common_abort 10060 10061 10062/* ------------------------------ */ 10063 .balign 64 10064.L_OP_UNUSED_C7FF: /* 0x1c7 */ 10065/* File: armv5te/OP_UNUSED_C7FF.S */ 10066/* File: armv5te/unused.S */ 10067 bl common_abort 10068 10069 10070/* ------------------------------ */ 10071 .balign 64 10072.L_OP_UNUSED_C8FF: /* 0x1c8 */ 10073/* File: armv5te/OP_UNUSED_C8FF.S */ 10074/* File: armv5te/unused.S */ 10075 bl common_abort 10076 10077 10078/* ------------------------------ */ 10079 .balign 64 10080.L_OP_UNUSED_C9FF: /* 0x1c9 */ 10081/* File: armv5te/OP_UNUSED_C9FF.S */ 10082/* File: armv5te/unused.S */ 10083 bl common_abort 10084 10085 10086/* ------------------------------ */ 10087 .balign 64 10088.L_OP_UNUSED_CAFF: /* 0x1ca */ 10089/* File: armv5te/OP_UNUSED_CAFF.S */ 10090/* File: armv5te/unused.S */ 10091 bl common_abort 10092 10093 10094/* ------------------------------ */ 10095 .balign 64 10096.L_OP_UNUSED_CBFF: /* 0x1cb */ 10097/* File: armv5te/OP_UNUSED_CBFF.S */ 10098/* File: armv5te/unused.S */ 10099 bl common_abort 10100 10101 10102/* ------------------------------ */ 10103 .balign 64 10104.L_OP_UNUSED_CCFF: /* 0x1cc */ 10105/* File: armv5te/OP_UNUSED_CCFF.S */ 10106/* File: armv5te/unused.S */ 10107 bl common_abort 10108 10109 10110/* ------------------------------ */ 10111 .balign 64 10112.L_OP_UNUSED_CDFF: /* 0x1cd */ 10113/* File: armv5te/OP_UNUSED_CDFF.S */ 10114/* File: armv5te/unused.S */ 10115 bl common_abort 10116 10117 10118/* ------------------------------ */ 10119 .balign 64 10120.L_OP_UNUSED_CEFF: /* 0x1ce */ 10121/* File: armv5te/OP_UNUSED_CEFF.S */ 10122/* File: armv5te/unused.S */ 10123 bl common_abort 10124 10125 10126/* ------------------------------ */ 10127 .balign 64 10128.L_OP_UNUSED_CFFF: /* 0x1cf */ 10129/* File: armv5te/OP_UNUSED_CFFF.S */ 10130/* File: armv5te/unused.S */ 10131 bl common_abort 10132 10133 10134/* ------------------------------ */ 10135 .balign 64 10136.L_OP_UNUSED_D0FF: /* 0x1d0 */ 10137/* File: armv5te/OP_UNUSED_D0FF.S */ 10138/* File: armv5te/unused.S */ 10139 bl common_abort 10140 10141 10142/* ------------------------------ */ 10143 .balign 64 10144.L_OP_UNUSED_D1FF: /* 0x1d1 */ 10145/* File: armv5te/OP_UNUSED_D1FF.S */ 10146/* File: armv5te/unused.S */ 10147 bl common_abort 10148 10149 10150/* ------------------------------ */ 10151 .balign 64 10152.L_OP_UNUSED_D2FF: /* 0x1d2 */ 10153/* File: armv5te/OP_UNUSED_D2FF.S */ 10154/* File: armv5te/unused.S */ 10155 bl common_abort 10156 10157 10158/* ------------------------------ */ 10159 .balign 64 10160.L_OP_UNUSED_D3FF: /* 0x1d3 */ 10161/* File: armv5te/OP_UNUSED_D3FF.S */ 10162/* File: armv5te/unused.S */ 10163 bl common_abort 10164 10165 10166/* ------------------------------ */ 10167 .balign 64 10168.L_OP_UNUSED_D4FF: /* 0x1d4 */ 10169/* File: armv5te/OP_UNUSED_D4FF.S */ 10170/* File: armv5te/unused.S */ 10171 bl common_abort 10172 10173 10174/* ------------------------------ */ 10175 .balign 64 10176.L_OP_UNUSED_D5FF: /* 0x1d5 */ 10177/* File: armv5te/OP_UNUSED_D5FF.S */ 10178/* File: armv5te/unused.S */ 10179 bl common_abort 10180 10181 10182/* ------------------------------ */ 10183 .balign 64 10184.L_OP_UNUSED_D6FF: /* 0x1d6 */ 10185/* File: armv5te/OP_UNUSED_D6FF.S */ 10186/* File: armv5te/unused.S */ 10187 bl common_abort 10188 10189 10190/* ------------------------------ */ 10191 .balign 64 10192.L_OP_UNUSED_D7FF: /* 0x1d7 */ 10193/* File: armv5te/OP_UNUSED_D7FF.S */ 10194/* File: armv5te/unused.S */ 10195 bl common_abort 10196 10197 10198/* ------------------------------ */ 10199 .balign 64 10200.L_OP_UNUSED_D8FF: /* 0x1d8 */ 10201/* File: armv5te/OP_UNUSED_D8FF.S */ 10202/* File: armv5te/unused.S */ 10203 bl common_abort 10204 10205 10206/* ------------------------------ */ 10207 .balign 64 10208.L_OP_UNUSED_D9FF: /* 0x1d9 */ 10209/* File: armv5te/OP_UNUSED_D9FF.S */ 10210/* File: armv5te/unused.S */ 10211 bl common_abort 10212 10213 10214/* ------------------------------ */ 10215 .balign 64 10216.L_OP_UNUSED_DAFF: /* 0x1da */ 10217/* File: armv5te/OP_UNUSED_DAFF.S */ 10218/* File: armv5te/unused.S */ 10219 bl common_abort 10220 10221 10222/* ------------------------------ */ 10223 .balign 64 10224.L_OP_UNUSED_DBFF: /* 0x1db */ 10225/* File: armv5te/OP_UNUSED_DBFF.S */ 10226/* File: armv5te/unused.S */ 10227 bl common_abort 10228 10229 10230/* ------------------------------ */ 10231 .balign 64 10232.L_OP_UNUSED_DCFF: /* 0x1dc */ 10233/* File: armv5te/OP_UNUSED_DCFF.S */ 10234/* File: armv5te/unused.S */ 10235 bl common_abort 10236 10237 10238/* ------------------------------ */ 10239 .balign 64 10240.L_OP_UNUSED_DDFF: /* 0x1dd */ 10241/* File: armv5te/OP_UNUSED_DDFF.S */ 10242/* File: armv5te/unused.S */ 10243 bl common_abort 10244 10245 10246/* ------------------------------ */ 10247 .balign 64 10248.L_OP_UNUSED_DEFF: /* 0x1de */ 10249/* File: armv5te/OP_UNUSED_DEFF.S */ 10250/* File: armv5te/unused.S */ 10251 bl common_abort 10252 10253 10254/* ------------------------------ */ 10255 .balign 64 10256.L_OP_UNUSED_DFFF: /* 0x1df */ 10257/* File: armv5te/OP_UNUSED_DFFF.S */ 10258/* File: armv5te/unused.S */ 10259 bl common_abort 10260 10261 10262/* ------------------------------ */ 10263 .balign 64 10264.L_OP_UNUSED_E0FF: /* 0x1e0 */ 10265/* File: armv5te/OP_UNUSED_E0FF.S */ 10266/* File: armv5te/unused.S */ 10267 bl common_abort 10268 10269 10270/* ------------------------------ */ 10271 .balign 64 10272.L_OP_UNUSED_E1FF: /* 0x1e1 */ 10273/* File: armv5te/OP_UNUSED_E1FF.S */ 10274/* File: armv5te/unused.S */ 10275 bl common_abort 10276 10277 10278/* ------------------------------ */ 10279 .balign 64 10280.L_OP_UNUSED_E2FF: /* 0x1e2 */ 10281/* File: armv5te/OP_UNUSED_E2FF.S */ 10282/* File: armv5te/unused.S */ 10283 bl common_abort 10284 10285 10286/* ------------------------------ */ 10287 .balign 64 10288.L_OP_UNUSED_E3FF: /* 0x1e3 */ 10289/* File: armv5te/OP_UNUSED_E3FF.S */ 10290/* File: armv5te/unused.S */ 10291 bl common_abort 10292 10293 10294/* ------------------------------ */ 10295 .balign 64 10296.L_OP_UNUSED_E4FF: /* 0x1e4 */ 10297/* File: armv5te/OP_UNUSED_E4FF.S */ 10298/* File: armv5te/unused.S */ 10299 bl common_abort 10300 10301 10302/* ------------------------------ */ 10303 .balign 64 10304.L_OP_UNUSED_E5FF: /* 0x1e5 */ 10305/* File: armv5te/OP_UNUSED_E5FF.S */ 10306/* File: armv5te/unused.S */ 10307 bl common_abort 10308 10309 10310/* ------------------------------ */ 10311 .balign 64 10312.L_OP_UNUSED_E6FF: /* 0x1e6 */ 10313/* File: armv5te/OP_UNUSED_E6FF.S */ 10314/* File: armv5te/unused.S */ 10315 bl common_abort 10316 10317 10318/* ------------------------------ */ 10319 .balign 64 10320.L_OP_UNUSED_E7FF: /* 0x1e7 */ 10321/* File: armv5te/OP_UNUSED_E7FF.S */ 10322/* File: armv5te/unused.S */ 10323 bl common_abort 10324 10325 10326/* ------------------------------ */ 10327 .balign 64 10328.L_OP_UNUSED_E8FF: /* 0x1e8 */ 10329/* File: armv5te/OP_UNUSED_E8FF.S */ 10330/* File: armv5te/unused.S */ 10331 bl common_abort 10332 10333 10334/* ------------------------------ */ 10335 .balign 64 10336.L_OP_UNUSED_E9FF: /* 0x1e9 */ 10337/* File: armv5te/OP_UNUSED_E9FF.S */ 10338/* File: armv5te/unused.S */ 10339 bl common_abort 10340 10341 10342/* ------------------------------ */ 10343 .balign 64 10344.L_OP_UNUSED_EAFF: /* 0x1ea */ 10345/* File: armv5te/OP_UNUSED_EAFF.S */ 10346/* File: armv5te/unused.S */ 10347 bl common_abort 10348 10349 10350/* ------------------------------ */ 10351 .balign 64 10352.L_OP_UNUSED_EBFF: /* 0x1eb */ 10353/* File: armv5te/OP_UNUSED_EBFF.S */ 10354/* File: armv5te/unused.S */ 10355 bl common_abort 10356 10357 10358/* ------------------------------ */ 10359 .balign 64 10360.L_OP_UNUSED_ECFF: /* 0x1ec */ 10361/* File: armv5te/OP_UNUSED_ECFF.S */ 10362/* File: armv5te/unused.S */ 10363 bl common_abort 10364 10365 10366/* ------------------------------ */ 10367 .balign 64 10368.L_OP_UNUSED_EDFF: /* 0x1ed */ 10369/* File: armv5te/OP_UNUSED_EDFF.S */ 10370/* File: armv5te/unused.S */ 10371 bl common_abort 10372 10373 10374/* ------------------------------ */ 10375 .balign 64 10376.L_OP_UNUSED_EEFF: /* 0x1ee */ 10377/* File: armv5te/OP_UNUSED_EEFF.S */ 10378/* File: armv5te/unused.S */ 10379 bl common_abort 10380 10381 10382/* ------------------------------ */ 10383 .balign 64 10384.L_OP_UNUSED_EFFF: /* 0x1ef */ 10385/* File: armv5te/OP_UNUSED_EFFF.S */ 10386/* File: armv5te/unused.S */ 10387 bl common_abort 10388 10389 10390/* ------------------------------ */ 10391 .balign 64 10392.L_OP_UNUSED_F0FF: /* 0x1f0 */ 10393/* File: armv5te/OP_UNUSED_F0FF.S */ 10394/* File: armv5te/unused.S */ 10395 bl common_abort 10396 10397 10398/* ------------------------------ */ 10399 .balign 64 10400.L_OP_UNUSED_F1FF: /* 0x1f1 */ 10401/* File: armv5te/OP_UNUSED_F1FF.S */ 10402/* File: armv5te/unused.S */ 10403 bl common_abort 10404 10405 10406/* ------------------------------ */ 10407 .balign 64 10408.L_OP_UNUSED_F2FF: /* 0x1f2 */ 10409/* File: armv5te/OP_UNUSED_F2FF.S */ 10410/* File: armv5te/unused.S */ 10411 bl common_abort 10412 10413 10414/* ------------------------------ */ 10415 .balign 64 10416.L_OP_UNUSED_F3FF: /* 0x1f3 */ 10417/* File: armv5te/OP_UNUSED_F3FF.S */ 10418/* File: armv5te/unused.S */ 10419 bl common_abort 10420 10421 10422/* ------------------------------ */ 10423 .balign 64 10424.L_OP_UNUSED_F4FF: /* 0x1f4 */ 10425/* File: armv5te/OP_UNUSED_F4FF.S */ 10426/* File: armv5te/unused.S */ 10427 bl common_abort 10428 10429 10430/* ------------------------------ */ 10431 .balign 64 10432.L_OP_UNUSED_F5FF: /* 0x1f5 */ 10433/* File: armv5te/OP_UNUSED_F5FF.S */ 10434/* File: armv5te/unused.S */ 10435 bl common_abort 10436 10437 10438/* ------------------------------ */ 10439 .balign 64 10440.L_OP_UNUSED_F6FF: /* 0x1f6 */ 10441/* File: armv5te/OP_UNUSED_F6FF.S */ 10442/* File: armv5te/unused.S */ 10443 bl common_abort 10444 10445 10446/* ------------------------------ */ 10447 .balign 64 10448.L_OP_UNUSED_F7FF: /* 0x1f7 */ 10449/* File: armv5te/OP_UNUSED_F7FF.S */ 10450/* File: armv5te/unused.S */ 10451 bl common_abort 10452 10453 10454/* ------------------------------ */ 10455 .balign 64 10456.L_OP_UNUSED_F8FF: /* 0x1f8 */ 10457/* File: armv5te/OP_UNUSED_F8FF.S */ 10458/* File: armv5te/unused.S */ 10459 bl common_abort 10460 10461 10462/* ------------------------------ */ 10463 .balign 64 10464.L_OP_UNUSED_F9FF: /* 0x1f9 */ 10465/* File: armv5te/OP_UNUSED_F9FF.S */ 10466/* File: armv5te/unused.S */ 10467 bl common_abort 10468 10469 10470/* ------------------------------ */ 10471 .balign 64 10472.L_OP_UNUSED_FAFF: /* 0x1fa */ 10473/* File: armv5te/OP_UNUSED_FAFF.S */ 10474/* File: armv5te/unused.S */ 10475 bl common_abort 10476 10477 10478/* ------------------------------ */ 10479 .balign 64 10480.L_OP_UNUSED_FBFF: /* 0x1fb */ 10481/* File: armv5te/OP_UNUSED_FBFF.S */ 10482/* File: armv5te/unused.S */ 10483 bl common_abort 10484 10485 10486/* ------------------------------ */ 10487 .balign 64 10488.L_OP_UNUSED_FCFF: /* 0x1fc */ 10489/* File: armv5te/OP_UNUSED_FCFF.S */ 10490/* File: armv5te/unused.S */ 10491 bl common_abort 10492 10493 10494/* ------------------------------ */ 10495 .balign 64 10496.L_OP_UNUSED_FDFF: /* 0x1fd */ 10497/* File: armv5te/OP_UNUSED_FDFF.S */ 10498/* File: armv5te/unused.S */ 10499 bl common_abort 10500 10501 10502/* ------------------------------ */ 10503 .balign 64 10504.L_OP_UNUSED_FEFF: /* 0x1fe */ 10505/* File: armv5te/OP_UNUSED_FEFF.S */ 10506/* File: armv5te/unused.S */ 10507 bl common_abort 10508 10509 10510/* ------------------------------ */ 10511 .balign 64 10512.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */ 10513/* File: armv5te/OP_THROW_VERIFICATION_ERROR_JUMBO.S */ 10514 /* 10515 * Handle a jumbo throw-verification-error instruction. This throws an 10516 * exception for an error discovered during verification. The 10517 * exception is indicated by BBBB, with some detail provided by AAAAAAAA. 10518 */ 10519 /* exop BBBB, Class@AAAAAAAA */ 10520 FETCH(r1, 1) @ r1<- aaaa (lo) 10521 FETCH(r2, 2) @ r2<- AAAA (hi) 10522 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10523 orr r2, r1, r2, lsl #16 @ r2<- AAAAaaaa 10524 EXPORT_PC() @ export the PC 10525 FETCH(r1, 3) @ r1<- BBBB 10526 bl dvmThrowVerificationError @ always throws 10527 b common_exceptionThrown @ handle exception 10528 10529 10530 .balign 64 10531 .size dvmAsmInstructionStart, .-dvmAsmInstructionStart 10532 .global dvmAsmInstructionEnd 10533dvmAsmInstructionEnd: 10534 10535/* 10536 * =========================================================================== 10537 * Sister implementations 10538 * =========================================================================== 10539 */ 10540 .global dvmAsmSisterStart 10541 .type dvmAsmSisterStart, %function 10542 .text 10543 .balign 4 10544dvmAsmSisterStart: 10545 10546/* continuation for OP_CONST_STRING */ 10547 10548 /* 10549 * Continuation if the String has not yet been resolved. 10550 * r1: BBBB (String ref) 10551 * r9: target register 10552 */ 10553.LOP_CONST_STRING_resolve: 10554 EXPORT_PC() 10555 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10556 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10557 bl dvmResolveString @ r0<- String reference 10558 cmp r0, #0 @ failed? 10559 beq common_exceptionThrown @ yup, handle the exception 10560 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10561 GET_INST_OPCODE(ip) @ extract opcode from rINST 10562 SET_VREG(r0, r9) @ vAA<- r0 10563 GOTO_OPCODE(ip) @ jump to next instruction 10564 10565/* continuation for OP_CONST_STRING_JUMBO */ 10566 10567 /* 10568 * Continuation if the String has not yet been resolved. 10569 * r1: BBBBBBBB (String ref) 10570 * r9: target register 10571 */ 10572.LOP_CONST_STRING_JUMBO_resolve: 10573 EXPORT_PC() 10574 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10575 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10576 bl dvmResolveString @ r0<- String reference 10577 cmp r0, #0 @ failed? 10578 beq common_exceptionThrown @ yup, handle the exception 10579 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 10580 GET_INST_OPCODE(ip) @ extract opcode from rINST 10581 SET_VREG(r0, r9) @ vAA<- r0 10582 GOTO_OPCODE(ip) @ jump to next instruction 10583 10584/* continuation for OP_CONST_CLASS */ 10585 10586 /* 10587 * Continuation if the Class has not yet been resolved. 10588 * r1: BBBB (Class ref) 10589 * r9: target register 10590 */ 10591.LOP_CONST_CLASS_resolve: 10592 EXPORT_PC() 10593 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10594 mov r2, #1 @ r2<- true 10595 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10596 bl dvmResolveClass @ r0<- Class reference 10597 cmp r0, #0 @ failed? 10598 beq common_exceptionThrown @ yup, handle the exception 10599 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10600 GET_INST_OPCODE(ip) @ extract opcode from rINST 10601 SET_VREG(r0, r9) @ vAA<- r0 10602 GOTO_OPCODE(ip) @ jump to next instruction 10603 10604/* continuation for OP_CHECK_CAST */ 10605 10606 /* 10607 * Trivial test failed, need to perform full check. This is common. 10608 * r0 holds obj->clazz 10609 * r1 holds desired class resolved from BBBB 10610 * r9 holds object 10611 */ 10612.LOP_CHECK_CAST_fullcheck: 10613 mov r10, r1 @ avoid ClassObject getting clobbered 10614 bl dvmInstanceofNonTrivial @ r0<- boolean result 10615 cmp r0, #0 @ failed? 10616 bne .LOP_CHECK_CAST_okay @ no, success 10617 10618 @ A cast has failed. We need to throw a ClassCastException. 10619 EXPORT_PC() @ about to throw 10620 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 10621 mov r1, r10 @ r1<- desired class 10622 bl dvmThrowClassCastException 10623 b common_exceptionThrown 10624 10625 /* 10626 * Resolution required. This is the least-likely path. 10627 * 10628 * r2 holds BBBB 10629 * r9 holds object 10630 */ 10631.LOP_CHECK_CAST_resolve: 10632 EXPORT_PC() @ resolve() could throw 10633 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 10634 mov r1, r2 @ r1<- BBBB 10635 mov r2, #0 @ r2<- false 10636 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 10637 bl dvmResolveClass @ r0<- resolved ClassObject ptr 10638 cmp r0, #0 @ got null? 10639 beq common_exceptionThrown @ yes, handle exception 10640 mov r1, r0 @ r1<- class resolved from BBB 10641 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 10642 b .LOP_CHECK_CAST_resolved @ pick up where we left off 10643 10644/* continuation for OP_INSTANCE_OF */ 10645 10646 /* 10647 * Trivial test failed, need to perform full check. This is common. 10648 * r0 holds obj->clazz 10649 * r1 holds class resolved from BBBB 10650 * r9 holds A 10651 */ 10652.LOP_INSTANCE_OF_fullcheck: 10653 bl dvmInstanceofNonTrivial @ r0<- boolean result 10654 @ fall through to OP_INSTANCE_OF_store 10655 10656 /* 10657 * r0 holds boolean result 10658 * r9 holds A 10659 */ 10660.LOP_INSTANCE_OF_store: 10661 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10662 SET_VREG(r0, r9) @ vA<- r0 10663 GET_INST_OPCODE(ip) @ extract opcode from rINST 10664 GOTO_OPCODE(ip) @ jump to next instruction 10665 10666 /* 10667 * Trivial test succeeded, save and bail. 10668 * r9 holds A 10669 */ 10670.LOP_INSTANCE_OF_trivial: 10671 mov r0, #1 @ indicate success 10672 @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper 10673 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10674 SET_VREG(r0, r9) @ vA<- r0 10675 GET_INST_OPCODE(ip) @ extract opcode from rINST 10676 GOTO_OPCODE(ip) @ jump to next instruction 10677 10678 /* 10679 * Resolution required. This is the least-likely path. 10680 * 10681 * r3 holds BBBB 10682 * r9 holds A 10683 */ 10684.LOP_INSTANCE_OF_resolve: 10685 EXPORT_PC() @ resolve() could throw 10686 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 10687 mov r1, r3 @ r1<- BBBB 10688 mov r2, #1 @ r2<- true 10689 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 10690 bl dvmResolveClass @ r0<- resolved ClassObject ptr 10691 cmp r0, #0 @ got null? 10692 beq common_exceptionThrown @ yes, handle exception 10693 mov r1, r0 @ r1<- class resolved from BBB 10694 mov r3, rINST, lsr #12 @ r3<- B 10695 GET_VREG(r0, r3) @ r0<- vB (object) 10696 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 10697 b .LOP_INSTANCE_OF_resolved @ pick up where we left off 10698 10699/* continuation for OP_NEW_INSTANCE */ 10700 10701 .balign 32 @ minimize cache lines 10702.LOP_NEW_INSTANCE_finish: @ r0=new object 10703 mov r3, rINST, lsr #8 @ r3<- AA 10704 cmp r0, #0 @ failed? 10705 beq common_exceptionThrown @ yes, handle the exception 10706 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10707 GET_INST_OPCODE(ip) @ extract opcode from rINST 10708 SET_VREG(r0, r3) @ vAA<- r0 10709 GOTO_OPCODE(ip) @ jump to next instruction 10710 10711 /* 10712 * Class initialization required. 10713 * 10714 * r0 holds class object 10715 */ 10716.LOP_NEW_INSTANCE_needinit: 10717 mov r9, r0 @ save r0 10718 bl dvmInitClass @ initialize class 10719 cmp r0, #0 @ check boolean result 10720 mov r0, r9 @ restore r0 10721 bne .LOP_NEW_INSTANCE_initialized @ success, continue 10722 b common_exceptionThrown @ failed, deal with init exception 10723 10724 /* 10725 * Resolution required. This is the least-likely path. 10726 * 10727 * r1 holds BBBB 10728 */ 10729.LOP_NEW_INSTANCE_resolve: 10730 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 10731 mov r2, #0 @ r2<- false 10732 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 10733 bl dvmResolveClass @ r0<- resolved ClassObject ptr 10734 cmp r0, #0 @ got null? 10735 bne .LOP_NEW_INSTANCE_resolved @ no, continue 10736 b common_exceptionThrown @ yes, handle exception 10737 10738.LstrInstantiationErrorPtr: 10739 .word .LstrInstantiationError 10740 10741/* continuation for OP_NEW_ARRAY */ 10742 10743 10744 /* 10745 * Resolve class. (This is an uncommon case.) 10746 * 10747 * r1 holds array length 10748 * r2 holds class ref CCCC 10749 */ 10750.LOP_NEW_ARRAY_resolve: 10751 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 10752 mov r9, r1 @ r9<- length (save) 10753 mov r1, r2 @ r1<- CCCC 10754 mov r2, #0 @ r2<- false 10755 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 10756 bl dvmResolveClass @ r0<- call(clazz, ref) 10757 cmp r0, #0 @ got null? 10758 mov r1, r9 @ r1<- length (restore) 10759 beq common_exceptionThrown @ yes, handle exception 10760 @ fall through to OP_NEW_ARRAY_finish 10761 10762 /* 10763 * Finish allocation. 10764 * 10765 * r0 holds class 10766 * r1 holds array length 10767 */ 10768.LOP_NEW_ARRAY_finish: 10769 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 10770 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 10771 cmp r0, #0 @ failed? 10772 mov r2, rINST, lsr #8 @ r2<- A+ 10773 beq common_exceptionThrown @ yes, handle the exception 10774 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10775 and r2, r2, #15 @ r2<- A 10776 GET_INST_OPCODE(ip) @ extract opcode from rINST 10777 SET_VREG(r0, r2) @ vA<- r0 10778 GOTO_OPCODE(ip) @ jump to next instruction 10779 10780/* continuation for OP_FILLED_NEW_ARRAY */ 10781 10782 /* 10783 * On entry: 10784 * r0 holds array class 10785 * r10 holds AA or BA 10786 */ 10787.LOP_FILLED_NEW_ARRAY_continue: 10788 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 10789 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 10790 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 10791 .if 0 10792 mov r1, r10 @ r1<- AA (length) 10793 .else 10794 mov r1, r10, lsr #4 @ r1<- B (length) 10795 .endif 10796 cmp rINST, #'I' @ array of ints? 10797 cmpne rINST, #'L' @ array of objects? 10798 cmpne rINST, #'[' @ array of arrays? 10799 mov r9, r1 @ save length in r9 10800 bne .LOP_FILLED_NEW_ARRAY_notimpl @ no, not handled yet 10801 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 10802 cmp r0, #0 @ null return? 10803 beq common_exceptionThrown @ alloc failed, handle exception 10804 10805 FETCH(r1, 2) @ r1<- FEDC or CCCC 10806 str r0, [rGLUE, #offGlue_retval] @ retval.l <- new array 10807 str rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type 10808 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 10809 subs r9, r9, #1 @ length--, check for neg 10810 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 10811 bmi 2f @ was zero, bail 10812 10813 @ copy values from registers into the array 10814 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 10815 .if 0 10816 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 108171: ldr r3, [r2], #4 @ r3<- *r2++ 10818 subs r9, r9, #1 @ count-- 10819 str r3, [r0], #4 @ *contents++ = vX 10820 bpl 1b 10821 @ continue at 2 10822 .else 10823 cmp r9, #4 @ length was initially 5? 10824 and r2, r10, #15 @ r2<- A 10825 bne 1f @ <= 4 args, branch 10826 GET_VREG(r3, r2) @ r3<- vA 10827 sub r9, r9, #1 @ count-- 10828 str r3, [r0, #16] @ contents[4] = vA 108291: and r2, r1, #15 @ r2<- F/E/D/C 10830 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 10831 mov r1, r1, lsr #4 @ r1<- next reg in low 4 10832 subs r9, r9, #1 @ count-- 10833 str r3, [r0], #4 @ *contents++ = vX 10834 bpl 1b 10835 @ continue at 2 10836 .endif 10837 108382: 10839 ldr r0, [rGLUE, #offGlue_retval] @ r0<- object 10840 ldr r1, [rGLUE, #offGlue_retval+4] @ r1<- type 10841 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 10842 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 10843 cmp r1, #'I' @ Is int array? 10844 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 10845 GOTO_OPCODE(ip) @ execute it 10846 10847 /* 10848 * Throw an exception indicating that we have not implemented this 10849 * mode of filled-new-array. 10850 */ 10851.LOP_FILLED_NEW_ARRAY_notimpl: 10852 ldr r0, .L_strInternalError 10853 ldr r1, .L_strFilledNewArrayNotImpl 10854 bl dvmThrowException 10855 b common_exceptionThrown 10856 10857 .if (!0) @ define in one or the other, not both 10858.L_strFilledNewArrayNotImpl: 10859 .word .LstrFilledNewArrayNotImpl 10860.L_strInternalError: 10861 .word .LstrInternalError 10862 .endif 10863 10864/* continuation for OP_FILLED_NEW_ARRAY_RANGE */ 10865 10866 /* 10867 * On entry: 10868 * r0 holds array class 10869 * r10 holds AA or BA 10870 */ 10871.LOP_FILLED_NEW_ARRAY_RANGE_continue: 10872 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 10873 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 10874 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 10875 .if 1 10876 mov r1, r10 @ r1<- AA (length) 10877 .else 10878 mov r1, r10, lsr #4 @ r1<- B (length) 10879 .endif 10880 cmp rINST, #'I' @ array of ints? 10881 cmpne rINST, #'L' @ array of objects? 10882 cmpne rINST, #'[' @ array of arrays? 10883 mov r9, r1 @ save length in r9 10884 bne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl @ no, not handled yet 10885 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 10886 cmp r0, #0 @ null return? 10887 beq common_exceptionThrown @ alloc failed, handle exception 10888 10889 FETCH(r1, 2) @ r1<- FEDC or CCCC 10890 str r0, [rGLUE, #offGlue_retval] @ retval.l <- new array 10891 str rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type 10892 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 10893 subs r9, r9, #1 @ length--, check for neg 10894 FETCH_ADVANCE_INST(3) @ advance to next instr, load rINST 10895 bmi 2f @ was zero, bail 10896 10897 @ copy values from registers into the array 10898 @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA 10899 .if 1 10900 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 109011: ldr r3, [r2], #4 @ r3<- *r2++ 10902 subs r9, r9, #1 @ count-- 10903 str r3, [r0], #4 @ *contents++ = vX 10904 bpl 1b 10905 @ continue at 2 10906 .else 10907 cmp r9, #4 @ length was initially 5? 10908 and r2, r10, #15 @ r2<- A 10909 bne 1f @ <= 4 args, branch 10910 GET_VREG(r3, r2) @ r3<- vA 10911 sub r9, r9, #1 @ count-- 10912 str r3, [r0, #16] @ contents[4] = vA 109131: and r2, r1, #15 @ r2<- F/E/D/C 10914 GET_VREG(r3, r2) @ r3<- vF/vE/vD/vC 10915 mov r1, r1, lsr #4 @ r1<- next reg in low 4 10916 subs r9, r9, #1 @ count-- 10917 str r3, [r0], #4 @ *contents++ = vX 10918 bpl 1b 10919 @ continue at 2 10920 .endif 10921 109222: 10923 ldr r0, [rGLUE, #offGlue_retval] @ r0<- object 10924 ldr r1, [rGLUE, #offGlue_retval+4] @ r1<- type 10925 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 10926 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 10927 cmp r1, #'I' @ Is int array? 10928 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 10929 GOTO_OPCODE(ip) @ execute it 10930 10931 /* 10932 * Throw an exception indicating that we have not implemented this 10933 * mode of filled-new-array. 10934 */ 10935.LOP_FILLED_NEW_ARRAY_RANGE_notimpl: 10936 ldr r0, .L_strInternalError 10937 ldr r1, .L_strFilledNewArrayNotImpl 10938 bl dvmThrowException 10939 b common_exceptionThrown 10940 10941 .if (!1) @ define in one or the other, not both 10942.L_strFilledNewArrayNotImpl: 10943 .word .LstrFilledNewArrayNotImpl 10944.L_strInternalError: 10945 .word .LstrInternalError 10946 .endif 10947 10948/* continuation for OP_CMPL_FLOAT */ 10949.LOP_CMPL_FLOAT_finish: 10950 SET_VREG(r0, r9) @ vAA<- r0 10951 GOTO_OPCODE(ip) @ jump to next instruction 10952 10953/* continuation for OP_CMPG_FLOAT */ 10954.LOP_CMPG_FLOAT_finish: 10955 SET_VREG(r0, r9) @ vAA<- r0 10956 GOTO_OPCODE(ip) @ jump to next instruction 10957 10958/* continuation for OP_CMPL_DOUBLE */ 10959.LOP_CMPL_DOUBLE_finish: 10960 SET_VREG(r0, r9) @ vAA<- r0 10961 GOTO_OPCODE(ip) @ jump to next instruction 10962 10963/* continuation for OP_CMPG_DOUBLE */ 10964.LOP_CMPG_DOUBLE_finish: 10965 SET_VREG(r0, r9) @ vAA<- r0 10966 GOTO_OPCODE(ip) @ jump to next instruction 10967 10968/* continuation for OP_CMP_LONG */ 10969 10970.LOP_CMP_LONG_less: 10971 mvn r1, #0 @ r1<- -1 10972 @ Want to cond code the next mov so we can avoid branch, but don't see it; 10973 @ instead, we just replicate the tail end. 10974 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10975 SET_VREG(r1, r9) @ vAA<- r1 10976 GET_INST_OPCODE(ip) @ extract opcode from rINST 10977 GOTO_OPCODE(ip) @ jump to next instruction 10978 10979.LOP_CMP_LONG_greater: 10980 mov r1, #1 @ r1<- 1 10981 @ fall through to _finish 10982 10983.LOP_CMP_LONG_finish: 10984 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10985 SET_VREG(r1, r9) @ vAA<- r1 10986 GET_INST_OPCODE(ip) @ extract opcode from rINST 10987 GOTO_OPCODE(ip) @ jump to next instruction 10988 10989/* continuation for OP_AGET_WIDE */ 10990 10991.LOP_AGET_WIDE_finish: 10992 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 10993 ldrd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 10994 add r9, rFP, r9, lsl #2 @ r9<- &fp[AA] 10995 GET_INST_OPCODE(ip) @ extract opcode from rINST 10996 stmia r9, {r2-r3} @ vAA/vAA+1<- r2/r3 10997 GOTO_OPCODE(ip) @ jump to next instruction 10998 10999/* continuation for OP_APUT_WIDE */ 11000 11001.LOP_APUT_WIDE_finish: 11002 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11003 ldmia r9, {r2-r3} @ r2/r3<- vAA/vAA+1 11004 GET_INST_OPCODE(ip) @ extract opcode from rINST 11005 strd r2, [r0, #offArrayObject_contents] @ r2/r3<- vBB[vCC] 11006 GOTO_OPCODE(ip) @ jump to next instruction 11007 11008/* continuation for OP_APUT_OBJECT */ 11009 /* 11010 * On entry: 11011 * rINST = vBB (arrayObj) 11012 * r9 = vAA (obj) 11013 * r10 = offset into array (vBB + vCC * width) 11014 */ 11015.LOP_APUT_OBJECT_finish: 11016 cmp r9, #0 @ storing null reference? 11017 beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks 11018 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 11019 ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz 11020 bl dvmCanPutArrayElement @ test object type vs. array type 11021 cmp r0, #0 @ okay? 11022 beq .LOP_APUT_OBJECT_throw @ no 11023 mov r1, rINST @ r1<- arrayObj 11024 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11025 ldr r2, [rGLUE, #offGlue_cardTable] @ get biased CT base 11026 add r10, #offArrayObject_contents @ r0<- pointer to slot 11027 GET_INST_OPCODE(ip) @ extract opcode from rINST 11028 str r9, [r10] @ vBB[vCC]<- vAA 11029 strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head 11030 GOTO_OPCODE(ip) @ jump to next instruction 11031.LOP_APUT_OBJECT_skip_check: 11032 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11033 GET_INST_OPCODE(ip) @ extract opcode from rINST 11034 str r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA 11035 GOTO_OPCODE(ip) @ jump to next instruction 11036.LOP_APUT_OBJECT_throw: 11037 @ The types don't match. We need to throw an ArrayStoreException. 11038 ldr r0, [r9, #offObject_clazz] 11039 ldr r1, [rINST, #offObject_clazz] 11040 EXPORT_PC() 11041 bl dvmThrowArrayStoreException 11042 b common_exceptionThrown 11043 11044/* continuation for OP_IGET */ 11045 11046 /* 11047 * Currently: 11048 * r0 holds resolved field 11049 * r9 holds object 11050 */ 11051.LOP_IGET_finish: 11052 @bl common_squeak0 11053 cmp r9, #0 @ check object for null 11054 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11055 beq common_errNullObject @ object was null 11056 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11057 ubfx r2, rINST, #8, #4 @ r2<- A 11058 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11059 GET_INST_OPCODE(ip) @ extract opcode from rINST 11060 SET_VREG(r0, r2) @ fp[A]<- r0 11061 GOTO_OPCODE(ip) @ jump to next instruction 11062 11063/* continuation for OP_IGET_WIDE */ 11064 11065 /* 11066 * Currently: 11067 * r0 holds resolved field 11068 * r9 holds object 11069 */ 11070.LOP_IGET_WIDE_finish: 11071 cmp r9, #0 @ check object for null 11072 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11073 beq common_errNullObject @ object was null 11074 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 11075 ubfx r2, rINST, #8, #4 @ r2<- A 11076 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11077 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 11078 GET_INST_OPCODE(ip) @ extract opcode from rINST 11079 stmia r3, {r0-r1} @ fp[A]<- r0/r1 11080 GOTO_OPCODE(ip) @ jump to next instruction 11081 11082/* continuation for OP_IGET_OBJECT */ 11083 11084 /* 11085 * Currently: 11086 * r0 holds resolved field 11087 * r9 holds object 11088 */ 11089.LOP_IGET_OBJECT_finish: 11090 @bl common_squeak0 11091 cmp r9, #0 @ check object for null 11092 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11093 beq common_errNullObject @ object was null 11094 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11095 @ no-op @ acquiring load 11096 mov r2, rINST, lsr #8 @ r2<- A+ 11097 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11098 and r2, r2, #15 @ r2<- A 11099 GET_INST_OPCODE(ip) @ extract opcode from rINST 11100 SET_VREG(r0, r2) @ fp[A]<- r0 11101 GOTO_OPCODE(ip) @ jump to next instruction 11102 11103/* continuation for OP_IGET_BOOLEAN */ 11104 11105 /* 11106 * Currently: 11107 * r0 holds resolved field 11108 * r9 holds object 11109 */ 11110.LOP_IGET_BOOLEAN_finish: 11111 @bl common_squeak1 11112 cmp r9, #0 @ check object for null 11113 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11114 beq common_errNullObject @ object was null 11115 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11116 @ no-op @ acquiring load 11117 mov r2, rINST, lsr #8 @ r2<- A+ 11118 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11119 and r2, r2, #15 @ r2<- A 11120 GET_INST_OPCODE(ip) @ extract opcode from rINST 11121 SET_VREG(r0, r2) @ fp[A]<- r0 11122 GOTO_OPCODE(ip) @ jump to next instruction 11123 11124/* continuation for OP_IGET_BYTE */ 11125 11126 /* 11127 * Currently: 11128 * r0 holds resolved field 11129 * r9 holds object 11130 */ 11131.LOP_IGET_BYTE_finish: 11132 @bl common_squeak2 11133 cmp r9, #0 @ check object for null 11134 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11135 beq common_errNullObject @ object was null 11136 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11137 @ no-op @ acquiring load 11138 mov r2, rINST, lsr #8 @ r2<- A+ 11139 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11140 and r2, r2, #15 @ r2<- A 11141 GET_INST_OPCODE(ip) @ extract opcode from rINST 11142 SET_VREG(r0, r2) @ fp[A]<- r0 11143 GOTO_OPCODE(ip) @ jump to next instruction 11144 11145/* continuation for OP_IGET_CHAR */ 11146 11147 /* 11148 * Currently: 11149 * r0 holds resolved field 11150 * r9 holds object 11151 */ 11152.LOP_IGET_CHAR_finish: 11153 @bl common_squeak3 11154 cmp r9, #0 @ check object for null 11155 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11156 beq common_errNullObject @ object was null 11157 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11158 @ no-op @ acquiring load 11159 mov r2, rINST, lsr #8 @ r2<- A+ 11160 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11161 and r2, r2, #15 @ r2<- A 11162 GET_INST_OPCODE(ip) @ extract opcode from rINST 11163 SET_VREG(r0, r2) @ fp[A]<- r0 11164 GOTO_OPCODE(ip) @ jump to next instruction 11165 11166/* continuation for OP_IGET_SHORT */ 11167 11168 /* 11169 * Currently: 11170 * r0 holds resolved field 11171 * r9 holds object 11172 */ 11173.LOP_IGET_SHORT_finish: 11174 @bl common_squeak4 11175 cmp r9, #0 @ check object for null 11176 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11177 beq common_errNullObject @ object was null 11178 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11179 @ no-op @ acquiring load 11180 mov r2, rINST, lsr #8 @ r2<- A+ 11181 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11182 and r2, r2, #15 @ r2<- A 11183 GET_INST_OPCODE(ip) @ extract opcode from rINST 11184 SET_VREG(r0, r2) @ fp[A]<- r0 11185 GOTO_OPCODE(ip) @ jump to next instruction 11186 11187/* continuation for OP_IPUT */ 11188 11189 /* 11190 * Currently: 11191 * r0 holds resolved field 11192 * r9 holds object 11193 */ 11194.LOP_IPUT_finish: 11195 @bl common_squeak0 11196 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11197 ubfx r1, rINST, #8, #4 @ r1<- A 11198 cmp r9, #0 @ check object for null 11199 GET_VREG(r0, r1) @ r0<- fp[A] 11200 beq common_errNullObject @ object was null 11201 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11202 GET_INST_OPCODE(ip) @ extract opcode from rINST 11203 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11204 GOTO_OPCODE(ip) @ jump to next instruction 11205 11206/* continuation for OP_IPUT_WIDE */ 11207 11208 /* 11209 * Currently: 11210 * r0 holds resolved field 11211 * r9 holds object 11212 */ 11213.LOP_IPUT_WIDE_finish: 11214 ubfx r2, rINST, #8, #4 @ r2<- A 11215 cmp r9, #0 @ check object for null 11216 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11217 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 11218 beq common_errNullObject @ object was null 11219 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11220 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 11221 GET_INST_OPCODE(ip) @ extract opcode from rINST 11222 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0 11223 GOTO_OPCODE(ip) @ jump to next instruction 11224 11225/* continuation for OP_IPUT_OBJECT */ 11226 11227 /* 11228 * Currently: 11229 * r0 holds resolved field 11230 * r9 holds object 11231 */ 11232.LOP_IPUT_OBJECT_finish: 11233 @bl common_squeak0 11234 mov r1, rINST, lsr #8 @ r1<- A+ 11235 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11236 and r1, r1, #15 @ r1<- A 11237 cmp r9, #0 @ check object for null 11238 GET_VREG(r0, r1) @ r0<- fp[A] 11239 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 11240 beq common_errNullObject @ object was null 11241 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11242 GET_INST_OPCODE(ip) @ extract opcode from rINST 11243 @ no-op @ releasing store 11244 str r0, [r9, r3] @ obj.field (32 bits)<- r0 11245 cmp r0, #0 @ stored a null reference? 11246 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 11247 GOTO_OPCODE(ip) @ jump to next instruction 11248 11249/* continuation for OP_IPUT_BOOLEAN */ 11250 11251 /* 11252 * Currently: 11253 * r0 holds resolved field 11254 * r9 holds object 11255 */ 11256.LOP_IPUT_BOOLEAN_finish: 11257 @bl common_squeak1 11258 mov r1, rINST, lsr #8 @ r1<- A+ 11259 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11260 and r1, r1, #15 @ r1<- A 11261 cmp r9, #0 @ check object for null 11262 GET_VREG(r0, r1) @ r0<- fp[A] 11263 beq common_errNullObject @ object was null 11264 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11265 GET_INST_OPCODE(ip) @ extract opcode from rINST 11266 @ no-op @ releasing store 11267 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11268 GOTO_OPCODE(ip) @ jump to next instruction 11269 11270/* continuation for OP_IPUT_BYTE */ 11271 11272 /* 11273 * Currently: 11274 * r0 holds resolved field 11275 * r9 holds object 11276 */ 11277.LOP_IPUT_BYTE_finish: 11278 @bl common_squeak2 11279 mov r1, rINST, lsr #8 @ r1<- A+ 11280 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11281 and r1, r1, #15 @ r1<- A 11282 cmp r9, #0 @ check object for null 11283 GET_VREG(r0, r1) @ r0<- fp[A] 11284 beq common_errNullObject @ object was null 11285 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11286 GET_INST_OPCODE(ip) @ extract opcode from rINST 11287 @ no-op @ releasing store 11288 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11289 GOTO_OPCODE(ip) @ jump to next instruction 11290 11291/* continuation for OP_IPUT_CHAR */ 11292 11293 /* 11294 * Currently: 11295 * r0 holds resolved field 11296 * r9 holds object 11297 */ 11298.LOP_IPUT_CHAR_finish: 11299 @bl common_squeak3 11300 mov r1, rINST, lsr #8 @ r1<- A+ 11301 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11302 and r1, r1, #15 @ r1<- A 11303 cmp r9, #0 @ check object for null 11304 GET_VREG(r0, r1) @ r0<- fp[A] 11305 beq common_errNullObject @ object was null 11306 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11307 GET_INST_OPCODE(ip) @ extract opcode from rINST 11308 @ no-op @ releasing store 11309 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11310 GOTO_OPCODE(ip) @ jump to next instruction 11311 11312/* continuation for OP_IPUT_SHORT */ 11313 11314 /* 11315 * Currently: 11316 * r0 holds resolved field 11317 * r9 holds object 11318 */ 11319.LOP_IPUT_SHORT_finish: 11320 @bl common_squeak4 11321 mov r1, rINST, lsr #8 @ r1<- A+ 11322 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11323 and r1, r1, #15 @ r1<- A 11324 cmp r9, #0 @ check object for null 11325 GET_VREG(r0, r1) @ r0<- fp[A] 11326 beq common_errNullObject @ object was null 11327 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11328 GET_INST_OPCODE(ip) @ extract opcode from rINST 11329 @ no-op @ releasing store 11330 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11331 GOTO_OPCODE(ip) @ jump to next instruction 11332 11333/* continuation for OP_SGET */ 11334 11335 /* 11336 * Continuation if the field has not yet been resolved. 11337 * r1: BBBB field ref 11338 */ 11339.LOP_SGET_resolve: 11340 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11341 EXPORT_PC() @ resolve() could throw, so export now 11342 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11343 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11344 cmp r0, #0 @ success? 11345 bne .LOP_SGET_finish @ yes, finish 11346 b common_exceptionThrown @ no, handle exception 11347 11348/* continuation for OP_SGET_WIDE */ 11349 11350 /* 11351 * Continuation if the field has not yet been resolved. 11352 * r1: BBBB field ref 11353 * 11354 * Returns StaticField pointer in r0. 11355 */ 11356.LOP_SGET_WIDE_resolve: 11357 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11358 EXPORT_PC() @ resolve() could throw, so export now 11359 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11360 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11361 cmp r0, #0 @ success? 11362 bne .LOP_SGET_WIDE_finish @ yes, finish 11363 b common_exceptionThrown @ no, handle exception 11364 11365/* continuation for OP_SGET_OBJECT */ 11366 11367 /* 11368 * Continuation if the field has not yet been resolved. 11369 * r1: BBBB field ref 11370 */ 11371.LOP_SGET_OBJECT_resolve: 11372 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11373 EXPORT_PC() @ resolve() could throw, so export now 11374 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11375 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11376 cmp r0, #0 @ success? 11377 bne .LOP_SGET_OBJECT_finish @ yes, finish 11378 b common_exceptionThrown @ no, handle exception 11379 11380/* continuation for OP_SGET_BOOLEAN */ 11381 11382 /* 11383 * Continuation if the field has not yet been resolved. 11384 * r1: BBBB field ref 11385 */ 11386.LOP_SGET_BOOLEAN_resolve: 11387 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11388 EXPORT_PC() @ resolve() could throw, so export now 11389 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11390 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11391 cmp r0, #0 @ success? 11392 bne .LOP_SGET_BOOLEAN_finish @ yes, finish 11393 b common_exceptionThrown @ no, handle exception 11394 11395/* continuation for OP_SGET_BYTE */ 11396 11397 /* 11398 * Continuation if the field has not yet been resolved. 11399 * r1: BBBB field ref 11400 */ 11401.LOP_SGET_BYTE_resolve: 11402 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11403 EXPORT_PC() @ resolve() could throw, so export now 11404 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11405 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11406 cmp r0, #0 @ success? 11407 bne .LOP_SGET_BYTE_finish @ yes, finish 11408 b common_exceptionThrown @ no, handle exception 11409 11410/* continuation for OP_SGET_CHAR */ 11411 11412 /* 11413 * Continuation if the field has not yet been resolved. 11414 * r1: BBBB field ref 11415 */ 11416.LOP_SGET_CHAR_resolve: 11417 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11418 EXPORT_PC() @ resolve() could throw, so export now 11419 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11420 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11421 cmp r0, #0 @ success? 11422 bne .LOP_SGET_CHAR_finish @ yes, finish 11423 b common_exceptionThrown @ no, handle exception 11424 11425/* continuation for OP_SGET_SHORT */ 11426 11427 /* 11428 * Continuation if the field has not yet been resolved. 11429 * r1: BBBB field ref 11430 */ 11431.LOP_SGET_SHORT_resolve: 11432 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11433 EXPORT_PC() @ resolve() could throw, so export now 11434 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11435 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11436 cmp r0, #0 @ success? 11437 bne .LOP_SGET_SHORT_finish @ yes, finish 11438 b common_exceptionThrown @ no, handle exception 11439 11440/* continuation for OP_SPUT */ 11441 11442 /* 11443 * Continuation if the field has not yet been resolved. 11444 * r1: BBBB field ref 11445 */ 11446.LOP_SPUT_resolve: 11447 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11448 EXPORT_PC() @ resolve() could throw, so export now 11449 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11450 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11451 cmp r0, #0 @ success? 11452 bne .LOP_SPUT_finish @ yes, finish 11453 b common_exceptionThrown @ no, handle exception 11454 11455/* continuation for OP_SPUT_WIDE */ 11456 11457 /* 11458 * Continuation if the field has not yet been resolved. 11459 * r1: BBBB field ref 11460 * r9: &fp[AA] 11461 * 11462 * Returns StaticField pointer in r2. 11463 */ 11464.LOP_SPUT_WIDE_resolve: 11465 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11466 EXPORT_PC() @ resolve() could throw, so export now 11467 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11468 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11469 cmp r0, #0 @ success? 11470 mov r2, r0 @ copy to r2 11471 bne .LOP_SPUT_WIDE_finish @ yes, finish 11472 b common_exceptionThrown @ no, handle exception 11473 11474/* continuation for OP_SPUT_OBJECT */ 11475.LOP_SPUT_OBJECT_finish: @ field ptr in r0 11476 mov r2, rINST, lsr #8 @ r2<- AA 11477 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11478 GET_VREG(r1, r2) @ r1<- fp[AA] 11479 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 11480 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 11481 GET_INST_OPCODE(ip) @ extract opcode from rINST 11482 @ no-op @ releasing store 11483 str r1, [r0, #offStaticField_value] @ field<- vAA 11484 cmp r1, #0 @ stored a null object? 11485 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 11486 GOTO_OPCODE(ip) @ jump to next instruction 11487 11488/* continuation for OP_SPUT_BOOLEAN */ 11489 11490 /* 11491 * Continuation if the field has not yet been resolved. 11492 * r1: BBBB field ref 11493 */ 11494.LOP_SPUT_BOOLEAN_resolve: 11495 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11496 EXPORT_PC() @ resolve() could throw, so export now 11497 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11498 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11499 cmp r0, #0 @ success? 11500 bne .LOP_SPUT_BOOLEAN_finish @ yes, finish 11501 b common_exceptionThrown @ no, handle exception 11502 11503/* continuation for OP_SPUT_BYTE */ 11504 11505 /* 11506 * Continuation if the field has not yet been resolved. 11507 * r1: BBBB field ref 11508 */ 11509.LOP_SPUT_BYTE_resolve: 11510 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11511 EXPORT_PC() @ resolve() could throw, so export now 11512 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11513 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11514 cmp r0, #0 @ success? 11515 bne .LOP_SPUT_BYTE_finish @ yes, finish 11516 b common_exceptionThrown @ no, handle exception 11517 11518/* continuation for OP_SPUT_CHAR */ 11519 11520 /* 11521 * Continuation if the field has not yet been resolved. 11522 * r1: BBBB field ref 11523 */ 11524.LOP_SPUT_CHAR_resolve: 11525 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11526 EXPORT_PC() @ resolve() could throw, so export now 11527 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11528 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11529 cmp r0, #0 @ success? 11530 bne .LOP_SPUT_CHAR_finish @ yes, finish 11531 b common_exceptionThrown @ no, handle exception 11532 11533/* continuation for OP_SPUT_SHORT */ 11534 11535 /* 11536 * Continuation if the field has not yet been resolved. 11537 * r1: BBBB field ref 11538 */ 11539.LOP_SPUT_SHORT_resolve: 11540 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11541 EXPORT_PC() @ resolve() could throw, so export now 11542 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11543 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11544 cmp r0, #0 @ success? 11545 bne .LOP_SPUT_SHORT_finish @ yes, finish 11546 b common_exceptionThrown @ no, handle exception 11547 11548/* continuation for OP_INVOKE_VIRTUAL */ 11549 11550 /* 11551 * At this point: 11552 * r0 = resolved base method 11553 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 11554 */ 11555.LOP_INVOKE_VIRTUAL_continue: 11556 GET_VREG(r1, r10) @ r1<- "this" ptr 11557 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11558 cmp r1, #0 @ is "this" null? 11559 beq common_errNullObject @ null "this", throw exception 11560 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 11561 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 11562 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 11563 bl common_invokeMethodNoRange @ continue on 11564 11565/* continuation for OP_INVOKE_SUPER */ 11566 11567 /* 11568 * At this point: 11569 * r0 = resolved base method 11570 * r9 = method->clazz 11571 */ 11572.LOP_INVOKE_SUPER_continue: 11573 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 11574 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11575 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 11576 EXPORT_PC() @ must export for invoke 11577 cmp r2, r3 @ compare (methodIndex, vtableCount) 11578 bcs .LOP_INVOKE_SUPER_nsm @ method not present in superclass 11579 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 11580 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 11581 bl common_invokeMethodNoRange @ continue on 11582 11583.LOP_INVOKE_SUPER_resolve: 11584 mov r0, r9 @ r0<- method->clazz 11585 mov r2, #METHOD_VIRTUAL @ resolver method type 11586 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11587 cmp r0, #0 @ got null? 11588 bne .LOP_INVOKE_SUPER_continue @ no, continue 11589 b common_exceptionThrown @ yes, handle exception 11590 11591 /* 11592 * Throw a NoSuchMethodError with the method name as the message. 11593 * r0 = resolved base method 11594 */ 11595.LOP_INVOKE_SUPER_nsm: 11596 ldr r1, [r0, #offMethod_name] @ r1<- method name 11597 b common_errNoSuchMethod 11598 11599/* continuation for OP_INVOKE_DIRECT */ 11600 11601 /* 11602 * On entry: 11603 * r1 = reference (BBBB or CCCC) 11604 * r10 = "this" register 11605 */ 11606.LOP_INVOKE_DIRECT_resolve: 11607 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 11608 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 11609 mov r2, #METHOD_DIRECT @ resolver method type 11610 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11611 cmp r0, #0 @ got null? 11612 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 11613 bne .LOP_INVOKE_DIRECT_finish @ no, continue 11614 b common_exceptionThrown @ yes, handle exception 11615 11616/* continuation for OP_INVOKE_VIRTUAL_RANGE */ 11617 11618 /* 11619 * At this point: 11620 * r0 = resolved base method 11621 * r10 = C or CCCC (index of first arg, which is the "this" ptr) 11622 */ 11623.LOP_INVOKE_VIRTUAL_RANGE_continue: 11624 GET_VREG(r1, r10) @ r1<- "this" ptr 11625 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11626 cmp r1, #0 @ is "this" null? 11627 beq common_errNullObject @ null "this", throw exception 11628 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 11629 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 11630 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 11631 bl common_invokeMethodRange @ continue on 11632 11633/* continuation for OP_INVOKE_SUPER_RANGE */ 11634 11635 /* 11636 * At this point: 11637 * r0 = resolved base method 11638 * r9 = method->clazz 11639 */ 11640.LOP_INVOKE_SUPER_RANGE_continue: 11641 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 11642 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 11643 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 11644 EXPORT_PC() @ must export for invoke 11645 cmp r2, r3 @ compare (methodIndex, vtableCount) 11646 bcs .LOP_INVOKE_SUPER_RANGE_nsm @ method not present in superclass 11647 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 11648 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 11649 bl common_invokeMethodRange @ continue on 11650 11651.LOP_INVOKE_SUPER_RANGE_resolve: 11652 mov r0, r9 @ r0<- method->clazz 11653 mov r2, #METHOD_VIRTUAL @ resolver method type 11654 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11655 cmp r0, #0 @ got null? 11656 bne .LOP_INVOKE_SUPER_RANGE_continue @ no, continue 11657 b common_exceptionThrown @ yes, handle exception 11658 11659 /* 11660 * Throw a NoSuchMethodError with the method name as the message. 11661 * r0 = resolved base method 11662 */ 11663.LOP_INVOKE_SUPER_RANGE_nsm: 11664 ldr r1, [r0, #offMethod_name] @ r1<- method name 11665 b common_errNoSuchMethod 11666 11667/* continuation for OP_INVOKE_DIRECT_RANGE */ 11668 11669 /* 11670 * On entry: 11671 * r1 = reference (BBBB or CCCC) 11672 * r10 = "this" register 11673 */ 11674.LOP_INVOKE_DIRECT_RANGE_resolve: 11675 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 11676 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 11677 mov r2, #METHOD_DIRECT @ resolver method type 11678 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 11679 cmp r0, #0 @ got null? 11680 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 11681 bne .LOP_INVOKE_DIRECT_RANGE_finish @ no, continue 11682 b common_exceptionThrown @ yes, handle exception 11683 11684/* continuation for OP_FLOAT_TO_LONG */ 11685/* 11686 * Convert the float in r0 to a long in r0/r1. 11687 * 11688 * We have to clip values to long min/max per the specification. The 11689 * expected common case is a "reasonable" value that converts directly 11690 * to modest integer. The EABI convert function isn't doing this for us. 11691 */ 11692f2l_doconv: 11693 stmfd sp!, {r4, lr} 11694 mov r1, #0x5f000000 @ (float)maxlong 11695 mov r4, r0 11696 bl __aeabi_fcmpge @ is arg >= maxlong? 11697 cmp r0, #0 @ nonzero == yes 11698 mvnne r0, #0 @ return maxlong (7fffffff) 11699 mvnne r1, #0x80000000 11700 ldmnefd sp!, {r4, pc} 11701 11702 mov r0, r4 @ recover arg 11703 mov r1, #0xdf000000 @ (float)minlong 11704 bl __aeabi_fcmple @ is arg <= minlong? 11705 cmp r0, #0 @ nonzero == yes 11706 movne r0, #0 @ return minlong (80000000) 11707 movne r1, #0x80000000 11708 ldmnefd sp!, {r4, pc} 11709 11710 mov r0, r4 @ recover arg 11711 mov r1, r4 11712 bl __aeabi_fcmpeq @ is arg == self? 11713 cmp r0, #0 @ zero == no 11714 moveq r1, #0 @ return zero for NaN 11715 ldmeqfd sp!, {r4, pc} 11716 11717 mov r0, r4 @ recover arg 11718 bl __aeabi_f2lz @ convert float to long 11719 ldmfd sp!, {r4, pc} 11720 11721/* continuation for OP_DOUBLE_TO_LONG */ 11722/* 11723 * Convert the double in r0/r1 to a long in r0/r1. 11724 * 11725 * We have to clip values to long min/max per the specification. The 11726 * expected common case is a "reasonable" value that converts directly 11727 * to modest integer. The EABI convert function isn't doing this for us. 11728 */ 11729d2l_doconv: 11730 stmfd sp!, {r4, r5, lr} @ save regs 11731 mov r3, #0x43000000 @ maxlong, as a double (high word) 11732 add r3, #0x00e00000 @ 0x43e00000 11733 mov r2, #0 @ maxlong, as a double (low word) 11734 sub sp, sp, #4 @ align for EABI 11735 mov r4, r0 @ save a copy of r0 11736 mov r5, r1 @ and r1 11737 bl __aeabi_dcmpge @ is arg >= maxlong? 11738 cmp r0, #0 @ nonzero == yes 11739 mvnne r0, #0 @ return maxlong (7fffffffffffffff) 11740 mvnne r1, #0x80000000 11741 bne 1f 11742 11743 mov r0, r4 @ recover arg 11744 mov r1, r5 11745 mov r3, #0xc3000000 @ minlong, as a double (high word) 11746 add r3, #0x00e00000 @ 0xc3e00000 11747 mov r2, #0 @ minlong, as a double (low word) 11748 bl __aeabi_dcmple @ is arg <= minlong? 11749 cmp r0, #0 @ nonzero == yes 11750 movne r0, #0 @ return minlong (8000000000000000) 11751 movne r1, #0x80000000 11752 bne 1f 11753 11754 mov r0, r4 @ recover arg 11755 mov r1, r5 11756 mov r2, r4 @ compare against self 11757 mov r3, r5 11758 bl __aeabi_dcmpeq @ is arg == self? 11759 cmp r0, #0 @ zero == no 11760 moveq r1, #0 @ return zero for NaN 11761 beq 1f 11762 11763 mov r0, r4 @ recover arg 11764 mov r1, r5 11765 bl __aeabi_d2lz @ convert double to long 11766 117671: 11768 add sp, sp, #4 11769 ldmfd sp!, {r4, r5, pc} 11770 11771/* continuation for OP_MUL_LONG */ 11772 11773.LOP_MUL_LONG_finish: 11774 GET_INST_OPCODE(ip) @ extract opcode from rINST 11775 stmia r0, {r9-r10} @ vAA/vAA+1<- r9/r10 11776 GOTO_OPCODE(ip) @ jump to next instruction 11777 11778/* continuation for OP_SHL_LONG */ 11779 11780.LOP_SHL_LONG_finish: 11781 mov r0, r0, asl r2 @ r0<- r0 << r2 11782 GET_INST_OPCODE(ip) @ extract opcode from rINST 11783 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11784 GOTO_OPCODE(ip) @ jump to next instruction 11785 11786/* continuation for OP_SHR_LONG */ 11787 11788.LOP_SHR_LONG_finish: 11789 mov r1, r1, asr r2 @ r1<- r1 >> r2 11790 GET_INST_OPCODE(ip) @ extract opcode from rINST 11791 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11792 GOTO_OPCODE(ip) @ jump to next instruction 11793 11794/* continuation for OP_USHR_LONG */ 11795 11796.LOP_USHR_LONG_finish: 11797 mov r1, r1, lsr r2 @ r1<- r1 >>> r2 11798 GET_INST_OPCODE(ip) @ extract opcode from rINST 11799 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11800 GOTO_OPCODE(ip) @ jump to next instruction 11801 11802/* continuation for OP_SHL_LONG_2ADDR */ 11803 11804.LOP_SHL_LONG_2ADDR_finish: 11805 GET_INST_OPCODE(ip) @ extract opcode from rINST 11806 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11807 GOTO_OPCODE(ip) @ jump to next instruction 11808 11809/* continuation for OP_SHR_LONG_2ADDR */ 11810 11811.LOP_SHR_LONG_2ADDR_finish: 11812 GET_INST_OPCODE(ip) @ extract opcode from rINST 11813 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11814 GOTO_OPCODE(ip) @ jump to next instruction 11815 11816/* continuation for OP_USHR_LONG_2ADDR */ 11817 11818.LOP_USHR_LONG_2ADDR_finish: 11819 GET_INST_OPCODE(ip) @ extract opcode from rINST 11820 stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1 11821 GOTO_OPCODE(ip) @ jump to next instruction 11822 11823/* continuation for OP_IGET_VOLATILE */ 11824 11825 /* 11826 * Currently: 11827 * r0 holds resolved field 11828 * r9 holds object 11829 */ 11830.LOP_IGET_VOLATILE_finish: 11831 @bl common_squeak0 11832 cmp r9, #0 @ check object for null 11833 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11834 beq common_errNullObject @ object was null 11835 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11836 SMP_DMB @ acquiring load 11837 mov r2, rINST, lsr #8 @ r2<- A+ 11838 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11839 and r2, r2, #15 @ r2<- A 11840 GET_INST_OPCODE(ip) @ extract opcode from rINST 11841 SET_VREG(r0, r2) @ fp[A]<- r0 11842 GOTO_OPCODE(ip) @ jump to next instruction 11843 11844/* continuation for OP_IPUT_VOLATILE */ 11845 11846 /* 11847 * Currently: 11848 * r0 holds resolved field 11849 * r9 holds object 11850 */ 11851.LOP_IPUT_VOLATILE_finish: 11852 @bl common_squeak0 11853 mov r1, rINST, lsr #8 @ r1<- A+ 11854 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11855 and r1, r1, #15 @ r1<- A 11856 cmp r9, #0 @ check object for null 11857 GET_VREG(r0, r1) @ r0<- fp[A] 11858 beq common_errNullObject @ object was null 11859 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11860 GET_INST_OPCODE(ip) @ extract opcode from rINST 11861 SMP_DMB @ releasing store 11862 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 11863 GOTO_OPCODE(ip) @ jump to next instruction 11864 11865/* continuation for OP_SGET_VOLATILE */ 11866 11867 /* 11868 * Continuation if the field has not yet been resolved. 11869 * r1: BBBB field ref 11870 */ 11871.LOP_SGET_VOLATILE_resolve: 11872 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11873 EXPORT_PC() @ resolve() could throw, so export now 11874 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11875 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11876 cmp r0, #0 @ success? 11877 bne .LOP_SGET_VOLATILE_finish @ yes, finish 11878 b common_exceptionThrown @ no, handle exception 11879 11880/* continuation for OP_SPUT_VOLATILE */ 11881 11882 /* 11883 * Continuation if the field has not yet been resolved. 11884 * r1: BBBB field ref 11885 */ 11886.LOP_SPUT_VOLATILE_resolve: 11887 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11888 EXPORT_PC() @ resolve() could throw, so export now 11889 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11890 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11891 cmp r0, #0 @ success? 11892 bne .LOP_SPUT_VOLATILE_finish @ yes, finish 11893 b common_exceptionThrown @ no, handle exception 11894 11895/* continuation for OP_IGET_OBJECT_VOLATILE */ 11896 11897 /* 11898 * Currently: 11899 * r0 holds resolved field 11900 * r9 holds object 11901 */ 11902.LOP_IGET_OBJECT_VOLATILE_finish: 11903 @bl common_squeak0 11904 cmp r9, #0 @ check object for null 11905 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11906 beq common_errNullObject @ object was null 11907 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 11908 SMP_DMB @ acquiring load 11909 mov r2, rINST, lsr #8 @ r2<- A+ 11910 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11911 and r2, r2, #15 @ r2<- A 11912 GET_INST_OPCODE(ip) @ extract opcode from rINST 11913 SET_VREG(r0, r2) @ fp[A]<- r0 11914 GOTO_OPCODE(ip) @ jump to next instruction 11915 11916/* continuation for OP_IGET_WIDE_VOLATILE */ 11917 11918 /* 11919 * Currently: 11920 * r0 holds resolved field 11921 * r9 holds object 11922 */ 11923.LOP_IGET_WIDE_VOLATILE_finish: 11924 cmp r9, #0 @ check object for null 11925 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11926 beq common_errNullObject @ object was null 11927 .if 1 11928 add r0, r9, r3 @ r0<- address of field 11929 bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field 11930 .else 11931 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 11932 .endif 11933 mov r2, rINST, lsr #8 @ r2<- A+ 11934 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11935 and r2, r2, #15 @ r2<- A 11936 add r3, rFP, r2, lsl #2 @ r3<- &fp[A] 11937 GET_INST_OPCODE(ip) @ extract opcode from rINST 11938 stmia r3, {r0-r1} @ fp[A]<- r0/r1 11939 GOTO_OPCODE(ip) @ jump to next instruction 11940 11941/* continuation for OP_IPUT_WIDE_VOLATILE */ 11942 11943 /* 11944 * Currently: 11945 * r0 holds resolved field 11946 * r9 holds object 11947 */ 11948.LOP_IPUT_WIDE_VOLATILE_finish: 11949 mov r2, rINST, lsr #8 @ r2<- A+ 11950 cmp r9, #0 @ check object for null 11951 and r2, r2, #15 @ r2<- A 11952 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 11953 add r2, rFP, r2, lsl #2 @ r3<- &fp[A] 11954 beq common_errNullObject @ object was null 11955 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 11956 ldmia r2, {r0-r1} @ r0/r1<- fp[A] 11957 GET_INST_OPCODE(r10) @ extract opcode from rINST 11958 .if 1 11959 add r2, r9, r3 @ r2<- target address 11960 bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2 11961 .else 11962 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 11963 .endif 11964 GOTO_OPCODE(r10) @ jump to next instruction 11965 11966/* continuation for OP_SGET_WIDE_VOLATILE */ 11967 11968 /* 11969 * Continuation if the field has not yet been resolved. 11970 * r1: BBBB field ref 11971 * 11972 * Returns StaticField pointer in r0. 11973 */ 11974.LOP_SGET_WIDE_VOLATILE_resolve: 11975 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11976 EXPORT_PC() @ resolve() could throw, so export now 11977 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11978 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11979 cmp r0, #0 @ success? 11980 bne .LOP_SGET_WIDE_VOLATILE_finish @ yes, finish 11981 b common_exceptionThrown @ no, handle exception 11982 11983/* continuation for OP_SPUT_WIDE_VOLATILE */ 11984 11985 /* 11986 * Continuation if the field has not yet been resolved. 11987 * r1: BBBB field ref 11988 * r9: &fp[AA] 11989 * 11990 * Returns StaticField pointer in r2. 11991 */ 11992.LOP_SPUT_WIDE_VOLATILE_resolve: 11993 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 11994 EXPORT_PC() @ resolve() could throw, so export now 11995 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 11996 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 11997 cmp r0, #0 @ success? 11998 mov r2, r0 @ copy to r2 11999 bne .LOP_SPUT_WIDE_VOLATILE_finish @ yes, finish 12000 b common_exceptionThrown @ no, handle exception 12001 12002/* continuation for OP_EXECUTE_INLINE */ 12003 12004 /* 12005 * Extract args, call function. 12006 * r0 = #of args (0-4) 12007 * r10 = call index 12008 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 12009 * 12010 * Other ideas: 12011 * - Use a jump table from the main piece to jump directly into the 12012 * AND/LDR pairs. Costs a data load, saves a branch. 12013 * - Have five separate pieces that do the loading, so we can work the 12014 * interleave a little better. Increases code size. 12015 */ 12016.LOP_EXECUTE_INLINE_continue: 12017 rsb r0, r0, #4 @ r0<- 4-r0 12018 FETCH(r9, 2) @ r9<- FEDC 12019 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 12020 bl common_abort @ (skipped due to ARM prefetch) 120214: and ip, r9, #0xf000 @ isolate F 12022 ldr r3, [rFP, ip, lsr #10] @ r3<- vF (shift right 12, left 2) 120233: and ip, r9, #0x0f00 @ isolate E 12024 ldr r2, [rFP, ip, lsr #6] @ r2<- vE 120252: and ip, r9, #0x00f0 @ isolate D 12026 ldr r1, [rFP, ip, lsr #2] @ r1<- vD 120271: and ip, r9, #0x000f @ isolate C 12028 ldr r0, [rFP, ip, lsl #2] @ r0<- vC 120290: 12030 ldr r9, .LOP_EXECUTE_INLINE_table @ table of InlineOperation 12031 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 12032 @ (not reached) 12033 12034.LOP_EXECUTE_INLINE_table: 12035 .word gDvmInlineOpsTable 12036 12037/* continuation for OP_EXECUTE_INLINE_RANGE */ 12038 12039 /* 12040 * Extract args, call function. 12041 * r0 = #of args (0-4) 12042 * r10 = call index 12043 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 12044 */ 12045.LOP_EXECUTE_INLINE_RANGE_continue: 12046 rsb r0, r0, #4 @ r0<- 4-r0 12047 FETCH(r9, 2) @ r9<- CCCC 12048 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 12049 bl common_abort @ (skipped due to ARM prefetch) 120504: add ip, r9, #3 @ base+3 12051 GET_VREG(r3, ip) @ r3<- vBase[3] 120523: add ip, r9, #2 @ base+2 12053 GET_VREG(r2, ip) @ r2<- vBase[2] 120542: add ip, r9, #1 @ base+1 12055 GET_VREG(r1, ip) @ r1<- vBase[1] 120561: add ip, r9, #0 @ (nop) 12057 GET_VREG(r0, ip) @ r0<- vBase[0] 120580: 12059 ldr r9, .LOP_EXECUTE_INLINE_RANGE_table @ table of InlineOperation 12060 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 12061 @ (not reached) 12062 12063.LOP_EXECUTE_INLINE_RANGE_table: 12064 .word gDvmInlineOpsTable 12065 12066/* continuation for OP_IPUT_OBJECT_VOLATILE */ 12067 12068 /* 12069 * Currently: 12070 * r0 holds resolved field 12071 * r9 holds object 12072 */ 12073.LOP_IPUT_OBJECT_VOLATILE_finish: 12074 @bl common_squeak0 12075 mov r1, rINST, lsr #8 @ r1<- A+ 12076 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12077 and r1, r1, #15 @ r1<- A 12078 cmp r9, #0 @ check object for null 12079 GET_VREG(r0, r1) @ r0<- fp[A] 12080 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12081 beq common_errNullObject @ object was null 12082 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12083 GET_INST_OPCODE(ip) @ extract opcode from rINST 12084 SMP_DMB @ releasing store 12085 str r0, [r9, r3] @ obj.field (32 bits)<- r0 12086 cmp r0, #0 @ stored a null reference? 12087 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 12088 GOTO_OPCODE(ip) @ jump to next instruction 12089 12090/* continuation for OP_SGET_OBJECT_VOLATILE */ 12091 12092 /* 12093 * Continuation if the field has not yet been resolved. 12094 * r1: BBBB field ref 12095 */ 12096.LOP_SGET_OBJECT_VOLATILE_resolve: 12097 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12098 EXPORT_PC() @ resolve() could throw, so export now 12099 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12100 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12101 cmp r0, #0 @ success? 12102 bne .LOP_SGET_OBJECT_VOLATILE_finish @ yes, finish 12103 b common_exceptionThrown @ no, handle exception 12104 12105/* continuation for OP_SPUT_OBJECT_VOLATILE */ 12106.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0 12107 mov r2, rINST, lsr #8 @ r2<- AA 12108 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 12109 GET_VREG(r1, r2) @ r1<- fp[AA] 12110 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12111 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 12112 GET_INST_OPCODE(ip) @ extract opcode from rINST 12113 SMP_DMB @ releasing store 12114 str r1, [r0, #offStaticField_value] @ field<- vAA 12115 cmp r1, #0 @ stored a null object? 12116 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 12117 GOTO_OPCODE(ip) @ jump to next instruction 12118 12119/* continuation for OP_CONST_CLASS_JUMBO */ 12120 12121 /* 12122 * Continuation if the Class has not yet been resolved. 12123 * r1: AAAAAAAA (Class ref) 12124 * r9: target register 12125 */ 12126.LOP_CONST_CLASS_JUMBO_resolve: 12127 EXPORT_PC() 12128 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 12129 mov r2, #1 @ r2<- true 12130 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 12131 bl dvmResolveClass @ r0<- Class reference 12132 cmp r0, #0 @ failed? 12133 beq common_exceptionThrown @ yup, handle the exception 12134 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12135 GET_INST_OPCODE(ip) @ extract opcode from rINST 12136 SET_VREG(r0, r9) @ vBBBB<- r0 12137 GOTO_OPCODE(ip) @ jump to next instruction 12138 12139/* continuation for OP_CHECK_CAST_JUMBO */ 12140 12141 /* 12142 * Trivial test failed, need to perform full check. This is common. 12143 * r0 holds obj->clazz 12144 * r1 holds desired class resolved from AAAAAAAA 12145 * r9 holds object 12146 */ 12147.LOP_CHECK_CAST_JUMBO_fullcheck: 12148 mov r10, r1 @ avoid ClassObject getting clobbered 12149 bl dvmInstanceofNonTrivial @ r0<- boolean result 12150 cmp r0, #0 @ failed? 12151 bne .LOP_CHECK_CAST_JUMBO_okay @ no, success 12152 12153 @ A cast has failed. We need to throw a ClassCastException. 12154 EXPORT_PC() @ about to throw 12155 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz (actual class) 12156 mov r1, r10 @ r1<- desired class 12157 bl dvmThrowClassCastException 12158 b common_exceptionThrown 12159 12160 /* 12161 * Advance PC and get the next opcode. 12162 */ 12163.LOP_CHECK_CAST_JUMBO_okay: 12164 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12165 GET_INST_OPCODE(ip) @ extract opcode from rINST 12166 GOTO_OPCODE(ip) @ jump to next instruction 12167 12168 /* 12169 * Resolution required. This is the least-likely path. 12170 * 12171 * r2 holds AAAAAAAA 12172 * r9 holds object 12173 */ 12174.LOP_CHECK_CAST_JUMBO_resolve: 12175 EXPORT_PC() @ resolve() could throw 12176 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12177 mov r1, r2 @ r1<- AAAAAAAA 12178 mov r2, #0 @ r2<- false 12179 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12180 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12181 cmp r0, #0 @ got null? 12182 beq common_exceptionThrown @ yes, handle exception 12183 mov r1, r0 @ r1<- class resolved from AAAAAAAA 12184 ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz 12185 b .LOP_CHECK_CAST_JUMBO_resolved @ pick up where we left off 12186 12187/* continuation for OP_INSTANCE_OF_JUMBO */ 12188 12189 /* 12190 * Class resolved, determine type of check necessary. This is common. 12191 * r0 holds obj->clazz 12192 * r1 holds class resolved from AAAAAAAA 12193 * r9 holds BBBB 12194 */ 12195.LOP_INSTANCE_OF_JUMBO_resolved: 12196 cmp r0, r1 @ same class (trivial success)? 12197 beq .LOP_INSTANCE_OF_JUMBO_trivial @ yes, trivial finish 12198 @ fall through to OP_INSTANCE_OF_JUMBO_fullcheck 12199 12200 /* 12201 * Trivial test failed, need to perform full check. This is common. 12202 * r0 holds obj->clazz 12203 * r1 holds class resolved from AAAAAAAA 12204 * r9 holds BBBB 12205 */ 12206.LOP_INSTANCE_OF_JUMBO_fullcheck: 12207 bl dvmInstanceofNonTrivial @ r0<- boolean result 12208 @ fall through to OP_INSTANCE_OF_JUMBO_store 12209 12210 /* 12211 * r0 holds boolean result 12212 * r9 holds BBBB 12213 */ 12214.LOP_INSTANCE_OF_JUMBO_store: 12215 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12216 SET_VREG(r0, r9) @ vBBBB<- r0 12217 GET_INST_OPCODE(ip) @ extract opcode from rINST 12218 GOTO_OPCODE(ip) @ jump to next instruction 12219 12220 /* 12221 * Trivial test succeeded, save and bail. 12222 * r9 holds BBBB 12223 */ 12224.LOP_INSTANCE_OF_JUMBO_trivial: 12225 mov r0, #1 @ indicate success 12226 @ could b OP_INSTANCE_OF_JUMBO_store, but copying is faster and cheaper 12227 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12228 SET_VREG(r0, r9) @ vBBBB<- r0 12229 GET_INST_OPCODE(ip) @ extract opcode from rINST 12230 GOTO_OPCODE(ip) @ jump to next instruction 12231 12232 /* 12233 * Resolution required. This is the least-likely path. 12234 * 12235 * r3 holds AAAAAAAA 12236 * r9 holds BBBB 12237 */ 12238 12239.LOP_INSTANCE_OF_JUMBO_resolve: 12240 EXPORT_PC() @ resolve() could throw 12241 ldr r0, [rGLUE, #offGlue_method] @ r0<- glue->method 12242 mov r1, r3 @ r1<- AAAAAAAA 12243 mov r2, #1 @ r2<- true 12244 ldr r0, [r0, #offMethod_clazz] @ r0<- method->clazz 12245 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12246 cmp r0, #0 @ got null? 12247 beq common_exceptionThrown @ yes, handle exception 12248 FETCH(r3, 4) @ r3<- vCCCC 12249 mov r1, r0 @ r1<- class resolved from AAAAAAAA 12250 GET_VREG(r0, r3) @ r0<- vCCCC (object) 12251 ldr r0, [r0, #offObject_clazz] @ r0<- obj->clazz 12252 b .LOP_INSTANCE_OF_JUMBO_resolved @ pick up where we left off 12253 12254/* continuation for OP_NEW_INSTANCE_JUMBO */ 12255 12256 .balign 32 @ minimize cache lines 12257.LOP_NEW_INSTANCE_JUMBO_finish: @ r0=new object 12258 FETCH(r3, 3) @ r3<- BBBB 12259 cmp r0, #0 @ failed? 12260 beq common_exceptionThrown @ yes, handle the exception 12261 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12262 GET_INST_OPCODE(ip) @ extract opcode from rINST 12263 SET_VREG(r0, r3) @ vBBBB<- r0 12264 GOTO_OPCODE(ip) @ jump to next instruction 12265 12266 /* 12267 * Class initialization required. 12268 * 12269 * r0 holds class object 12270 */ 12271.LOP_NEW_INSTANCE_JUMBO_needinit: 12272 mov r9, r0 @ save r0 12273 bl dvmInitClass @ initialize class 12274 cmp r0, #0 @ check boolean result 12275 mov r0, r9 @ restore r0 12276 bne .LOP_NEW_INSTANCE_JUMBO_initialized @ success, continue 12277 b common_exceptionThrown @ failed, deal with init exception 12278 12279 /* 12280 * Resolution required. This is the least-likely path. 12281 * 12282 * r1 holds AAAAAAAA 12283 */ 12284.LOP_NEW_INSTANCE_JUMBO_resolve: 12285 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12286 mov r2, #0 @ r2<- false 12287 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12288 bl dvmResolveClass @ r0<- resolved ClassObject ptr 12289 cmp r0, #0 @ got null? 12290 bne .LOP_NEW_INSTANCE_JUMBO_resolved @ no, continue 12291 b common_exceptionThrown @ yes, handle exception 12292 12293/* continuation for OP_NEW_ARRAY_JUMBO */ 12294 12295 12296 /* 12297 * Resolve class. (This is an uncommon case.) 12298 * 12299 * r1 holds array length 12300 * r2 holds class ref AAAAAAAA 12301 */ 12302.LOP_NEW_ARRAY_JUMBO_resolve: 12303 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 12304 mov r9, r1 @ r9<- length (save) 12305 mov r1, r2 @ r1<- AAAAAAAA 12306 mov r2, #0 @ r2<- false 12307 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 12308 bl dvmResolveClass @ r0<- call(clazz, ref) 12309 cmp r0, #0 @ got null? 12310 mov r1, r9 @ r1<- length (restore) 12311 beq common_exceptionThrown @ yes, handle exception 12312 @ fall through to OP_NEW_ARRAY_JUMBO_finish 12313 12314 /* 12315 * Finish allocation. 12316 * 12317 * r0 holds class 12318 * r1 holds array length 12319 */ 12320.LOP_NEW_ARRAY_JUMBO_finish: 12321 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 12322 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 12323 cmp r0, #0 @ failed? 12324 FETCH(r2, 3) @ r2<- vBBBB 12325 beq common_exceptionThrown @ yes, handle the exception 12326 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12327 GET_INST_OPCODE(ip) @ extract opcode from rINST 12328 SET_VREG(r0, r2) @ vBBBB<- r0 12329 GOTO_OPCODE(ip) @ jump to next instruction 12330 12331/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */ 12332 12333 /* 12334 * On entry: 12335 * r0 holds array class 12336 */ 12337.LOP_FILLED_NEW_ARRAY_JUMBO_continue: 12338 ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor 12339 mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags 12340 ldrb rINST, [r3, #1] @ rINST<- descriptor[1] 12341 FETCH(r1, 3) @ r1<- BBBB (length) 12342 cmp rINST, #'I' @ array of ints? 12343 cmpne rINST, #'L' @ array of objects? 12344 cmpne rINST, #'[' @ array of arrays? 12345 mov r9, r1 @ save length in r9 12346 bne .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl @ no, not handled yet 12347 bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags) 12348 cmp r0, #0 @ null return? 12349 beq common_exceptionThrown @ alloc failed, handle exception 12350 12351 FETCH(r1, 4) @ r1<- CCCC 12352 str r0, [rGLUE, #offGlue_retval] @ retval.l <- new array 12353 str rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type 12354 add r0, r0, #offArrayObject_contents @ r0<- newArray->contents 12355 subs r9, r9, #1 @ length--, check for neg 12356 FETCH_ADVANCE_INST(5) @ advance to next instr, load rINST 12357 bmi 2f @ was zero, bail 12358 12359 @ copy values from registers into the array 12360 @ r0=array, r1=CCCC, r9=BBBB (length) 12361 add r2, rFP, r1, lsl #2 @ r2<- &fp[CCCC] 123621: ldr r3, [r2], #4 @ r3<- *r2++ 12363 subs r9, r9, #1 @ count-- 12364 str r3, [r0], #4 @ *contents++ = vX 12365 bpl 1b 12366 123672: ldr r0, [rGLUE, #offGlue_retval] @ r0<- object 12368 ldr r1, [rGLUE, #offGlue_retval+4] @ r1<- type 12369 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12370 GET_INST_OPCODE(ip) @ ip<- opcode from rINST 12371 cmp r1, #'I' @ Is int array? 12372 strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head 12373 GOTO_OPCODE(ip) @ execute it 12374 12375 /* 12376 * Throw an exception indicating that we have not implemented this 12377 * mode of filled-new-array. 12378 */ 12379.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl: 12380 ldr r0, .L_strInternalError 12381 ldr r1, .L_strFilledNewArrayNotImpl 12382 bl dvmThrowException 12383 b common_exceptionThrown 12384 12385/* continuation for OP_IGET_JUMBO */ 12386 12387 /* 12388 * Currently: 12389 * r0 holds resolved field 12390 * r9 holds object 12391 */ 12392.LOP_IGET_JUMBO_resolved: 12393 cmp r0, #0 @ resolution unsuccessful? 12394 beq common_exceptionThrown @ yes, throw exception 12395 @ fall through to OP_IGET_JUMBO_finish 12396 12397 /* 12398 * Currently: 12399 * r0 holds resolved field 12400 * r9 holds object 12401 */ 12402.LOP_IGET_JUMBO_finish: 12403 @bl common_squeak0 12404 cmp r9, #0 @ check object for null 12405 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12406 beq common_errNullObject @ object was null 12407 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12408 @ no-op @ acquiring load 12409 FETCH(r2, 3) @ r2<- BBBB 12410 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12411 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12412 GET_INST_OPCODE(ip) @ extract opcode from rINST 12413 GOTO_OPCODE(ip) @ jump to next instruction 12414 12415/* continuation for OP_IGET_WIDE_JUMBO */ 12416 12417 /* 12418 * Currently: 12419 * r0 holds resolved field 12420 * r9 holds object 12421 */ 12422.LOP_IGET_WIDE_JUMBO_resolved: 12423 cmp r0, #0 @ resolution unsuccessful? 12424 beq common_exceptionThrown @ yes, throw exception 12425 @ fall through to OP_IGET_WIDE_JUMBO_finish 12426 12427 /* 12428 * Currently: 12429 * r0 holds resolved field 12430 * r9 holds object 12431 */ 12432.LOP_IGET_WIDE_JUMBO_finish: 12433 cmp r9, #0 @ check object for null 12434 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12435 beq common_errNullObject @ object was null 12436 ldrd r0, [r9, r3] @ r0/r1<- obj.field (64-bit align ok) 12437 FETCH(r2, 3) @ r2<- BBBB 12438 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12439 add r3, rFP, r2, lsl #2 @ r3<- &fp[BBBB] 12440 GET_INST_OPCODE(ip) @ extract opcode from rINST 12441 stmia r3, {r0-r1} @ fp[BBBB]<- r0/r1 12442 GOTO_OPCODE(ip) @ jump to next instruction 12443 12444/* continuation for OP_IGET_OBJECT_JUMBO */ 12445 12446 /* 12447 * Currently: 12448 * r0 holds resolved field 12449 * r9 holds object 12450 */ 12451.LOP_IGET_OBJECT_JUMBO_resolved: 12452 cmp r0, #0 @ resolution unsuccessful? 12453 beq common_exceptionThrown @ yes, throw exception 12454 @ fall through to OP_IGET_OBJECT_JUMBO_finish 12455 12456 /* 12457 * Currently: 12458 * r0 holds resolved field 12459 * r9 holds object 12460 */ 12461.LOP_IGET_OBJECT_JUMBO_finish: 12462 @bl common_squeak0 12463 cmp r9, #0 @ check object for null 12464 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12465 beq common_errNullObject @ object was null 12466 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12467 @ no-op @ acquiring load 12468 FETCH(r2, 3) @ r2<- BBBB 12469 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12470 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12471 GET_INST_OPCODE(ip) @ extract opcode from rINST 12472 GOTO_OPCODE(ip) @ jump to next instruction 12473 12474/* continuation for OP_IGET_BOOLEAN_JUMBO */ 12475 12476 /* 12477 * Currently: 12478 * r0 holds resolved field 12479 * r9 holds object 12480 */ 12481.LOP_IGET_BOOLEAN_JUMBO_resolved: 12482 cmp r0, #0 @ resolution unsuccessful? 12483 beq common_exceptionThrown @ yes, throw exception 12484 @ fall through to OP_IGET_BOOLEAN_JUMBO_finish 12485 12486 /* 12487 * Currently: 12488 * r0 holds resolved field 12489 * r9 holds object 12490 */ 12491.LOP_IGET_BOOLEAN_JUMBO_finish: 12492 @bl common_squeak1 12493 cmp r9, #0 @ check object for null 12494 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12495 beq common_errNullObject @ object was null 12496 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12497 @ no-op @ acquiring load 12498 FETCH(r2, 3) @ r2<- BBBB 12499 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12500 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12501 GET_INST_OPCODE(ip) @ extract opcode from rINST 12502 GOTO_OPCODE(ip) @ jump to next instruction 12503 12504/* continuation for OP_IGET_BYTE_JUMBO */ 12505 12506 /* 12507 * Currently: 12508 * r0 holds resolved field 12509 * r9 holds object 12510 */ 12511.LOP_IGET_BYTE_JUMBO_resolved: 12512 cmp r0, #0 @ resolution unsuccessful? 12513 beq common_exceptionThrown @ yes, throw exception 12514 @ fall through to OP_IGET_BYTE_JUMBO_finish 12515 12516 /* 12517 * Currently: 12518 * r0 holds resolved field 12519 * r9 holds object 12520 */ 12521.LOP_IGET_BYTE_JUMBO_finish: 12522 @bl common_squeak2 12523 cmp r9, #0 @ check object for null 12524 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12525 beq common_errNullObject @ object was null 12526 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12527 @ no-op @ acquiring load 12528 FETCH(r2, 3) @ r2<- BBBB 12529 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12530 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12531 GET_INST_OPCODE(ip) @ extract opcode from rINST 12532 GOTO_OPCODE(ip) @ jump to next instruction 12533 12534/* continuation for OP_IGET_CHAR_JUMBO */ 12535 12536 /* 12537 * Currently: 12538 * r0 holds resolved field 12539 * r9 holds object 12540 */ 12541.LOP_IGET_CHAR_JUMBO_resolved: 12542 cmp r0, #0 @ resolution unsuccessful? 12543 beq common_exceptionThrown @ yes, throw exception 12544 @ fall through to OP_IGET_CHAR_JUMBO_finish 12545 12546 /* 12547 * Currently: 12548 * r0 holds resolved field 12549 * r9 holds object 12550 */ 12551.LOP_IGET_CHAR_JUMBO_finish: 12552 @bl common_squeak3 12553 cmp r9, #0 @ check object for null 12554 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12555 beq common_errNullObject @ object was null 12556 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12557 @ no-op @ acquiring load 12558 FETCH(r2, 3) @ r2<- BBBB 12559 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12560 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12561 GET_INST_OPCODE(ip) @ extract opcode from rINST 12562 GOTO_OPCODE(ip) @ jump to next instruction 12563 12564/* continuation for OP_IGET_SHORT_JUMBO */ 12565 12566 /* 12567 * Currently: 12568 * r0 holds resolved field 12569 * r9 holds object 12570 */ 12571.LOP_IGET_SHORT_JUMBO_resolved: 12572 cmp r0, #0 @ resolution unsuccessful? 12573 beq common_exceptionThrown @ yes, throw exception 12574 @ fall through to OP_IGET_SHORT_JUMBO_finish 12575 12576 /* 12577 * Currently: 12578 * r0 holds resolved field 12579 * r9 holds object 12580 */ 12581.LOP_IGET_SHORT_JUMBO_finish: 12582 @bl common_squeak4 12583 cmp r9, #0 @ check object for null 12584 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12585 beq common_errNullObject @ object was null 12586 ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits) 12587 @ no-op @ acquiring load 12588 FETCH(r2, 3) @ r2<- BBBB 12589 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12590 SET_VREG(r0, r2) @ fp[BBBB]<- r0 12591 GET_INST_OPCODE(ip) @ extract opcode from rINST 12592 GOTO_OPCODE(ip) @ jump to next instruction 12593 12594/* continuation for OP_IPUT_JUMBO */ 12595 12596 /* 12597 * Currently: 12598 * r0 holds resolved field 12599 * r9 holds object 12600 */ 12601.LOP_IPUT_JUMBO_resolved: 12602 cmp r0, #0 @ resolution unsuccessful? 12603 beq common_exceptionThrown @ yes, throw exception 12604 @ fall through to OP_IPUT_JUMBO_finish 12605 12606 /* 12607 * Currently: 12608 * r0 holds resolved field 12609 * r9 holds object 12610 */ 12611.LOP_IPUT_JUMBO_finish: 12612 @bl common_squeak0 12613 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12614 FETCH(r1, 3) @ r1<- BBBB 12615 cmp r9, #0 @ check object for null 12616 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12617 beq common_errNullObject @ object was null 12618 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12619 GET_INST_OPCODE(ip) @ extract opcode from rINST 12620 @ no-op @ releasing store 12621 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12622 GOTO_OPCODE(ip) @ jump to next instruction 12623 12624/* continuation for OP_IPUT_WIDE_JUMBO */ 12625 12626 /* 12627 * Currently: 12628 * r0 holds resolved field 12629 * r9 holds object 12630 */ 12631.LOP_IPUT_WIDE_JUMBO_resolved: 12632 cmp r0, #0 @ resolution unsuccessful? 12633 beq common_exceptionThrown @ yes, throw exception 12634 @ fall through to OP_IPUT_WIDE_JUMBO_finish 12635 12636 /* 12637 * Currently: 12638 * r0 holds resolved field 12639 * r9 holds object 12640 */ 12641.LOP_IPUT_WIDE_JUMBO_finish: 12642 cmp r9, #0 @ check object for null 12643 FETCH(r2, 3) @ r1<- BBBB 12644 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12645 add r2, rFP, r2, lsl #2 @ r3<- &fp[BBBB] 12646 beq common_errNullObject @ object was null 12647 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12648 ldmia r2, {r0-r1} @ r0/r1<- fp[BBBB] 12649 GET_INST_OPCODE(r10) @ extract opcode from rINST 12650 strd r0, [r9, r3] @ obj.field (64 bits, aligned)<- r0/r1 12651 GOTO_OPCODE(r10) @ jump to next instruction 12652 12653/* continuation for OP_IPUT_OBJECT_JUMBO */ 12654 12655 /* 12656 * Currently: 12657 * r0 holds resolved field 12658 * r9 holds object 12659 */ 12660.LOP_IPUT_OBJECT_JUMBO_resolved: 12661 cmp r0, #0 @ resolution unsuccessful? 12662 beq common_exceptionThrown @ yes, throw exception 12663 @ fall through to OP_IPUT_OBJECT_JUMBO_finish 12664 12665 /* 12666 * Currently: 12667 * r0 holds resolved field 12668 * r9 holds object 12669 */ 12670.LOP_IPUT_OBJECT_JUMBO_finish: 12671 @bl common_squeak0 12672 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12673 FETCH(r1, 3) @ r1<- BBBB 12674 cmp r9, #0 @ check object for null 12675 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12676 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12677 beq common_errNullObject @ object was null 12678 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12679 GET_INST_OPCODE(ip) @ extract opcode from rINST 12680 @ no-op @ releasing store 12681 str r0, [r9, r3] @ obj.field (32 bits)<- r0 12682 cmp r0, #0 @ stored a null reference? 12683 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not 12684 GOTO_OPCODE(ip) @ jump to next instruction 12685 12686/* continuation for OP_IPUT_BOOLEAN_JUMBO */ 12687 12688 /* 12689 * Currently: 12690 * r0 holds resolved field 12691 * r9 holds object 12692 */ 12693.LOP_IPUT_BOOLEAN_JUMBO_resolved: 12694 cmp r0, #0 @ resolution unsuccessful? 12695 beq common_exceptionThrown @ yes, throw exception 12696 @ fall through to OP_IPUT_BOOLEAN_JUMBO_finish 12697 12698 /* 12699 * Currently: 12700 * r0 holds resolved field 12701 * r9 holds object 12702 */ 12703.LOP_IPUT_BOOLEAN_JUMBO_finish: 12704 @bl common_squeak1 12705 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12706 FETCH(r1, 3) @ r1<- BBBB 12707 cmp r9, #0 @ check object for null 12708 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12709 beq common_errNullObject @ object was null 12710 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12711 GET_INST_OPCODE(ip) @ extract opcode from rINST 12712 @ no-op @ releasing store 12713 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12714 GOTO_OPCODE(ip) @ jump to next instruction 12715 12716/* continuation for OP_IPUT_BYTE_JUMBO */ 12717 12718 /* 12719 * Currently: 12720 * r0 holds resolved field 12721 * r9 holds object 12722 */ 12723.LOP_IPUT_BYTE_JUMBO_resolved: 12724 cmp r0, #0 @ resolution unsuccessful? 12725 beq common_exceptionThrown @ yes, throw exception 12726 @ fall through to OP_IPUT_BYTE_JUMBO_finish 12727 12728 /* 12729 * Currently: 12730 * r0 holds resolved field 12731 * r9 holds object 12732 */ 12733.LOP_IPUT_BYTE_JUMBO_finish: 12734 @bl common_squeak2 12735 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12736 FETCH(r1, 3) @ r1<- BBBB 12737 cmp r9, #0 @ check object for null 12738 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12739 beq common_errNullObject @ object was null 12740 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12741 GET_INST_OPCODE(ip) @ extract opcode from rINST 12742 @ no-op @ releasing store 12743 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12744 GOTO_OPCODE(ip) @ jump to next instruction 12745 12746/* continuation for OP_IPUT_CHAR_JUMBO */ 12747 12748 /* 12749 * Currently: 12750 * r0 holds resolved field 12751 * r9 holds object 12752 */ 12753.LOP_IPUT_CHAR_JUMBO_resolved: 12754 cmp r0, #0 @ resolution unsuccessful? 12755 beq common_exceptionThrown @ yes, throw exception 12756 @ fall through to OP_IPUT_CHAR_JUMBO_finish 12757 12758 /* 12759 * Currently: 12760 * r0 holds resolved field 12761 * r9 holds object 12762 */ 12763.LOP_IPUT_CHAR_JUMBO_finish: 12764 @bl common_squeak3 12765 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12766 FETCH(r1, 3) @ r1<- BBBB 12767 cmp r9, #0 @ check object for null 12768 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12769 beq common_errNullObject @ object was null 12770 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12771 GET_INST_OPCODE(ip) @ extract opcode from rINST 12772 @ no-op @ releasing store 12773 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12774 GOTO_OPCODE(ip) @ jump to next instruction 12775 12776/* continuation for OP_IPUT_SHORT_JUMBO */ 12777 12778 /* 12779 * Currently: 12780 * r0 holds resolved field 12781 * r9 holds object 12782 */ 12783.LOP_IPUT_SHORT_JUMBO_resolved: 12784 cmp r0, #0 @ resolution unsuccessful? 12785 beq common_exceptionThrown @ yes, throw exception 12786 @ fall through to OP_IPUT_SHORT_JUMBO_finish 12787 12788 /* 12789 * Currently: 12790 * r0 holds resolved field 12791 * r9 holds object 12792 */ 12793.LOP_IPUT_SHORT_JUMBO_finish: 12794 @bl common_squeak4 12795 ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field 12796 FETCH(r1, 3) @ r1<- BBBB 12797 cmp r9, #0 @ check object for null 12798 GET_VREG(r0, r1) @ r0<- fp[BBBB] 12799 beq common_errNullObject @ object was null 12800 FETCH_ADVANCE_INST(5) @ advance rPC, load rINST 12801 GET_INST_OPCODE(ip) @ extract opcode from rINST 12802 @ no-op @ releasing store 12803 str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0 12804 GOTO_OPCODE(ip) @ jump to next instruction 12805 12806/* continuation for OP_SGET_JUMBO */ 12807 12808 /* 12809 * Continuation if the field has not yet been resolved. 12810 * r1: AAAAAAAA field ref 12811 */ 12812.LOP_SGET_JUMBO_resolve: 12813 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12814 EXPORT_PC() @ resolve() could throw, so export now 12815 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12816 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12817 cmp r0, #0 @ success? 12818 bne .LOP_SGET_JUMBO_finish @ yes, finish 12819 b common_exceptionThrown @ no, handle exception 12820 12821/* continuation for OP_SGET_WIDE_JUMBO */ 12822 12823 /* 12824 * Continuation if the field has not yet been resolved. 12825 * r1: BBBB field ref 12826 * 12827 * Returns StaticField pointer in r0. 12828 */ 12829.LOP_SGET_WIDE_JUMBO_resolve: 12830 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12831 EXPORT_PC() @ resolve() could throw, so export now 12832 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12833 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12834 cmp r0, #0 @ success? 12835 bne .LOP_SGET_WIDE_JUMBO_finish @ yes, finish 12836 b common_exceptionThrown @ no, handle exception 12837 12838/* continuation for OP_SGET_OBJECT_JUMBO */ 12839 12840 /* 12841 * Continuation if the field has not yet been resolved. 12842 * r1: AAAAAAAA field ref 12843 */ 12844.LOP_SGET_OBJECT_JUMBO_resolve: 12845 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12846 EXPORT_PC() @ resolve() could throw, so export now 12847 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12848 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12849 cmp r0, #0 @ success? 12850 bne .LOP_SGET_OBJECT_JUMBO_finish @ yes, finish 12851 b common_exceptionThrown @ no, handle exception 12852 12853/* continuation for OP_SGET_BOOLEAN_JUMBO */ 12854 12855 /* 12856 * Continuation if the field has not yet been resolved. 12857 * r1: AAAAAAAA field ref 12858 */ 12859.LOP_SGET_BOOLEAN_JUMBO_resolve: 12860 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12861 EXPORT_PC() @ resolve() could throw, so export now 12862 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12863 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12864 cmp r0, #0 @ success? 12865 bne .LOP_SGET_BOOLEAN_JUMBO_finish @ yes, finish 12866 b common_exceptionThrown @ no, handle exception 12867 12868/* continuation for OP_SGET_BYTE_JUMBO */ 12869 12870 /* 12871 * Continuation if the field has not yet been resolved. 12872 * r1: AAAAAAAA field ref 12873 */ 12874.LOP_SGET_BYTE_JUMBO_resolve: 12875 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12876 EXPORT_PC() @ resolve() could throw, so export now 12877 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12878 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12879 cmp r0, #0 @ success? 12880 bne .LOP_SGET_BYTE_JUMBO_finish @ yes, finish 12881 b common_exceptionThrown @ no, handle exception 12882 12883/* continuation for OP_SGET_CHAR_JUMBO */ 12884 12885 /* 12886 * Continuation if the field has not yet been resolved. 12887 * r1: AAAAAAAA field ref 12888 */ 12889.LOP_SGET_CHAR_JUMBO_resolve: 12890 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12891 EXPORT_PC() @ resolve() could throw, so export now 12892 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12893 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12894 cmp r0, #0 @ success? 12895 bne .LOP_SGET_CHAR_JUMBO_finish @ yes, finish 12896 b common_exceptionThrown @ no, handle exception 12897 12898/* continuation for OP_SGET_SHORT_JUMBO */ 12899 12900 /* 12901 * Continuation if the field has not yet been resolved. 12902 * r1: AAAAAAAA field ref 12903 */ 12904.LOP_SGET_SHORT_JUMBO_resolve: 12905 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12906 EXPORT_PC() @ resolve() could throw, so export now 12907 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12908 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12909 cmp r0, #0 @ success? 12910 bne .LOP_SGET_SHORT_JUMBO_finish @ yes, finish 12911 b common_exceptionThrown @ no, handle exception 12912 12913/* continuation for OP_SPUT_JUMBO */ 12914 12915 /* 12916 * Continuation if the field has not yet been resolved. 12917 * r1: AAAAAAAA field ref 12918 */ 12919.LOP_SPUT_JUMBO_resolve: 12920 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12921 EXPORT_PC() @ resolve() could throw, so export now 12922 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12923 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12924 cmp r0, #0 @ success? 12925 bne .LOP_SPUT_JUMBO_finish @ yes, finish 12926 b common_exceptionThrown @ no, handle exception 12927 12928/* continuation for OP_SPUT_WIDE_JUMBO */ 12929 12930 /* 12931 * Continuation if the field has not yet been resolved. 12932 * r1: BBBB field ref 12933 * r9: &fp[AA] 12934 * 12935 * Returns StaticField pointer in r2. 12936 */ 12937.LOP_SPUT_WIDE_JUMBO_resolve: 12938 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12939 EXPORT_PC() @ resolve() could throw, so export now 12940 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12941 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12942 cmp r0, #0 @ success? 12943 mov r2, r0 @ copy to r2 12944 bne .LOP_SPUT_WIDE_JUMBO_finish @ yes, finish 12945 b common_exceptionThrown @ no, handle exception 12946 12947/* continuation for OP_SPUT_OBJECT_JUMBO */ 12948 12949.LOP_SPUT_OBJECT_JUMBO_finish: @ field ptr in r0 12950 FETCH(r2, 3) @ r2<- BBBB 12951 FETCH_ADVANCE_INST(4) @ advance rPC, load rINST 12952 GET_VREG(r1, r2) @ r1<- fp[BBBB] 12953 ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base 12954 ldr r9, [r0, #offField_clazz] @ r9<- field->clazz 12955 GET_INST_OPCODE(ip) @ extract opcode from rINST 12956 @ no-op @ releasing store 12957 str r1, [r0, #offStaticField_value] @ field<- vBBBB 12958 cmp r1, #0 @ stored a null object? 12959 strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head 12960 GOTO_OPCODE(ip) @ jump to next instruction 12961 12962/* continuation for OP_SPUT_BOOLEAN_JUMBO */ 12963 12964 /* 12965 * Continuation if the field has not yet been resolved. 12966 * r1: AAAAAAAA field ref 12967 */ 12968.LOP_SPUT_BOOLEAN_JUMBO_resolve: 12969 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12970 EXPORT_PC() @ resolve() could throw, so export now 12971 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12972 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12973 cmp r0, #0 @ success? 12974 bne .LOP_SPUT_BOOLEAN_JUMBO_finish @ yes, finish 12975 b common_exceptionThrown @ no, handle exception 12976 12977/* continuation for OP_SPUT_BYTE_JUMBO */ 12978 12979 /* 12980 * Continuation if the field has not yet been resolved. 12981 * r1: AAAAAAAA field ref 12982 */ 12983.LOP_SPUT_BYTE_JUMBO_resolve: 12984 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 12985 EXPORT_PC() @ resolve() could throw, so export now 12986 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 12987 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 12988 cmp r0, #0 @ success? 12989 bne .LOP_SPUT_BYTE_JUMBO_finish @ yes, finish 12990 b common_exceptionThrown @ no, handle exception 12991 12992/* continuation for OP_SPUT_CHAR_JUMBO */ 12993 12994 /* 12995 * Continuation if the field has not yet been resolved. 12996 * r1: AAAAAAAA field ref 12997 */ 12998.LOP_SPUT_CHAR_JUMBO_resolve: 12999 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13000 EXPORT_PC() @ resolve() could throw, so export now 13001 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13002 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13003 cmp r0, #0 @ success? 13004 bne .LOP_SPUT_CHAR_JUMBO_finish @ yes, finish 13005 b common_exceptionThrown @ no, handle exception 13006 13007/* continuation for OP_SPUT_SHORT_JUMBO */ 13008 13009 /* 13010 * Continuation if the field has not yet been resolved. 13011 * r1: AAAAAAAA field ref 13012 */ 13013.LOP_SPUT_SHORT_JUMBO_resolve: 13014 ldr r2, [rGLUE, #offGlue_method] @ r2<- current method 13015 EXPORT_PC() @ resolve() could throw, so export now 13016 ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz 13017 bl dvmResolveStaticField @ r0<- resolved StaticField ptr 13018 cmp r0, #0 @ success? 13019 bne .LOP_SPUT_SHORT_JUMBO_finish @ yes, finish 13020 b common_exceptionThrown @ no, handle exception 13021 13022/* continuation for OP_INVOKE_VIRTUAL_JUMBO */ 13023 13024 /* 13025 * At this point: 13026 * r0 = resolved base method 13027 */ 13028.LOP_INVOKE_VIRTUAL_JUMBO_continue: 13029 FETCH(r10, 4) @ r10<- CCCC 13030 GET_VREG(r1, r10) @ r1<- "this" ptr 13031 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 13032 cmp r1, #0 @ is "this" null? 13033 beq common_errNullObject @ null "this", throw exception 13034 ldr r3, [r1, #offObject_clazz] @ r1<- thisPtr->clazz 13035 ldr r3, [r3, #offClassObject_vtable] @ r3<- thisPtr->clazz->vtable 13036 ldr r0, [r3, r2, lsl #2] @ r3<- vtable[methodIndex] 13037 bl common_invokeMethodJumbo @ continue on 13038 13039/* continuation for OP_INVOKE_SUPER_JUMBO */ 13040 13041 /* 13042 * At this point: 13043 * r0 = resolved base method 13044 * r9 = method->clazz 13045 */ 13046.LOP_INVOKE_SUPER_JUMBO_continue: 13047 ldr r1, [r9, #offClassObject_super] @ r1<- method->clazz->super 13048 ldrh r2, [r0, #offMethod_methodIndex] @ r2<- baseMethod->methodIndex 13049 ldr r3, [r1, #offClassObject_vtableCount] @ r3<- super->vtableCount 13050 EXPORT_PC() @ must export for invoke 13051 cmp r2, r3 @ compare (methodIndex, vtableCount) 13052 bcs .LOP_INVOKE_SUPER_JUMBO_nsm @ method not present in superclass 13053 ldr r1, [r1, #offClassObject_vtable] @ r1<- ...clazz->super->vtable 13054 ldr r0, [r1, r2, lsl #2] @ r3<- vtable[methodIndex] 13055 bl common_invokeMethodJumbo @ continue on 13056 13057.LOP_INVOKE_SUPER_JUMBO_resolve: 13058 mov r0, r9 @ r0<- method->clazz 13059 mov r2, #METHOD_VIRTUAL @ resolver method type 13060 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 13061 cmp r0, #0 @ got null? 13062 bne .LOP_INVOKE_SUPER_JUMBO_continue @ no, continue 13063 b common_exceptionThrown @ yes, handle exception 13064 13065 /* 13066 * Throw a NoSuchMethodError with the method name as the message. 13067 * r0 = resolved base method 13068 */ 13069.LOP_INVOKE_SUPER_JUMBO_nsm: 13070 ldr r1, [r0, #offMethod_name] @ r1<- method name 13071 b common_errNoSuchMethod 13072 13073/* continuation for OP_INVOKE_DIRECT_JUMBO */ 13074 13075 /* 13076 * On entry: 13077 * r1 = reference (CCCC) 13078 * r10 = "this" register 13079 */ 13080.LOP_INVOKE_DIRECT_JUMBO_resolve: 13081 ldr r3, [rGLUE, #offGlue_method] @ r3<- glue->method 13082 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 13083 mov r2, #METHOD_DIRECT @ resolver method type 13084 bl dvmResolveMethod @ r0<- call(clazz, ref, flags) 13085 cmp r0, #0 @ got null? 13086 GET_VREG(r2, r10) @ r2<- "this" ptr (reload) 13087 bne .LOP_INVOKE_DIRECT_JUMBO_finish @ no, continue 13088 b common_exceptionThrown @ yes, handle exception 13089 13090 .size dvmAsmSisterStart, .-dvmAsmSisterStart 13091 .global dvmAsmSisterEnd 13092dvmAsmSisterEnd: 13093 13094/* File: armv5te/footer.S */ 13095 13096/* 13097 * =========================================================================== 13098 * Common subroutines and data 13099 * =========================================================================== 13100 */ 13101 13102 13103 13104 .text 13105 .align 2 13106 13107#if defined(WITH_JIT) 13108#if defined(WITH_SELF_VERIFICATION) 13109 .global dvmJitToInterpPunt 13110dvmJitToInterpPunt: 13111 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13112 mov r2,#kSVSPunt @ r2<- interpreter entry point 13113 mov r3, #0 13114 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13115 b jitSVShadowRunEnd @ doesn't return 13116 13117 .global dvmJitToInterpSingleStep 13118dvmJitToInterpSingleStep: 13119 str lr,[rGLUE,#offGlue_jitResumeNPC] 13120 str r1,[rGLUE,#offGlue_jitResumeDPC] 13121 mov r2,#kSVSSingleStep @ r2<- interpreter entry point 13122 b jitSVShadowRunEnd @ doesn't return 13123 13124 .global dvmJitToInterpNoChainNoProfile 13125dvmJitToInterpNoChainNoProfile: 13126 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13127 mov r0,rPC @ pass our target PC 13128 mov r2,#kSVSNoProfile @ r2<- interpreter entry point 13129 mov r3, #0 @ 0 means !inJitCodeCache 13130 str r3, [r10, #offThread_inJitCodeCache] @ back to the interp land 13131 b jitSVShadowRunEnd @ doesn't return 13132 13133 .global dvmJitToInterpTraceSelectNoChain 13134dvmJitToInterpTraceSelectNoChain: 13135 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13136 mov r0,rPC @ pass our target PC 13137 mov r2,#kSVSTraceSelect @ r2<- interpreter entry point 13138 mov r3, #0 @ 0 means !inJitCodeCache 13139 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13140 b jitSVShadowRunEnd @ doesn't return 13141 13142 .global dvmJitToInterpTraceSelect 13143dvmJitToInterpTraceSelect: 13144 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 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, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13149 b jitSVShadowRunEnd @ doesn't return 13150 13151 .global dvmJitToInterpBackwardBranch 13152dvmJitToInterpBackwardBranch: 13153 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13154 ldr r0,[lr, #-1] @ pass our target PC 13155 mov r2,#kSVSBackwardBranch @ r2<- interpreter entry point 13156 mov r3, #0 @ 0 means !inJitCodeCache 13157 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13158 b jitSVShadowRunEnd @ doesn't return 13159 13160 .global dvmJitToInterpNormal 13161dvmJitToInterpNormal: 13162 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13163 ldr r0,[lr, #-1] @ pass our target PC 13164 mov r2,#kSVSNormal @ r2<- interpreter entry point 13165 mov r3, #0 @ 0 means !inJitCodeCache 13166 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13167 b jitSVShadowRunEnd @ doesn't return 13168 13169 .global dvmJitToInterpNoChain 13170dvmJitToInterpNoChain: 13171 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13172 mov r0,rPC @ pass our target PC 13173 mov r2,#kSVSNoChain @ r2<- interpreter entry point 13174 mov r3, #0 @ 0 means !inJitCodeCache 13175 str r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13176 b jitSVShadowRunEnd @ doesn't return 13177#else 13178/* 13179 * Return from the translation cache to the interpreter when the compiler is 13180 * having issues translating/executing a Dalvik instruction. We have to skip 13181 * the code cache lookup otherwise it is possible to indefinitely bouce 13182 * between the interpreter and the code cache if the instruction that fails 13183 * to be compiled happens to be at a trace start. 13184 */ 13185 .global dvmJitToInterpPunt 13186dvmJitToInterpPunt: 13187 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13188 mov rPC, r0 13189#if defined(WITH_JIT_TUNING) 13190 mov r0,lr 13191 bl dvmBumpPunt; 13192#endif 13193 EXPORT_PC() 13194 mov r0, #0 13195 str r0, [r10, #offThread_inJitCodeCache] @ Back to the interp land 13196 adrl rIBASE, dvmAsmInstructionStart 13197 FETCH_INST() 13198 GET_INST_OPCODE(ip) 13199 GOTO_OPCODE(ip) 13200 13201/* 13202 * Return to the interpreter to handle a single instruction. 13203 * On entry: 13204 * r0 <= PC 13205 * r1 <= PC of resume instruction 13206 * lr <= resume point in translation 13207 */ 13208 .global dvmJitToInterpSingleStep 13209dvmJitToInterpSingleStep: 13210 str lr,[rGLUE,#offGlue_jitResumeNPC] 13211 str r1,[rGLUE,#offGlue_jitResumeDPC] 13212 mov r1,#kInterpEntryInstr 13213 @ enum is 4 byte in aapcs-EABI 13214 str r1, [rGLUE, #offGlue_entryPoint] 13215 mov rPC,r0 13216 EXPORT_PC() 13217 13218 adrl rIBASE, dvmAsmInstructionStart 13219 mov r2,#kJitSingleStep @ Ask for single step and then revert 13220 str r2,[rGLUE,#offGlue_jitState] 13221 mov r1,#1 @ set changeInterp to bail to debug interp 13222 b common_gotoBail 13223 13224/* 13225 * Return from the translation cache and immediately request 13226 * a translation for the exit target. Commonly used for callees. 13227 */ 13228 .global dvmJitToInterpTraceSelectNoChain 13229dvmJitToInterpTraceSelectNoChain: 13230#if defined(WITH_JIT_TUNING) 13231 bl dvmBumpNoChain 13232#endif 13233 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13234 mov r0,rPC 13235 bl dvmJitGetCodeAddr @ Is there a translation? 13236 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13237 mov r1, rPC @ arg1 of translation may need this 13238 mov lr, #0 @ in case target is HANDLER_INTERPRET 13239 cmp r0,#0 @ !0 means translation exists 13240 bxne r0 @ continue native execution if so 13241 b 2f @ branch over to use the interpreter 13242 13243/* 13244 * Return from the translation cache and immediately request 13245 * a translation for the exit target. Commonly used following 13246 * invokes. 13247 */ 13248 .global dvmJitToInterpTraceSelect 13249dvmJitToInterpTraceSelect: 13250 ldr rPC,[lr, #-1] @ get our target PC 13251 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13252 add rINST,lr,#-5 @ save start of chain branch 13253 add rINST, #-4 @ .. which is 9 bytes back 13254 mov r0,rPC 13255 bl dvmJitGetCodeAddr @ Is there a translation? 13256 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13257 cmp r0,#0 13258 beq 2f 13259 mov r1,rINST 13260 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 13261 mov r1, rPC @ arg1 of translation may need this 13262 mov lr, #0 @ in case target is HANDLER_INTERPRET 13263 cmp r0,#0 @ successful chain? 13264 bxne r0 @ continue native execution 13265 b toInterpreter @ didn't chain - resume with interpreter 13266 13267/* No translation, so request one if profiling isn't disabled*/ 132682: 13269 adrl rIBASE, dvmAsmInstructionStart 13270 GET_JIT_PROF_TABLE(r0) 13271 FETCH_INST() 13272 cmp r0, #0 13273 movne r2,#kJitTSelectRequestHot @ ask for trace selection 13274 bne common_selectTrace 13275 GET_INST_OPCODE(ip) 13276 GOTO_OPCODE(ip) 13277 13278/* 13279 * Return from the translation cache to the interpreter. 13280 * The return was done with a BLX from thumb mode, and 13281 * the following 32-bit word contains the target rPC value. 13282 * Note that lr (r14) will have its low-order bit set to denote 13283 * its thumb-mode origin. 13284 * 13285 * We'll need to stash our lr origin away, recover the new 13286 * target and then check to see if there is a translation available 13287 * for our new target. If so, we do a translation chain and 13288 * go back to native execution. Otherwise, it's back to the 13289 * interpreter (after treating this entry as a potential 13290 * trace start). 13291 */ 13292 .global dvmJitToInterpNormal 13293dvmJitToInterpNormal: 13294 ldr rPC,[lr, #-1] @ get our target PC 13295 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13296 add rINST,lr,#-5 @ save start of chain branch 13297 add rINST,#-4 @ .. which is 9 bytes back 13298#if defined(WITH_JIT_TUNING) 13299 bl dvmBumpNormal 13300#endif 13301 mov r0,rPC 13302 bl dvmJitGetCodeAddr @ Is there a translation? 13303 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13304 cmp r0,#0 13305 beq toInterpreter @ go if not, otherwise do chain 13306 mov r1,rINST 13307 bl dvmJitChain @ r0<- dvmJitChain(codeAddr,chainAddr) 13308 mov r1, rPC @ arg1 of translation may need this 13309 mov lr, #0 @ in case target is HANDLER_INTERPRET 13310 cmp r0,#0 @ successful chain? 13311 bxne r0 @ continue native execution 13312 b toInterpreter @ didn't chain - resume with interpreter 13313 13314/* 13315 * Return from the translation cache to the interpreter to do method invocation. 13316 * Check if translation exists for the callee, but don't chain to it. 13317 */ 13318 .global dvmJitToInterpNoChainNoProfile 13319dvmJitToInterpNoChainNoProfile: 13320#if defined(WITH_JIT_TUNING) 13321 bl dvmBumpNoChain 13322#endif 13323 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13324 mov r0,rPC 13325 bl dvmJitGetCodeAddr @ Is there a translation? 13326 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13327 mov r1, rPC @ arg1 of translation may need this 13328 mov lr, #0 @ in case target is HANDLER_INTERPRET 13329 cmp r0,#0 13330 bxne r0 @ continue native execution if so 13331 EXPORT_PC() 13332 adrl rIBASE, dvmAsmInstructionStart 13333 FETCH_INST() 13334 GET_INST_OPCODE(ip) @ extract opcode from rINST 13335 GOTO_OPCODE(ip) @ jump to next instruction 13336 13337/* 13338 * Return from the translation cache to the interpreter to do method invocation. 13339 * Check if translation exists for the callee, but don't chain to it. 13340 */ 13341 .global dvmJitToInterpNoChain 13342dvmJitToInterpNoChain: 13343#if defined(WITH_JIT_TUNING) 13344 bl dvmBumpNoChain 13345#endif 13346 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13347 mov r0,rPC 13348 bl dvmJitGetCodeAddr @ Is there a translation? 13349 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13350 mov r1, rPC @ arg1 of translation may need this 13351 mov lr, #0 @ in case target is HANDLER_INTERPRET 13352 cmp r0,#0 13353 bxne r0 @ continue native execution if so 13354#endif 13355 13356/* 13357 * No translation, restore interpreter regs and start interpreting. 13358 * rGLUE & rFP were preserved in the translated code, and rPC has 13359 * already been restored by the time we get here. We'll need to set 13360 * up rIBASE & rINST, and load the address of the JitTable into r0. 13361 */ 13362toInterpreter: 13363 EXPORT_PC() 13364 adrl rIBASE, dvmAsmInstructionStart 13365 FETCH_INST() 13366 GET_JIT_PROF_TABLE(r0) 13367 @ NOTE: intended fallthrough 13368 13369/* 13370 * Common code to update potential trace start counter, and initiate 13371 * a trace-build if appropriate. On entry, rPC should point to the 13372 * next instruction to execute, and rINST should be already loaded with 13373 * the next opcode word, and r0 holds a pointer to the jit profile 13374 * table (pJitProfTable). 13375 */ 13376common_testUpdateProfile: 13377 cmp r0,#0 13378 GET_INST_OPCODE(ip) 13379 GOTO_OPCODE_IFEQ(ip) @ if not profiling, fallthrough otherwise */ 13380 13381common_updateProfile: 13382 eor r3,rPC,rPC,lsr #12 @ cheap, but fast hash function 13383 lsl r3,r3,#(32 - JIT_PROF_SIZE_LOG_2) @ shift out excess bits 13384 ldrb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter 13385 GET_INST_OPCODE(ip) 13386 subs r1,r1,#1 @ decrement counter 13387 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it 13388 GOTO_OPCODE_IFNE(ip) @ if not threshold, fallthrough otherwise */ 13389 13390/* 13391 * Here, we switch to the debug interpreter to request 13392 * trace selection. First, though, check to see if there 13393 * is already a native translation in place (and, if so, 13394 * jump to it now). 13395 */ 13396 GET_JIT_THRESHOLD(r1) 13397 ldr r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self 13398 strb r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter 13399 EXPORT_PC() 13400 mov r0,rPC 13401 bl dvmJitGetCodeAddr @ r0<- dvmJitGetCodeAddr(rPC) 13402 str r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag 13403 mov r1, rPC @ arg1 of translation may need this 13404 mov lr, #0 @ in case target is HANDLER_INTERPRET 13405 cmp r0,#0 13406#if !defined(WITH_SELF_VERIFICATION) 13407 bxne r0 @ jump to the translation 13408 mov r2,#kJitTSelectRequest @ ask for trace selection 13409 @ fall-through to common_selectTrace 13410#else 13411 moveq r2,#kJitTSelectRequest @ ask for trace selection 13412 beq common_selectTrace 13413 /* 13414 * At this point, we have a target translation. However, if 13415 * that translation is actually the interpret-only pseudo-translation 13416 * we want to treat it the same as no translation. 13417 */ 13418 mov r10, r0 @ save target 13419 bl dvmCompilerGetInterpretTemplate 13420 cmp r0, r10 @ special case? 13421 bne jitSVShadowRunStart @ set up self verification shadow space 13422 @ Need to clear the inJitCodeCache flag 13423 ldr r10, [rGLUE, #offGlue_self] @ r10 <- glue->self 13424 mov r3, #0 @ 0 means not in the JIT code cache 13425 str r3, [r10, #offThread_inJitCodeCache] @ back to the interp land 13426 GET_INST_OPCODE(ip) 13427 GOTO_OPCODE(ip) 13428 /* no return */ 13429#endif 13430 13431/* 13432 * On entry: 13433 * r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot 13434 */ 13435common_selectTrace: 13436 str r2,[rGLUE,#offGlue_jitState] 13437 mov r2,#kInterpEntryInstr @ normal entry reason 13438 str r2,[rGLUE,#offGlue_entryPoint] 13439 mov r1,#1 @ set changeInterp 13440 b common_gotoBail 13441 13442#if defined(WITH_SELF_VERIFICATION) 13443/* 13444 * Save PC and registers to shadow memory for self verification mode 13445 * before jumping to native translation. 13446 * On entry: 13447 * rPC, rFP, rGLUE: the values that they should contain 13448 * r10: the address of the target translation. 13449 */ 13450jitSVShadowRunStart: 13451 mov r0,rPC @ r0<- program counter 13452 mov r1,rFP @ r1<- frame pointer 13453 mov r2,rGLUE @ r2<- InterpState pointer 13454 mov r3,r10 @ r3<- target translation 13455 bl dvmSelfVerificationSaveState @ save registers to shadow space 13456 ldr rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space 13457 add rGLUE,r0,#offShadowSpace_interpState @ rGLUE<- rGLUE in shadow space 13458 bx r10 @ jump to the translation 13459 13460/* 13461 * Restore PC, registers, and interpState to original values 13462 * before jumping back to the interpreter. 13463 */ 13464jitSVShadowRunEnd: 13465 mov r1,rFP @ pass ending fp 13466 bl dvmSelfVerificationRestoreState @ restore pc and fp values 13467 ldr rPC,[r0,#offShadowSpace_startPC] @ restore PC 13468 ldr rFP,[r0,#offShadowSpace_fp] @ restore FP 13469 ldr rGLUE,[r0,#offShadowSpace_glue] @ restore InterpState 13470 ldr r1,[r0,#offShadowSpace_svState] @ get self verification state 13471 cmp r1,#0 @ check for punt condition 13472 beq 1f 13473 mov r2,#kJitSelfVerification @ ask for self verification 13474 str r2,[rGLUE,#offGlue_jitState] 13475 mov r2,#kInterpEntryInstr @ normal entry reason 13476 str r2,[rGLUE,#offGlue_entryPoint] 13477 mov r1,#1 @ set changeInterp 13478 b common_gotoBail 13479 134801: @ exit to interpreter without check 13481 EXPORT_PC() 13482 adrl rIBASE, dvmAsmInstructionStart 13483 FETCH_INST() 13484 GET_INST_OPCODE(ip) 13485 GOTO_OPCODE(ip) 13486#endif 13487 13488#endif 13489 13490/* 13491 * Common code when a backward branch is taken. 13492 * 13493 * TODO: we could avoid a branch by just setting r0 and falling through 13494 * into the common_periodicChecks code, and having a test on r0 at the 13495 * end determine if we should return to the caller or update & branch to 13496 * the next instr. 13497 * 13498 * On entry: 13499 * r9 is PC adjustment *in bytes* 13500 */ 13501common_backwardBranch: 13502 mov r0, #kInterpEntryInstr 13503 bl common_periodicChecks 13504#if defined(WITH_JIT) 13505 GET_JIT_PROF_TABLE(r0) 13506 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 13507 cmp r0,#0 13508 bne common_updateProfile 13509 GET_INST_OPCODE(ip) 13510 GOTO_OPCODE(ip) 13511#else 13512 FETCH_ADVANCE_INST_RB(r9) @ update rPC, load rINST 13513 GET_INST_OPCODE(ip) @ extract opcode from rINST 13514 GOTO_OPCODE(ip) @ jump to next instruction 13515#endif 13516 13517 13518/* 13519 * Need to see if the thread needs to be suspended or debugger/profiler 13520 * activity has begun. If so, we suspend the thread or side-exit to 13521 * the debug interpreter as appropriate. 13522 * 13523 * The common case is no activity on any of these, so we want to figure 13524 * that out quickly. If something is up, we can then sort out what. 13525 * 13526 * We want to be fast if the VM was built without debugger or profiler 13527 * support, but we also need to recognize that the system is usually 13528 * shipped with both of these enabled. 13529 * 13530 * TODO: reduce this so we're just checking a single location. 13531 * 13532 * On entry: 13533 * r0 is reentry type, e.g. kInterpEntryInstr (for debugger/profiling) 13534 * r9 is trampoline PC adjustment *in bytes* 13535 */ 13536common_periodicChecks: 13537 ldr r1, [rGLUE, #offGlue_pInterpBreak] @ r3<- &interpBreak 13538 /* speculatively load address of thread-specific suspend count */ 13539 ldr r3, [rGLUE, #offGlue_pSelfSuspendCount] @ r3<- &suspendCount 13540 ldr r1, [r1] @ r1<- interpBreak 13541 /* speculatively load thread-specific suspend count */ 13542 ldr ip, [r3] @ ip<- suspendCount (int) 13543 cmp r1, #0 @ anything unusual? 13544 bxeq lr @ return if not 13545 /* 13546 * One or more interesting events have happened. Figure out what. 13547 * 13548 * r0 still holds the reentry type. 13549 */ 13550 cmp ip, #0 @ want suspend? 13551 beq 3f @ no, must be something else 13552 13553 stmfd sp!, {r0, lr} @ preserve r0 and lr 13554#if defined(WITH_JIT) 13555 /* 13556 * Refresh the Jit's cached copy of profile table pointer. This pointer 13557 * doubles as the Jit's on/off switch. 13558 */ 13559 ldr r3, [rGLUE, #offGlue_ppJitProfTable] @ r3<-&gDvmJit.pJitProfTable 13560 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 13561 ldr r3, [r3] @ r3 <- pJitProfTable 13562 EXPORT_PC() @ need for precise GC 13563 str r3, [rGLUE, #offGlue_pJitProfTable] @ refresh Jit's on/off switch 13564#else 13565 ldr r0, [rGLUE, #offGlue_self] @ r0<- glue->self 13566 EXPORT_PC() @ need for precise GC 13567#endif 13568 bl dvmCheckSuspendPending @ do full check, suspend if necessary 13569 ldmfd sp!, {r0, lr} @ restore r0 and lr 13570 13571 /* 13572 * Reload the interpBreak flags - they may have changed while we 13573 * were suspended. 13574 */ 13575 ldr r1, [rGLUE, #offGlue_pInterpBreak] @ r1<- &interpBreak 13576 ldr r1, [r1] @ r1<- interpBreak 135773: 13578 /* 13579 * TODO: this code is too fragile. Need a general mechanism 13580 * to identify what actions to take by submode. Some profiling modes 13581 * (instruction count) need to single-step, while method tracing 13582 * may not. Debugging with breakpoints can run unfettered, but 13583 * source-level single-stepping requires Dalvik singlestepping. 13584 * GC may require a one-shot action and then full-speed resumption. 13585 */ 13586 ands r1, #(kSubModeDebuggerActive | kSubModeEmulatorTrace | kSubModeInstCounting) 13587 bxeq lr @ nothing to do, return 13588 13589 @ debugger/profiler enabled, bail out; glue->entryPoint was set above 13590 str r0, [rGLUE, #offGlue_entryPoint] @ store r0, need for debug/prof 13591 add rPC, rPC, r9 @ update rPC 13592 mov r1, #1 @ "want switch" = true 13593 b common_gotoBail @ side exit 13594 13595 13596/* 13597 * The equivalent of "goto bail", this calls through the "bail handler". 13598 * 13599 * State registers will be saved to the "glue" area before bailing. 13600 * 13601 * On entry: 13602 * r1 is "bool changeInterp", indicating if we want to switch to the 13603 * other interpreter or just bail all the way out 13604 */ 13605common_gotoBail: 13606 SAVE_PC_FP_TO_GLUE() @ export state to "glue" 13607 mov r0, rGLUE @ r0<- glue ptr 13608 b dvmMterpStdBail @ call(glue, changeInterp) 13609 13610 @add r1, r1, #1 @ using (boolean+1) 13611 @add r0, rGLUE, #offGlue_jmpBuf @ r0<- &glue->jmpBuf 13612 @bl _longjmp @ does not return 13613 @bl common_abort 13614 13615 13616/* 13617 * Common code for jumbo method invocation. 13618 * NOTE: this adjusts rPC to account for the difference in instruction width. 13619 * As a result, the savedPc in the stack frame will not be wholly accurate. So 13620 * long as that is only used for source file line number calculations, we're 13621 * okay. 13622 * 13623 * On entry: 13624 * r0 is "Method* methodToCall", the method we're trying to call 13625 */ 13626common_invokeMethodJumbo: 13627.LinvokeNewJumbo: 13628 @ prepare to copy args to "outs" area of current frame 13629 add rPC, rPC, #4 @ adjust pc to make return consistent 13630 FETCH(r2, 1) @ r2<- BBBB (arg count) 13631 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 13632 cmp r2, #0 @ no args? 13633 beq .LinvokeArgsDone @ if no args, skip the rest 13634 FETCH(r1, 2) @ r1<- CCCC 13635 b .LinvokeRangeArgs @ handle args like invoke range 13636 13637/* 13638 * Common code for method invocation with range. 13639 * 13640 * On entry: 13641 * r0 is "Method* methodToCall", the method we're trying to call 13642 */ 13643common_invokeMethodRange: 13644.LinvokeNewRange: 13645 @ prepare to copy args to "outs" area of current frame 13646 movs r2, rINST, lsr #8 @ r2<- AA (arg count) -- test for zero 13647 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 13648 beq .LinvokeArgsDone @ if no args, skip the rest 13649 FETCH(r1, 2) @ r1<- CCCC 13650 13651.LinvokeRangeArgs: 13652 @ r0=methodToCall, r1=CCCC, r2=count, r10=outs 13653 @ (very few methods have > 10 args; could unroll for common cases) 13654 add r3, rFP, r1, lsl #2 @ r3<- &fp[CCCC] 13655 sub r10, r10, r2, lsl #2 @ r10<- "outs" area, for call args 136561: ldr r1, [r3], #4 @ val = *fp++ 13657 subs r2, r2, #1 @ count-- 13658 str r1, [r10], #4 @ *outs++ = val 13659 bne 1b @ ...while count != 0 13660 b .LinvokeArgsDone 13661 13662/* 13663 * Common code for method invocation without range. 13664 * 13665 * On entry: 13666 * r0 is "Method* methodToCall", the method we're trying to call 13667 */ 13668common_invokeMethodNoRange: 13669.LinvokeNewNoRange: 13670 @ prepare to copy args to "outs" area of current frame 13671 movs r2, rINST, lsr #12 @ r2<- B (arg count) -- test for zero 13672 SAVEAREA_FROM_FP(r10, rFP) @ r10<- stack save area 13673 FETCH(r1, 2) @ r1<- GFED (load here to hide latency) 13674 beq .LinvokeArgsDone 13675 13676 @ r0=methodToCall, r1=GFED, r2=count, r10=outs 13677.LinvokeNonRange: 13678 rsb r2, r2, #5 @ r2<- 5-r2 13679 add pc, pc, r2, lsl #4 @ computed goto, 4 instrs each 13680 bl common_abort @ (skipped due to ARM prefetch) 136815: and ip, rINST, #0x0f00 @ isolate A 13682 ldr r2, [rFP, ip, lsr #6] @ r2<- vA (shift right 8, left 2) 13683 mov r0, r0 @ nop 13684 str r2, [r10, #-4]! @ *--outs = vA 136854: and ip, r1, #0xf000 @ isolate G 13686 ldr r2, [rFP, ip, lsr #10] @ r2<- vG (shift right 12, left 2) 13687 mov r0, r0 @ nop 13688 str r2, [r10, #-4]! @ *--outs = vG 136893: and ip, r1, #0x0f00 @ isolate F 13690 ldr r2, [rFP, ip, lsr #6] @ r2<- vF 13691 mov r0, r0 @ nop 13692 str r2, [r10, #-4]! @ *--outs = vF 136932: and ip, r1, #0x00f0 @ isolate E 13694 ldr r2, [rFP, ip, lsr #2] @ r2<- vE 13695 mov r0, r0 @ nop 13696 str r2, [r10, #-4]! @ *--outs = vE 136971: and ip, r1, #0x000f @ isolate D 13698 ldr r2, [rFP, ip, lsl #2] @ r2<- vD 13699 mov r0, r0 @ nop 13700 str r2, [r10, #-4]! @ *--outs = vD 137010: @ fall through to .LinvokeArgsDone 13702 13703.LinvokeArgsDone: @ r0=methodToCall 13704 ldrh r9, [r0, #offMethod_registersSize] @ r9<- methodToCall->regsSize 13705 ldrh r3, [r0, #offMethod_outsSize] @ r3<- methodToCall->outsSize 13706 ldr r2, [r0, #offMethod_insns] @ r2<- method->insns 13707 ldr rINST, [r0, #offMethod_clazz] @ rINST<- method->clazz 13708 @ find space for the new stack frame, check for overflow 13709 SAVEAREA_FROM_FP(r1, rFP) @ r1<- stack save area 13710 sub r1, r1, r9, lsl #2 @ r1<- newFp (old savearea - regsSize) 13711 SAVEAREA_FROM_FP(r10, r1) @ r10<- newSaveArea 13712@ bl common_dumpRegs 13713 ldr r9, [rGLUE, #offGlue_interpStackEnd] @ r9<- interpStackEnd 13714 sub r3, r10, r3, lsl #2 @ r3<- bottom (newsave - outsSize) 13715 cmp r3, r9 @ bottom < interpStackEnd? 13716 ldr lr, [rGLUE, #offGlue_pInterpBreak] 13717 ldr r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags 13718 blo .LstackOverflow @ yes, this frame will overflow stack 13719 13720 @ set up newSaveArea 13721 ldr lr, [lr] @ lr<- active submodes 13722#ifdef EASY_GDB 13723 SAVEAREA_FROM_FP(ip, rFP) @ ip<- stack save area 13724 str ip, [r10, #offStackSaveArea_prevSave] 13725#endif 13726 str rFP, [r10, #offStackSaveArea_prevFrame] 13727 str rPC, [r10, #offStackSaveArea_savedPc] 13728#if defined(WITH_JIT) 13729 mov r9, #0 13730 str r9, [r10, #offStackSaveArea_returnAddr] 13731#endif 13732 ands lr, #kSubModeMethodTrace @ method tracing? 13733 beq 1f @ skip if not 13734 stmfd sp!, {r0-r3} @ preserve r0-r3 13735 mov r1, r6 13736 @ r0=methodToCall, r1=rGlue 13737 bl dvmFastMethodTraceEnter 13738 ldmfd sp!, {r0-r3} @ restore r0-r3 137391: 13740 str r0, [r10, #offStackSaveArea_method] 13741 tst r3, #ACC_NATIVE 13742 bne .LinvokeNative 13743 13744 /* 13745 stmfd sp!, {r0-r3} 13746 bl common_printNewline 13747 mov r0, rFP 13748 mov r1, #0 13749 bl dvmDumpFp 13750 ldmfd sp!, {r0-r3} 13751 stmfd sp!, {r0-r3} 13752 mov r0, r1 13753 mov r1, r10 13754 bl dvmDumpFp 13755 bl common_printNewline 13756 ldmfd sp!, {r0-r3} 13757 */ 13758 13759 ldrh r9, [r2] @ r9 <- load INST from new PC 13760 ldr r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex 13761 mov rPC, r2 @ publish new rPC 13762 ldr r2, [rGLUE, #offGlue_self] @ r2<- glue->self 13763 13764 @ Update "glue" values for the new method 13765 @ r0=methodToCall, r1=newFp, r2=self, r3=newMethodClass, r9=newINST 13766 str r0, [rGLUE, #offGlue_method] @ glue->method = methodToCall 13767 str r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ... 13768#if defined(WITH_JIT) 13769 GET_JIT_PROF_TABLE(r0) 13770 mov rFP, r1 @ fp = newFp 13771 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 13772 mov rINST, r9 @ publish new rINST 13773 str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp 13774 cmp r0,#0 13775 bne common_updateProfile 13776 GOTO_OPCODE(ip) @ jump to next instruction 13777#else 13778 mov rFP, r1 @ fp = newFp 13779 GET_PREFETCHED_OPCODE(ip, r9) @ extract prefetched opcode from r9 13780 mov rINST, r9 @ publish new rINST 13781 str r1, [r2, #offThread_curFrame] @ self->curFrame = newFp 13782 GOTO_OPCODE(ip) @ jump to next instruction 13783#endif 13784 13785.LinvokeNative: 13786 @ Prep for the native call 13787 @ r0=methodToCall, r1=newFp, r10=newSaveArea 13788 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self 13789 ldr lr, [rGLUE, #offGlue_pInterpBreak] 13790 ldr r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->... 13791 str r1, [r3, #offThread_curFrame] @ self->curFrame = newFp 13792 str r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top 13793 ldr lr, [lr] @ lr<- active submodes 13794 mov r9, r3 @ r9<- glue->self (preserve) 13795 13796 mov r2, r0 @ r2<- methodToCall 13797 mov r0, r1 @ r0<- newFp (points to args) 13798 add r1, rGLUE, #offGlue_retval @ r1<- &retval 13799 13800#ifdef ASSIST_DEBUGGER 13801 /* insert fake function header to help gdb find the stack frame */ 13802 b .Lskip 13803 .type dalvik_mterp, %function 13804dalvik_mterp: 13805 .fnstart 13806 MTERP_ENTRY1 13807 MTERP_ENTRY2 13808.Lskip: 13809#endif 13810 13811 ands lr, #kSubModeMethodTrace @ method tracing? 13812 beq 110f @ hop if not 13813 @ r2=JNIMethod, r6=rGLUE 13814 stmfd sp!, {r2,r6} 13815 13816 mov lr, pc @ set return addr 13817 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 13818 13819 @ r0=JNIMethod, r1=rGLUE 13820 ldmfd sp!, {r0-r1} 13821 bl dvmFastNativeMethodTraceExit 13822 @ r2=JNIMethod, r6=rGLUE 13823 stmfd sp!, {r2,r6} 13824 b 220f 13825110: 13826 mov lr, pc @ set return addr 13827 ldr pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc 13828220: 13829#if defined(WITH_JIT) 13830 ldr r3, [rGLUE, #offGlue_ppJitProfTable] @ Refresh Jit's on/off status 13831#endif 13832 13833 @ native return; r9=self, r10=newSaveArea 13834 @ equivalent to dvmPopJniLocals 13835 ldr r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top 13836 ldr r1, [r9, #offThread_exception] @ check for exception 13837#if defined(WITH_JIT) 13838 ldr r3, [r3] @ r3 <- gDvmJit.pProfTable 13839#endif 13840 str rFP, [r9, #offThread_curFrame] @ self->curFrame = fp 13841 cmp r1, #0 @ null? 13842 str r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top 13843#if defined(WITH_JIT) 13844 str r3, [rGLUE, #offGlue_pJitProfTable] @ refresh cached on/off switch 13845#endif 13846 bne common_exceptionThrown @ no, handle exception 13847 13848 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 13849 GET_INST_OPCODE(ip) @ extract opcode from rINST 13850 GOTO_OPCODE(ip) @ jump to next instruction 13851 13852.LstackOverflow: @ r0=methodToCall 13853 mov r1, r0 @ r1<- methodToCall 13854 ldr r0, [rGLUE, #offGlue_self] @ r0<- self 13855 bl dvmHandleStackOverflow 13856 b common_exceptionThrown 13857#ifdef ASSIST_DEBUGGER 13858 .fnend 13859#endif 13860 13861 13862 /* 13863 * Common code for method invocation, calling through "glue code". 13864 * 13865 * TODO: now that we have range and non-range invoke handlers, this 13866 * needs to be split into two. Maybe just create entry points 13867 * that set r9 and jump here? 13868 * 13869 * On entry: 13870 * r0 is "Method* methodToCall", the method we're trying to call 13871 * r9 is "bool methodCallRange", indicating if this is a /range variant 13872 */ 13873 .if 0 13874.LinvokeOld: 13875 sub sp, sp, #8 @ space for args + pad 13876 FETCH(ip, 2) @ ip<- FEDC or CCCC 13877 mov r2, r0 @ A2<- methodToCall 13878 mov r0, rGLUE @ A0<- glue 13879 SAVE_PC_FP_TO_GLUE() @ export state to "glue" 13880 mov r1, r9 @ A1<- methodCallRange 13881 mov r3, rINST, lsr #8 @ A3<- AA 13882 str ip, [sp, #0] @ A4<- ip 13883 bl dvmMterp_invokeMethod @ call the C invokeMethod 13884 add sp, sp, #8 @ remove arg area 13885 b common_resumeAfterGlueCall @ continue to next instruction 13886 .endif 13887 13888 13889 13890/* 13891 * Common code for handling a return instruction. 13892 * 13893 * This does not return. 13894 */ 13895common_returnFromMethod: 13896.LreturnNew: 13897 mov r0, #kInterpEntryReturn 13898 mov r9, #0 13899 bl common_periodicChecks 13900 13901 ldr lr, [rGLUE, #offGlue_pInterpBreak] 13902 SAVEAREA_FROM_FP(r0, rFP) 13903 ldr lr, [lr] @ lr<- active submodes 13904 ldr r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc 13905 ands lr, #kSubModeMethodTrace @ method tracing? 13906 beq 333f 13907 stmfd sp!, {r0-r3} @ preserve r0-r3 13908 mov r0, r6 13909 @ r0=rGlue 13910 bl dvmFastJavaMethodTraceExit 13911 ldmfd sp!, {r0-r3} @ restore r0-r3 13912333: 13913 ldr rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame 13914 ldr r3, [rGLUE, #offGlue_self] @ r3<- glue->self 13915 ldr r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)] 13916 @ r2<- method we're returning to 13917 cmp r2, #0 @ is this a break frame? 13918#if defined(WORKAROUND_CORTEX_A9_745320) 13919 /* Don't use conditional loads if the HW defect exists */ 13920 beq 101f 13921 ldr r10, [r2, #offMethod_clazz] @ r10<- method->clazz 13922101: 13923#else 13924 ldrne r10, [r2, #offMethod_clazz] @ r10<- method->clazz 13925#endif 13926 mov r1, #0 @ "want switch" = false 13927 beq common_gotoBail @ break frame, bail out completely 13928 13929 PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST 13930 str r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method 13931 ldr r1, [r10, #offClassObject_pDvmDex] @ r1<- method->clazz->pDvmDex 13932 str rFP, [r3, #offThread_curFrame] @ self->curFrame = fp 13933#if defined(WITH_JIT) 13934 ldr r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr 13935 mov rPC, r9 @ publish new rPC 13936 str r1, [rGLUE, #offGlue_methodClassDex] 13937 str r10, [r3, #offThread_inJitCodeCache] @ may return to JIT'ed land 13938 cmp r10, #0 @ caller is compiled code 13939 blxne r10 13940 GET_INST_OPCODE(ip) @ extract opcode from rINST 13941 GOTO_OPCODE(ip) @ jump to next instruction 13942#else 13943 GET_INST_OPCODE(ip) @ extract opcode from rINST 13944 mov rPC, r9 @ publish new rPC 13945 str r1, [rGLUE, #offGlue_methodClassDex] 13946 GOTO_OPCODE(ip) @ jump to next instruction 13947#endif 13948 13949 /* 13950 * Return handling, calls through "glue code". 13951 */ 13952 .if 0 13953.LreturnOld: 13954 SAVE_PC_FP_TO_GLUE() @ export state 13955 mov r0, rGLUE @ arg to function 13956 bl dvmMterp_returnFromMethod 13957 b common_resumeAfterGlueCall 13958 .endif 13959 13960 13961/* 13962 * Somebody has thrown an exception. Handle it. 13963 * 13964 * If the exception processing code returns to us (instead of falling 13965 * out of the interpreter), continue with whatever the next instruction 13966 * now happens to be. 13967 * 13968 * This does not return. 13969 */ 13970 .global dvmMterpCommonExceptionThrown 13971dvmMterpCommonExceptionThrown: 13972common_exceptionThrown: 13973.LexceptionNew: 13974 mov r0, #kInterpEntryThrow 13975 mov r9, #0 13976 bl common_periodicChecks 13977 13978 ldr r10, [rGLUE, #offGlue_self] @ r10<- glue->self 13979 ldr r9, [r10, #offThread_exception] @ r9<- self->exception 13980 mov r1, r10 @ r1<- self 13981 mov r0, r9 @ r0<- exception 13982 bl dvmAddTrackedAlloc @ don't let the exception be GCed 13983 mov r3, #0 @ r3<- NULL 13984 str r3, [r10, #offThread_exception] @ self->exception = NULL 13985 13986 /* set up args and a local for "&fp" */ 13987 /* (str sp, [sp, #-4]! would be perfect here, but is discouraged) */ 13988 str rFP, [sp, #-4]! @ *--sp = fp 13989 mov ip, sp @ ip<- &fp 13990 mov r3, #0 @ r3<- false 13991 str ip, [sp, #-4]! @ *--sp = &fp 13992 ldr r1, [rGLUE, #offGlue_method] @ r1<- glue->method 13993 mov r0, r10 @ r0<- self 13994 ldr r1, [r1, #offMethod_insns] @ r1<- method->insns 13995 mov r2, r9 @ r2<- exception 13996 sub r1, rPC, r1 @ r1<- pc - method->insns 13997 mov r1, r1, asr #1 @ r1<- offset in code units 13998 13999 /* call, r0 gets catchRelPc (a code-unit offset) */ 14000 bl dvmFindCatchBlock @ call(self, relPc, exc, scan?, &fp) 14001 14002 /* fix earlier stack overflow if necessary; may trash rFP */ 14003 ldrb r1, [r10, #offThread_stackOverflowed] 14004 cmp r1, #0 @ did we overflow earlier? 14005 beq 1f @ no, skip ahead 14006 mov rFP, r0 @ save relPc result in rFP 14007 mov r0, r10 @ r0<- self 14008 mov r1, r9 @ r1<- exception 14009 bl dvmCleanupStackOverflow @ call(self) 14010 mov r0, rFP @ restore result 140111: 14012 14013 /* update frame pointer and check result from dvmFindCatchBlock */ 14014 ldr rFP, [sp, #4] @ retrieve the updated rFP 14015 cmp r0, #0 @ is catchRelPc < 0? 14016 add sp, sp, #8 @ restore stack 14017 bmi .LnotCaughtLocally 14018 14019 /* adjust locals to match self->curFrame and updated PC */ 14020 SAVEAREA_FROM_FP(r1, rFP) @ r1<- new save area 14021 ldr r1, [r1, #offStackSaveArea_method] @ r1<- new method 14022 str r1, [rGLUE, #offGlue_method] @ glue->method = new method 14023 ldr r2, [r1, #offMethod_clazz] @ r2<- method->clazz 14024 ldr r3, [r1, #offMethod_insns] @ r3<- method->insns 14025 ldr r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex 14026 add rPC, r3, r0, asl #1 @ rPC<- method->insns + catchRelPc 14027 str r2, [rGLUE, #offGlue_methodClassDex] @ glue->pDvmDex = meth... 14028 14029 /* release the tracked alloc on the exception */ 14030 mov r0, r9 @ r0<- exception 14031 mov r1, r10 @ r1<- self 14032 bl dvmReleaseTrackedAlloc @ release the exception 14033 14034 /* restore the exception if the handler wants it */ 14035 FETCH_INST() @ load rINST from rPC 14036 GET_INST_OPCODE(ip) @ extract opcode from rINST 14037 cmp ip, #OP_MOVE_EXCEPTION @ is it "move-exception"? 14038 streq r9, [r10, #offThread_exception] @ yes, restore the exception 14039 GOTO_OPCODE(ip) @ jump to next instruction 14040 14041.LnotCaughtLocally: @ r9=exception, r10=self 14042 /* fix stack overflow if necessary */ 14043 ldrb r1, [r10, #offThread_stackOverflowed] 14044 cmp r1, #0 @ did we overflow earlier? 14045 movne r0, r10 @ if yes: r0<- self 14046 movne r1, r9 @ if yes: r1<- exception 14047 blne dvmCleanupStackOverflow @ if yes: call(self) 14048 14049 @ may want to show "not caught locally" debug messages here 14050#if DVM_SHOW_EXCEPTION >= 2 14051 /* call __android_log_print(prio, tag, format, ...) */ 14052 /* "Exception %s from %s:%d not caught locally" */ 14053 @ dvmLineNumFromPC(method, pc - method->insns) 14054 ldr r0, [rGLUE, #offGlue_method] 14055 ldr r1, [r0, #offMethod_insns] 14056 sub r1, rPC, r1 14057 asr r1, r1, #1 14058 bl dvmLineNumFromPC 14059 str r0, [sp, #-4]! 14060 @ dvmGetMethodSourceFile(method) 14061 ldr r0, [rGLUE, #offGlue_method] 14062 bl dvmGetMethodSourceFile 14063 str r0, [sp, #-4]! 14064 @ exception->clazz->descriptor 14065 ldr r3, [r9, #offObject_clazz] 14066 ldr r3, [r3, #offClassObject_descriptor] 14067 @ 14068 ldr r2, strExceptionNotCaughtLocally 14069 ldr r1, strLogTag 14070 mov r0, #3 @ LOG_DEBUG 14071 bl __android_log_print 14072#endif 14073 str r9, [r10, #offThread_exception] @ restore exception 14074 mov r0, r9 @ r0<- exception 14075 mov r1, r10 @ r1<- self 14076 bl dvmReleaseTrackedAlloc @ release the exception 14077 mov r1, #0 @ "want switch" = false 14078 b common_gotoBail @ bail out 14079 14080 14081 /* 14082 * Exception handling, calls through "glue code". 14083 */ 14084 .if 0 14085.LexceptionOld: 14086 SAVE_PC_FP_TO_GLUE() @ export state 14087 mov r0, rGLUE @ arg to function 14088 bl dvmMterp_exceptionThrown 14089 b common_resumeAfterGlueCall 14090 .endif 14091 14092 14093/* 14094 * After returning from a "glued" function, pull out the updated 14095 * values and start executing at the next instruction. 14096 */ 14097common_resumeAfterGlueCall: 14098 LOAD_PC_FP_FROM_GLUE() @ pull rPC and rFP out of glue 14099 FETCH_INST() @ load rINST from rPC 14100 GET_INST_OPCODE(ip) @ extract opcode from rINST 14101 GOTO_OPCODE(ip) @ jump to next instruction 14102 14103/* 14104 * Invalid array index. Note that our calling convention is strange; we use r1 14105 * and r3 because those just happen to be the registers all our callers are 14106 * using. We shuffle them here before calling the C function. 14107 * r1: index 14108 * r3: size 14109 */ 14110common_errArrayIndex: 14111 EXPORT_PC() 14112 mov r0, r1 14113 mov r1, r3 14114 bl dvmThrowAIOOBE 14115 b common_exceptionThrown 14116 14117/* 14118 * Integer divide or mod by zero. 14119 */ 14120common_errDivideByZero: 14121 EXPORT_PC() 14122 ldr r0, strArithmeticException 14123 ldr r1, strDivideByZero 14124 bl dvmThrowException 14125 b common_exceptionThrown 14126 14127/* 14128 * Attempt to allocate an array with a negative size. 14129 */ 14130common_errNegativeArraySize: 14131 EXPORT_PC() 14132 ldr r0, strNegativeArraySizeException 14133 mov r1, #0 14134 bl dvmThrowException 14135 b common_exceptionThrown 14136 14137/* 14138 * Invocation of a non-existent method. 14139 */ 14140common_errNoSuchMethod: 14141 EXPORT_PC() 14142 ldr r0, strNoSuchMethodError 14143 mov r1, #0 14144 bl dvmThrowException 14145 b common_exceptionThrown 14146 14147/* 14148 * We encountered a null object when we weren't expecting one. We 14149 * export the PC, throw a NullPointerException, and goto the exception 14150 * processing code. 14151 */ 14152common_errNullObject: 14153 EXPORT_PC() 14154 ldr r0, strNullPointerException 14155 mov r1, #0 14156 bl dvmThrowException 14157 b common_exceptionThrown 14158 14159/* 14160 * For debugging, cause an immediate fault. The source address will 14161 * be in lr (use a bl instruction to jump here). 14162 */ 14163common_abort: 14164 ldr pc, .LdeadFood 14165.LdeadFood: 14166 .word 0xdeadf00d 14167 14168/* 14169 * Spit out a "we were here", preserving all registers. (The attempt 14170 * to save ip won't work, but we need to save an even number of 14171 * registers for EABI 64-bit stack alignment.) 14172 */ 14173 .macro SQUEAK num 14174common_squeak\num: 14175 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14176 ldr r0, strSqueak 14177 mov r1, #\num 14178 bl printf 14179 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14180 bx lr 14181 .endm 14182 14183 SQUEAK 0 14184 SQUEAK 1 14185 SQUEAK 2 14186 SQUEAK 3 14187 SQUEAK 4 14188 SQUEAK 5 14189 14190/* 14191 * Spit out the number in r0, preserving registers. 14192 */ 14193common_printNum: 14194 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14195 mov r1, r0 14196 ldr r0, strSqueak 14197 bl printf 14198 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14199 bx lr 14200 14201/* 14202 * Print a newline, preserving registers. 14203 */ 14204common_printNewline: 14205 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14206 ldr r0, strNewline 14207 bl printf 14208 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14209 bx lr 14210 14211 /* 14212 * Print the 32-bit quantity in r0 as a hex value, preserving registers. 14213 */ 14214common_printHex: 14215 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14216 mov r1, r0 14217 ldr r0, strPrintHex 14218 bl printf 14219 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14220 bx lr 14221 14222/* 14223 * Print the 64-bit quantity in r0-r1, preserving registers. 14224 */ 14225common_printLong: 14226 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14227 mov r3, r1 14228 mov r2, r0 14229 ldr r0, strPrintLong 14230 bl printf 14231 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14232 bx lr 14233 14234/* 14235 * Print full method info. Pass the Method* in r0. Preserves regs. 14236 */ 14237common_printMethod: 14238 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14239 bl dvmMterpPrintMethod 14240 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14241 bx lr 14242 14243/* 14244 * Call a C helper function that dumps regs and possibly some 14245 * additional info. Requires the C function to be compiled in. 14246 */ 14247 .if 0 14248common_dumpRegs: 14249 stmfd sp!, {r0, r1, r2, r3, ip, lr} 14250 bl dvmMterpDumpArmRegs 14251 ldmfd sp!, {r0, r1, r2, r3, ip, lr} 14252 bx lr 14253 .endif 14254 14255#if 0 14256/* 14257 * Experiment on VFP mode. 14258 * 14259 * uint32_t setFPSCR(uint32_t val, uint32_t mask) 14260 * 14261 * Updates the bits specified by "mask", setting them to the values in "val". 14262 */ 14263setFPSCR: 14264 and r0, r0, r1 @ make sure no stray bits are set 14265 fmrx r2, fpscr @ get VFP reg 14266 mvn r1, r1 @ bit-invert mask 14267 and r2, r2, r1 @ clear masked bits 14268 orr r2, r2, r0 @ set specified bits 14269 fmxr fpscr, r2 @ set VFP reg 14270 mov r0, r2 @ return new value 14271 bx lr 14272 14273 .align 2 14274 .global dvmConfigureFP 14275 .type dvmConfigureFP, %function 14276dvmConfigureFP: 14277 stmfd sp!, {ip, lr} 14278 /* 0x03000000 sets DN/FZ */ 14279 /* 0x00009f00 clears the six exception enable flags */ 14280 bl common_squeak0 14281 mov r0, #0x03000000 @ r0<- 0x03000000 14282 add r1, r0, #0x9f00 @ r1<- 0x03009f00 14283 bl setFPSCR 14284 ldmfd sp!, {ip, pc} 14285#endif 14286 14287 14288/* 14289 * String references, must be close to the code that uses them. 14290 */ 14291 .align 2 14292strArithmeticException: 14293 .word .LstrArithmeticException 14294strDivideByZero: 14295 .word .LstrDivideByZero 14296strNegativeArraySizeException: 14297 .word .LstrNegativeArraySizeException 14298strNoSuchMethodError: 14299 .word .LstrNoSuchMethodError 14300strNullPointerException: 14301 .word .LstrNullPointerException 14302 14303strLogTag: 14304 .word .LstrLogTag 14305strExceptionNotCaughtLocally: 14306 .word .LstrExceptionNotCaughtLocally 14307 14308strNewline: 14309 .word .LstrNewline 14310strSqueak: 14311 .word .LstrSqueak 14312strPrintHex: 14313 .word .LstrPrintHex 14314strPrintLong: 14315 .word .LstrPrintLong 14316 14317/* 14318 * Zero-terminated ASCII string data. 14319 * 14320 * On ARM we have two choices: do like gcc does, and LDR from a .word 14321 * with the address, or use an ADR pseudo-op to get the address 14322 * directly. ADR saves 4 bytes and an indirection, but it's using a 14323 * PC-relative addressing mode and hence has a limited range, which 14324 * makes it not work well with mergeable string sections. 14325 */ 14326 .section .rodata.str1.4,"aMS",%progbits,1 14327 14328.LstrBadEntryPoint: 14329 .asciz "Bad entry point %d\n" 14330.LstrArithmeticException: 14331 .asciz "Ljava/lang/ArithmeticException;" 14332.LstrDivideByZero: 14333 .asciz "divide by zero" 14334.LstrFilledNewArrayNotImpl: 14335 .asciz "filled-new-array only implemented for objects and 'int'" 14336.LstrInternalError: 14337 .asciz "Ljava/lang/InternalError;" 14338.LstrInstantiationError: 14339 .asciz "Ljava/lang/InstantiationError;" 14340.LstrNegativeArraySizeException: 14341 .asciz "Ljava/lang/NegativeArraySizeException;" 14342.LstrNoSuchMethodError: 14343 .asciz "Ljava/lang/NoSuchMethodError;" 14344.LstrNullPointerException: 14345 .asciz "Ljava/lang/NullPointerException;" 14346 14347.LstrLogTag: 14348 .asciz "mterp" 14349.LstrExceptionNotCaughtLocally: 14350 .asciz "Exception %s from %s:%d not caught locally\n" 14351 14352.LstrNewline: 14353 .asciz "\n" 14354.LstrSqueak: 14355 .asciz "<%d>" 14356.LstrPrintHex: 14357 .asciz "<0x%x>" 14358.LstrPrintLong: 14359 .asciz "<%lld>" 14360 14361